@sanity/runtime-cli 14.7.2 → 14.8.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 +150 -99
- package/dist/actions/blueprints/assets.d.ts +4 -3
- package/dist/actions/blueprints/assets.js +69 -101
- package/dist/actions/blueprints/blueprint.d.ts +2 -2
- package/dist/actions/blueprints/blueprint.js +1 -8
- package/dist/actions/blueprints/config.d.ts +2 -2
- package/dist/actions/blueprints/logs-streaming.d.ts +2 -2
- package/dist/actions/blueprints/logs.d.ts +2 -4
- package/dist/actions/blueprints/resources.d.ts +3 -3
- package/dist/actions/blueprints/resources.js +30 -10
- package/dist/actions/blueprints/stacks.d.ts +15 -25
- package/dist/actions/functions/dev.d.ts +1 -1
- package/dist/actions/functions/env/list.d.ts +1 -1
- package/dist/actions/functions/env/remove.d.ts +1 -1
- package/dist/actions/functions/env/update.d.ts +1 -1
- package/dist/actions/functions/logs.d.ts +3 -3
- package/dist/actions/node.d.ts +1 -1
- package/dist/actions/sanity/examples.d.ts +2 -2
- package/dist/actions/sanity/projects.d.ts +7 -13
- package/dist/baseCommands.d.ts +8 -0
- package/dist/baseCommands.js +10 -4
- package/dist/commands/blueprints/config.d.ts +1 -1
- package/dist/commands/blueprints/config.js +5 -13
- package/dist/commands/blueprints/deploy.d.ts +1 -1
- package/dist/commands/blueprints/deploy.js +2 -1
- package/dist/commands/blueprints/destroy.d.ts +1 -1
- package/dist/commands/blueprints/destroy.js +5 -7
- package/dist/commands/blueprints/doctor.js +2 -2
- package/dist/commands/blueprints/info.d.ts +1 -1
- package/dist/commands/blueprints/info.js +2 -1
- package/dist/commands/blueprints/init.js +3 -11
- package/dist/commands/blueprints/plan.d.ts +1 -1
- package/dist/commands/blueprints/plan.js +2 -1
- package/dist/commands/blueprints/promote.d.ts +0 -1
- package/dist/commands/blueprints/promote.js +2 -6
- package/dist/commands/blueprints/stacks.d.ts +1 -1
- package/dist/commands/blueprints/stacks.js +5 -13
- package/dist/commands/functions/build.d.ts +1 -1
- package/dist/commands/functions/build.js +2 -1
- package/dist/commands/functions/env/add.d.ts +1 -1
- package/dist/commands/functions/env/add.js +2 -1
- package/dist/commands/functions/env/list.d.ts +1 -1
- package/dist/commands/functions/env/list.js +2 -1
- package/dist/commands/functions/env/remove.d.ts +1 -1
- package/dist/commands/functions/env/remove.js +2 -1
- package/dist/commands/functions/logs.d.ts +0 -1
- package/dist/commands/functions/logs.js +0 -5
- package/dist/commands/functions/test.d.ts +1 -1
- package/dist/commands/functions/test.js +5 -13
- package/dist/constants.d.ts +2 -1
- package/dist/cores/blueprints/config.js +11 -7
- package/dist/cores/blueprints/deploy.js +62 -74
- package/dist/cores/blueprints/destroy.js +3 -3
- package/dist/cores/blueprints/doctor.js +5 -1
- package/dist/cores/blueprints/info.js +1 -1
- package/dist/cores/blueprints/init.d.ts +4 -3
- package/dist/cores/blueprints/plan.js +7 -1
- package/dist/cores/blueprints/promote.d.ts +0 -1
- package/dist/cores/blueprints/promote.js +4 -4
- package/dist/cores/blueprints/stacks.js +6 -2
- package/dist/cores/functions/add.d.ts +1 -0
- package/dist/cores/functions/add.js +2 -2
- package/dist/cores/functions/build.js +2 -2
- package/dist/cores/functions/env/add.js +1 -1
- package/dist/cores/functions/env/list.js +1 -1
- package/dist/cores/functions/env/remove.js +1 -1
- package/dist/cores/functions/test.js +4 -4
- package/dist/cores/index.d.ts +9 -2
- package/dist/cores/index.js +3 -2
- package/dist/server/app.d.ts +1 -1
- package/dist/server/handlers/invoke.d.ts +1 -1
- package/dist/utils/display/prompt.d.ts +2 -2
- package/dist/utils/display/prompt.js +1 -1
- package/dist/utils/display/resources-formatting.d.ts +2 -2
- package/dist/utils/display/resources-formatting.js +1 -1
- package/dist/utils/functions/fetch-document.d.ts +2 -2
- package/dist/utils/functions/prepare-asset.d.ts +3 -8
- package/dist/utils/functions/prepare-asset.js +2 -2
- package/dist/utils/functions/should-auto-resolve-deps.js +1 -1
- package/dist/utils/functions/should-transpile.js +1 -1
- package/dist/utils/invoke-local.d.ts +1 -7
- package/dist/utils/invoke-local.js +5 -24
- package/dist/utils/logger.d.ts +2 -0
- package/dist/utils/logger.js +2 -0
- package/dist/utils/other/github.d.ts +1 -1
- package/dist/utils/other/npmjs.d.ts +1 -1
- package/dist/utils/traced-fetch.d.ts +1 -1
- package/dist/utils/types.d.ts +21 -80
- package/dist/utils/types.js +6 -14
- package/dist/utils/validate/resource.d.ts +0 -3
- package/dist/utils/validate/resource.js +0 -270
- package/dist/utils/validated-token.d.ts +2 -2
- package/oclif.manifest.json +36 -90
- package/package.json +2 -2
|
@@ -4,7 +4,7 @@ import { setupLogStreaming } from '../../actions/blueprints/logs-streaming.js';
|
|
|
4
4
|
import { getStack, updateStack } from '../../actions/blueprints/stacks.js';
|
|
5
5
|
import { niceId } from '../../utils/display/presenters.js';
|
|
6
6
|
import { styleText } from '../../utils/style-text.js';
|
|
7
|
-
import {
|
|
7
|
+
import { isLocalFunctionResource, isStudioResource } from '../../utils/types.js';
|
|
8
8
|
const DEFAULT_ASSET_TIMEOUT = 60;
|
|
9
9
|
const assetTimeoutS = Number(process.env.SANITY_ASSET_TIMEOUT) || DEFAULT_ASSET_TIMEOUT;
|
|
10
10
|
const assetTimeoutMs = assetTimeoutS * 1000;
|
|
@@ -30,77 +30,13 @@ export async function blueprintDeployCore(options) {
|
|
|
30
30
|
}
|
|
31
31
|
const { resources } = blueprint.parsedBlueprint;
|
|
32
32
|
const validResources = resources?.filter((r) => r.type) || [];
|
|
33
|
-
const
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
const fnSpinner = log.ora({ text: `Processing ${resource.name}...`, prefixText: ' ' }).start();
|
|
41
|
-
const warnTimer = setTimeout(() => {
|
|
42
|
-
fnSpinner.text = `Still processing ${resource.name}, this can take a moment...`;
|
|
43
|
-
}, warnTimeoutMs);
|
|
44
|
-
let assetTimeoutTimer;
|
|
45
|
-
let result;
|
|
46
|
-
try {
|
|
47
|
-
result = await Promise.race([
|
|
48
|
-
stashAsset({ resource, auth, logger: log, installer }),
|
|
49
|
-
new Promise((_, reject) => {
|
|
50
|
-
assetTimeoutTimer = setTimeout(() => {
|
|
51
|
-
reject(new Error(`Processing ${resource.name} timed out after ${assetTimeoutS}s`));
|
|
52
|
-
}, assetTimeoutMs);
|
|
53
|
-
}),
|
|
54
|
-
]);
|
|
55
|
-
}
|
|
56
|
-
catch (err) {
|
|
57
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
58
|
-
fnSpinner.fail(msg);
|
|
59
|
-
return { success: false, error: msg };
|
|
60
|
-
}
|
|
61
|
-
finally {
|
|
62
|
-
clearTimeout(warnTimer);
|
|
63
|
-
clearTimeout(assetTimeoutTimer);
|
|
64
|
-
}
|
|
65
|
-
if (result.success && result.assetId) {
|
|
66
|
-
resource.src = result.assetId;
|
|
67
|
-
if (isLocalFunctionCollection(resource)) {
|
|
68
|
-
try {
|
|
69
|
-
for (const func of resource.functions) {
|
|
70
|
-
func.src = func.name;
|
|
71
|
-
}
|
|
72
|
-
fnSpinner.succeed(`${resource.name} collection ${niceId(result.assetId)} (${resource.functions.length} functions)`);
|
|
73
|
-
log(` Functions: ${resource.functions.map((f) => f.name).join(', ')}`);
|
|
74
|
-
}
|
|
75
|
-
catch (err) {
|
|
76
|
-
fnSpinner.fail(`Failed to update function collection ${resource.name}`);
|
|
77
|
-
return {
|
|
78
|
-
success: false,
|
|
79
|
-
error: `Error updating function collection '${resource.name}': ${err instanceof Error ? err.message : String(err)}`,
|
|
80
|
-
};
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
else {
|
|
84
|
-
fnSpinner.succeed(`${resource.name} ${niceId(result.assetId)}`);
|
|
85
|
-
log(` Source: ${resource.src}`);
|
|
86
|
-
}
|
|
87
|
-
if (result.hash) {
|
|
88
|
-
if (result.hash.length > 24) {
|
|
89
|
-
log.verbose(` Hash: ${result.hash.slice(0, 8)}...${result.hash.slice(-12)}`);
|
|
90
|
-
}
|
|
91
|
-
else {
|
|
92
|
-
log.verbose(` Hash: ${result.hash}`);
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
if (result.exists)
|
|
96
|
-
log.verbose(' Asset unchanged');
|
|
97
|
-
}
|
|
98
|
-
else {
|
|
99
|
-
const errorMsg = isLocalFunctionCollection(resource)
|
|
100
|
-
? `Failed uploading function collection ${resource.name} (${resource.functions?.length || 0} functions), deploy has stopped`
|
|
101
|
-
: `Failed uploading ${resource.name} asset, deploy has stopped`;
|
|
102
|
-
fnSpinner.fail(errorMsg);
|
|
103
|
-
return { success: false, error: result.error || 'Failed to process function resource' };
|
|
33
|
+
const preDeployResources = validResources.filter(isPreDeployResource);
|
|
34
|
+
if (preDeployResources.length > 0) {
|
|
35
|
+
log('Processing assets...');
|
|
36
|
+
for (const resource of preDeployResources) {
|
|
37
|
+
const preDeployResult = await preDeploy(resource, { auth, installer, log });
|
|
38
|
+
if (preDeployResult.success === false) {
|
|
39
|
+
return preDeployResult;
|
|
104
40
|
}
|
|
105
41
|
}
|
|
106
42
|
}
|
|
@@ -125,7 +61,7 @@ export async function blueprintDeployCore(options) {
|
|
|
125
61
|
if (noWait) {
|
|
126
62
|
log(styleText(['bold', 'green'], 'Stack deployment started!'));
|
|
127
63
|
log(`Use \`npx ${bin} blueprints info\` to check status`);
|
|
128
|
-
return { success: true, data: { resources } };
|
|
64
|
+
return { success: true, json: { stackId: stack.id, resources }, data: { resources } };
|
|
129
65
|
}
|
|
130
66
|
log(styleText('dim', 'Stack deployment progress:'));
|
|
131
67
|
let logStreamCleanup = null;
|
|
@@ -164,7 +100,7 @@ export async function blueprintDeployCore(options) {
|
|
|
164
100
|
if (logStreamCleanup)
|
|
165
101
|
logStreamCleanup();
|
|
166
102
|
log(styleText(['bold', 'green'], 'Stack deployment completed!'));
|
|
167
|
-
return { success: true, data: { resources } };
|
|
103
|
+
return { success: true, json: { stackId: stack.id, resources }, data: { resources } };
|
|
168
104
|
}
|
|
169
105
|
if (!idleMessageShown && Date.now() - lastLogAt > 60_000) {
|
|
170
106
|
log(`No new activity for 60 seconds. The deployment is still running on Sanity servers.`);
|
|
@@ -185,3 +121,55 @@ export async function blueprintDeployCore(options) {
|
|
|
185
121
|
return { success: false, error: errorMessage };
|
|
186
122
|
}
|
|
187
123
|
}
|
|
124
|
+
function isPreDeployResource(r) {
|
|
125
|
+
return isLocalFunctionResource(r) || isStudioResource(r);
|
|
126
|
+
}
|
|
127
|
+
async function preDeploy(resource, options) {
|
|
128
|
+
const { auth, installer, log } = options;
|
|
129
|
+
const fnSpinner = log.ora({ text: `Processing ${resource.name}...`, prefixText: ' ' }).start();
|
|
130
|
+
const warnTimer = setTimeout(() => {
|
|
131
|
+
fnSpinner.text = `Still processing ${resource.name}, this can take a moment...`;
|
|
132
|
+
}, warnTimeoutMs);
|
|
133
|
+
let assetTimeoutTimer;
|
|
134
|
+
let result;
|
|
135
|
+
try {
|
|
136
|
+
result = await Promise.race([
|
|
137
|
+
stashAsset({ resource, auth, logger: log, installer }),
|
|
138
|
+
new Promise((_, reject) => {
|
|
139
|
+
assetTimeoutTimer = setTimeout(() => {
|
|
140
|
+
reject(new Error(`Processing ${resource.name} timed out after ${assetTimeoutS}s`));
|
|
141
|
+
}, assetTimeoutMs);
|
|
142
|
+
}),
|
|
143
|
+
]);
|
|
144
|
+
}
|
|
145
|
+
catch (err) {
|
|
146
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
147
|
+
fnSpinner.fail(msg);
|
|
148
|
+
return { success: false, error: msg };
|
|
149
|
+
}
|
|
150
|
+
finally {
|
|
151
|
+
clearTimeout(warnTimer);
|
|
152
|
+
clearTimeout(assetTimeoutTimer);
|
|
153
|
+
}
|
|
154
|
+
if (result.success && result.assetId) {
|
|
155
|
+
resource.src = result.assetId;
|
|
156
|
+
fnSpinner.succeed(`${resource.name} ${niceId(result.assetId)}`);
|
|
157
|
+
log(` Source: ${resource.src}`);
|
|
158
|
+
if (result.hash) {
|
|
159
|
+
if (result.hash.length > 24) {
|
|
160
|
+
log.verbose(` Hash: ${result.hash.slice(0, 8)}...${result.hash.slice(-12)}`);
|
|
161
|
+
}
|
|
162
|
+
else {
|
|
163
|
+
log.verbose(` Hash: ${result.hash}`);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
if (result.exists)
|
|
167
|
+
log.verbose(' Asset unchanged');
|
|
168
|
+
}
|
|
169
|
+
else {
|
|
170
|
+
const errorMsg = `Failed uploading ${resource.name} asset, deploy has stopped`;
|
|
171
|
+
fnSpinner.fail(errorMsg);
|
|
172
|
+
return { success: false, error: result.error || 'Failed to process asset' };
|
|
173
|
+
}
|
|
174
|
+
return { success: true };
|
|
175
|
+
}
|
|
@@ -32,7 +32,7 @@ export async function blueprintDestroyCore(options) {
|
|
|
32
32
|
if (!ok)
|
|
33
33
|
return { success: false, error: error || 'Failed to destroy Stack deployment' };
|
|
34
34
|
log(`Stack deployment "${stack.name}" ${niceId(stack.id)} destroyed`);
|
|
35
|
-
return { success: true };
|
|
35
|
+
return { success: true, json: { stackId: stack.id, stackName: stack.name } };
|
|
36
36
|
}
|
|
37
37
|
const { scopeType, scopeId, stackId } = blueprint;
|
|
38
38
|
if (!scopeType || !scopeId)
|
|
@@ -92,7 +92,7 @@ export async function blueprintDestroyCore(options) {
|
|
|
92
92
|
destroySpinner.stop().clear();
|
|
93
93
|
if (noWait) {
|
|
94
94
|
log(styleText(['bold', 'magenta'], 'Stack destruction started!'));
|
|
95
|
-
return { success: true };
|
|
95
|
+
return { success: true, json: { stackId: stack.id, stackName: stack.name } };
|
|
96
96
|
}
|
|
97
97
|
log(styleText('dim', 'Stack destruction progress:'));
|
|
98
98
|
let logStreamCleanup = null;
|
|
@@ -117,7 +117,7 @@ export async function blueprintDestroyCore(options) {
|
|
|
117
117
|
if (logStreamCleanup)
|
|
118
118
|
logStreamCleanup();
|
|
119
119
|
log(styleText(['bold', 'magenta'], 'Stack destruction completed!'));
|
|
120
|
-
return { success: true };
|
|
120
|
+
return { success: true, json: { stackId: stack.id, stackName: stack.name } };
|
|
121
121
|
}
|
|
122
122
|
if (operation.status === 'FAILED') {
|
|
123
123
|
if (logStreamCleanup)
|
|
@@ -273,7 +273,11 @@ export async function blueprintDoctorCore(options) {
|
|
|
273
273
|
log(styleText(['bold', 'green'], 'All checks passed'));
|
|
274
274
|
if (fix)
|
|
275
275
|
log(styleText(['bold', 'yellow'], 'Nothing to fix; --fix flag is ignored'));
|
|
276
|
-
return {
|
|
276
|
+
return {
|
|
277
|
+
success: true,
|
|
278
|
+
json: { diagnostics: flatDiagnostics },
|
|
279
|
+
data: { diagnostics: flatDiagnostics },
|
|
280
|
+
};
|
|
277
281
|
}
|
|
278
282
|
if (fix) {
|
|
279
283
|
if (p) {
|
|
@@ -6,7 +6,7 @@ export async function blueprintInfoCore(options) {
|
|
|
6
6
|
log(formatStackInfo(deployedStack, true));
|
|
7
7
|
if (deployedStack.resources)
|
|
8
8
|
log(formatDeployedResourceTree(deployedStack.resources, verbose));
|
|
9
|
-
return { success: true };
|
|
9
|
+
return { success: true, json: { stack: deployedStack } };
|
|
10
10
|
}
|
|
11
11
|
catch (error) {
|
|
12
12
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { Logger } from '../../utils/logger.js';
|
|
1
2
|
import type { ScopeType } from '../../utils/types.js';
|
|
2
3
|
import type { CoreConfig, CoreResult } from '../index.js';
|
|
3
4
|
export interface BlueprintInitOptions extends CoreConfig {
|
|
@@ -35,13 +36,13 @@ export declare function resolveScopeAndStack(params: {
|
|
|
35
36
|
stackId: string | undefined;
|
|
36
37
|
stackName: string | undefined;
|
|
37
38
|
knownProjectId?: string;
|
|
38
|
-
log:
|
|
39
|
+
log: Logger;
|
|
39
40
|
token: string;
|
|
40
41
|
}): Promise<ResolvedScope>;
|
|
41
42
|
export declare function determineBlueprintExtension(params: {
|
|
42
43
|
requestedType: string | undefined;
|
|
43
44
|
blueprintDir: string;
|
|
44
|
-
log:
|
|
45
|
+
log: Logger;
|
|
45
46
|
}): Promise<string>;
|
|
46
47
|
export declare function createBlueprintFiles(params: {
|
|
47
48
|
blueprintDir: string;
|
|
@@ -51,6 +52,6 @@ export declare function createBlueprintFiles(params: {
|
|
|
51
52
|
scopeId: string;
|
|
52
53
|
stackId: string | undefined;
|
|
53
54
|
bin: string;
|
|
54
|
-
log:
|
|
55
|
+
log: Logger;
|
|
55
56
|
}): Promise<CoreResult>;
|
|
56
57
|
export {};
|
|
@@ -63,5 +63,11 @@ export async function blueprintPlanCore(options) {
|
|
|
63
63
|
else {
|
|
64
64
|
log(`\n ${styleText('dim', `No significant changes to deploy. Run \`npx ${bin} blueprints deploy\` to apply.`)}`);
|
|
65
65
|
}
|
|
66
|
-
return {
|
|
66
|
+
return {
|
|
67
|
+
success: true,
|
|
68
|
+
json: {
|
|
69
|
+
resources: parsedBlueprint.resources,
|
|
70
|
+
plan: planResponse.deploymentPlan,
|
|
71
|
+
},
|
|
72
|
+
};
|
|
67
73
|
}
|
|
@@ -4,9 +4,6 @@ import { promoteStack } from '../../actions/blueprints/stacks.js';
|
|
|
4
4
|
import { niceId } from '../../utils/display/presenters.js';
|
|
5
5
|
export async function blueprintPromoteCore(options) {
|
|
6
6
|
const { log, stackId, auth, flags, deployedStack, blueprint } = options;
|
|
7
|
-
if (!flags['i-know-what-im-doing']) {
|
|
8
|
-
return { success: false, error: 'Seems you do not know what you are doing.' };
|
|
9
|
-
}
|
|
10
7
|
let message = `"${deployedStack.name}" ${niceId(deployedStack.id)}`;
|
|
11
8
|
if (deployedStack.scopeType === 'organization') {
|
|
12
9
|
message = `Stack ${message} is already org-scoped. Promote again?`;
|
|
@@ -21,10 +18,13 @@ export async function blueprintPromoteCore(options) {
|
|
|
21
18
|
}
|
|
22
19
|
}
|
|
23
20
|
try {
|
|
21
|
+
const spinner = log.ora('Promoting Stack...').start();
|
|
24
22
|
const { ok, error, stack } = await promoteStack({ stackId, auth, logger: log });
|
|
25
23
|
if (!ok) {
|
|
24
|
+
spinner.fail('Failed to promote Stack');
|
|
26
25
|
return { success: false, error: error || 'Failed to promote Stack' };
|
|
27
26
|
}
|
|
27
|
+
spinner.stop().clear();
|
|
28
28
|
log(`Stack "${stack.name}" ${niceId(stack.id)} promoted successfully`);
|
|
29
29
|
const { blueprintFilePath } = blueprint.fileInfo;
|
|
30
30
|
try {
|
|
@@ -41,7 +41,7 @@ export async function blueprintPromoteCore(options) {
|
|
|
41
41
|
error: 'Stack promoted successfully but failed to update local Blueprint configuration. No config file found.',
|
|
42
42
|
};
|
|
43
43
|
}
|
|
44
|
-
return { success: true, data: { stack } };
|
|
44
|
+
return { success: true, json: { stack }, data: { stack } };
|
|
45
45
|
}
|
|
46
46
|
catch (error) {
|
|
47
47
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
@@ -25,16 +25,20 @@ export async function blueprintStacksCore(options) {
|
|
|
25
25
|
return { success: false, error: 'Unable to determine scope for Blueprint Stacks' };
|
|
26
26
|
}
|
|
27
27
|
try {
|
|
28
|
+
const spinner = log.ora('Fetching Stacks...').start();
|
|
28
29
|
const { ok, stacks, error } = await listStacks({ token, scopeType, scopeId }, log);
|
|
29
|
-
if (!ok)
|
|
30
|
+
if (!ok) {
|
|
31
|
+
spinner.fail('Failed to list Stacks');
|
|
30
32
|
return { success: false, error: error || 'Failed to list stacks' };
|
|
33
|
+
}
|
|
34
|
+
spinner.stop().clear();
|
|
31
35
|
if (!stacks || stacks.length === 0) {
|
|
32
36
|
log('No stacks found');
|
|
33
37
|
return { success: true };
|
|
34
38
|
}
|
|
35
39
|
log(`${styleText('bold', capitalize(scopeType))} ${niceId(scopeId)} ${styleText('bold', 'Stacks')}:\n`);
|
|
36
40
|
log(formatStacksListing(stacks, blueprintStackId));
|
|
37
|
-
return { success: true };
|
|
41
|
+
return { success: true, json: { stacks, scopeType, scopeId } };
|
|
38
42
|
}
|
|
39
43
|
catch (error) {
|
|
40
44
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
@@ -13,4 +13,5 @@ export interface FunctionAddOptions extends CoreConfig {
|
|
|
13
13
|
install?: boolean;
|
|
14
14
|
};
|
|
15
15
|
}
|
|
16
|
+
export declare const generateFunctionBlueprintResourceTemplate: (fnName: string, eventNames: string[]) => string;
|
|
16
17
|
export declare function functionAddCore(options: FunctionAddOptions): Promise<CoreResult>;
|
|
@@ -11,7 +11,7 @@ FUNCTION_TYPES, LABEL_DOCUMENT_CREATE, LABEL_DOCUMENT_DELETE, LABEL_DOCUMENT_UPD
|
|
|
11
11
|
import { check, indent, warn } from '../../utils/display/presenters.js';
|
|
12
12
|
import { styleText } from '../../utils/style-text.js';
|
|
13
13
|
import { validateFunctionName } from '../../utils/validate/resource.js';
|
|
14
|
-
const generateFunctionBlueprintResourceTemplate = (fnName, eventNames) => {
|
|
14
|
+
export const generateFunctionBlueprintResourceTemplate = (fnName, eventNames) => {
|
|
15
15
|
const functionType = eventNames[0].substring(0, eventNames[0].lastIndexOf('-'));
|
|
16
16
|
let definer = '';
|
|
17
17
|
const eventOns = eventNames.map((e) => `'${e.substring(e.lastIndexOf('-') + 1)}'`);
|
|
@@ -19,7 +19,7 @@ const generateFunctionBlueprintResourceTemplate = (fnName, eventNames) => {
|
|
|
19
19
|
case 'document':
|
|
20
20
|
definer = `defineDocumentFunction({name: '${fnName}', event: {on: [${eventOns.join(', ')}]}}), // ← add this line`;
|
|
21
21
|
break;
|
|
22
|
-
case 'media':
|
|
22
|
+
case 'media-library-asset':
|
|
23
23
|
definer = `defineMediaLibraryAssetFunction({name: '${fnName}', event: {on: [${eventOns.join(', ')}], resource: {type: 'media-library', id: 'my-media-library-id'}}}), // ← add this line`;
|
|
24
24
|
break;
|
|
25
25
|
case 'scheduled':
|
|
@@ -28,7 +28,7 @@ export async function functionBuildCore(options) {
|
|
|
28
28
|
for (const resource of functions) {
|
|
29
29
|
const spinner = log.ora(`Building ${resource.name}...`).start();
|
|
30
30
|
const prepResult = await prepareAsset({ resource }, { installer });
|
|
31
|
-
if (
|
|
31
|
+
if (prepResult.success === false) {
|
|
32
32
|
spinner.fail(`Failed to build ${resource.name}`);
|
|
33
33
|
errors.push({ name: resource.name, error: prepResult.error ?? 'Unknown error' });
|
|
34
34
|
continue;
|
|
@@ -58,5 +58,5 @@ export async function functionBuildCore(options) {
|
|
|
58
58
|
log.warn(`${errors.length} function(s) failed to build`);
|
|
59
59
|
}
|
|
60
60
|
log(`\nBuild complete: ${built.length} function(s)`);
|
|
61
|
-
return { success: true };
|
|
61
|
+
return { success: true, json: { built, errors, outDir } };
|
|
62
62
|
}
|
|
@@ -14,5 +14,5 @@ export async function functionEnvRemoveCore(options) {
|
|
|
14
14
|
return { success: false, error: result.error || 'Unknown error' };
|
|
15
15
|
}
|
|
16
16
|
spinner.succeed(`Removal of ${args.key} succeeded`);
|
|
17
|
-
return { success: true };
|
|
17
|
+
return { success: true, json: { name: args.name, key: args.key } };
|
|
18
18
|
}
|
|
@@ -138,7 +138,7 @@ export async function functionTestCore(options) {
|
|
|
138
138
|
event: 'scheduled',
|
|
139
139
|
};
|
|
140
140
|
const spinner = log.ora('Executing function...').start();
|
|
141
|
-
const { json, logs, error } = await testAction(resource, invokeOptions, contextOptions, {
|
|
141
|
+
const { json: response, logs, error, } = await testAction(resource, invokeOptions, contextOptions, {
|
|
142
142
|
timeout: timeout ? timeout : resource.timeout,
|
|
143
143
|
});
|
|
144
144
|
if (error) {
|
|
@@ -151,11 +151,11 @@ export async function functionTestCore(options) {
|
|
|
151
151
|
spinner.succeed('Function execution succeeded.');
|
|
152
152
|
log('Logs:');
|
|
153
153
|
log(logs || '');
|
|
154
|
-
if (
|
|
154
|
+
if (response) {
|
|
155
155
|
log('Response:');
|
|
156
|
-
log(JSON.stringify(
|
|
156
|
+
log(JSON.stringify(response, null, 2));
|
|
157
157
|
}
|
|
158
|
-
return { success: true };
|
|
158
|
+
return { success: true, json: { response, logs } };
|
|
159
159
|
}
|
|
160
160
|
catch (error) {
|
|
161
161
|
return {
|
package/dist/cores/index.d.ts
CHANGED
|
@@ -7,7 +7,7 @@ export interface CoreConfig {
|
|
|
7
7
|
/** The CLI binary name. */
|
|
8
8
|
bin: string;
|
|
9
9
|
/** The log output function. */
|
|
10
|
-
log:
|
|
10
|
+
log: Logger;
|
|
11
11
|
/** Enable resource validation during parsing */
|
|
12
12
|
validateResources?: boolean;
|
|
13
13
|
/** Path to a specific Blueprint file or directory */
|
|
@@ -25,7 +25,10 @@ export interface DeployedBlueprintConfig extends BlueprintConfig {
|
|
|
25
25
|
deployedStack: Stack;
|
|
26
26
|
}
|
|
27
27
|
export type CoreResult = {
|
|
28
|
-
/**
|
|
28
|
+
/**
|
|
29
|
+
* Internal data for isolated testing and debugging.
|
|
30
|
+
* Not returned to users! Use `json` for structured output via oclif's `--json` flag.
|
|
31
|
+
*/
|
|
29
32
|
data?: Record<string, unknown>;
|
|
30
33
|
} & ({
|
|
31
34
|
/** Something went wrong. */
|
|
@@ -40,6 +43,10 @@ export type CoreResult = {
|
|
|
40
43
|
/** The streaming function, if the operation is streaming. */
|
|
41
44
|
streaming?: Promise<void>;
|
|
42
45
|
error?: never;
|
|
46
|
+
/**
|
|
47
|
+
* Structured data returned to the user when `--json` is passed.
|
|
48
|
+
* Commands should return this value from `run()` for oclif to serialize.
|
|
49
|
+
*/
|
|
43
50
|
json?: Record<string, unknown>;
|
|
44
51
|
});
|
|
45
52
|
type InitBlueprintConfigParams = CoreConfig & ({
|
package/dist/cores/index.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { readLocalBlueprint } from '../actions/blueprints/blueprint.js';
|
|
2
2
|
import { getStack, resolveStackIdByNameOrId } from '../actions/blueprints/stacks.js';
|
|
3
3
|
import { presentBlueprintParserErrors } from '../utils/display/errors.js';
|
|
4
|
-
import { niceId } from '../utils/display/presenters.js';
|
|
5
4
|
import { validTokenOrErrorMessage } from '../utils/validated-token.js';
|
|
6
5
|
export * as blueprintsCores from './blueprints/index.js';
|
|
7
6
|
export * as functionsCores from './functions/index.js';
|
|
@@ -55,12 +54,14 @@ export async function initDeployedBlueprintConfig(config) {
|
|
|
55
54
|
config.log(`Incomplete configuration. Run \`${config.bin} blueprints doctor\` for diagnostics.`);
|
|
56
55
|
return { ok: false, error: 'Missing Stack deployment configuration for Blueprint' };
|
|
57
56
|
}
|
|
57
|
+
const spinner = config.log.ora('Loading Stack deployment...').start();
|
|
58
58
|
const stackResponse = await getStack({ stackId, auth, logger: config.log });
|
|
59
59
|
if (!stackResponse.ok) {
|
|
60
|
-
|
|
60
|
+
spinner.fail('Could not load Stack deployment');
|
|
61
61
|
config.log(`Run \`${config.bin} blueprints doctor\` for diagnostics.`);
|
|
62
62
|
return { ok: false, error: 'Missing Stack deployment' };
|
|
63
63
|
}
|
|
64
|
+
spinner.stop().clear();
|
|
64
65
|
return {
|
|
65
66
|
ok: true,
|
|
66
67
|
value: {
|
package/dist/server/app.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { Logger } from '../utils/logger.js';
|
|
2
2
|
import { type InvokeExecutionOptions } from '../utils/types.js';
|
|
3
|
-
declare const app: (host: string, port: number, logger:
|
|
3
|
+
declare const app: (host: string, port: number, logger: Logger, validateResources: boolean, executionOptions?: Partial<InvokeExecutionOptions>) => void;
|
|
4
4
|
declare function parseDocumentUrl(url: string): {
|
|
5
5
|
projectId: string;
|
|
6
6
|
dataset: string;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Logger } from '../../utils/logger.js';
|
|
2
2
|
import type { InvocationResponse, InvokeContextOptions, InvokeExecutionOptions, InvokePayloadMetadata } from '../../utils/types.js';
|
|
3
|
-
export declare function handleInvokeRequest(functionName: string, event: Record<string, unknown>, metadata: InvokePayloadMetadata, context: InvokeContextOptions, logger:
|
|
3
|
+
export declare function handleInvokeRequest(functionName: string, event: Record<string, unknown>, metadata: InvokePayloadMetadata, context: InvokeContextOptions, logger: Logger, validateResources: boolean, executionOptions?: Partial<InvokeExecutionOptions>): Promise<InvocationResponse & {
|
|
4
4
|
timings: Record<string, number>;
|
|
5
5
|
}>;
|
|
@@ -10,7 +10,7 @@ export declare function promptForProject({ token, knownOrganizationId, knownProj
|
|
|
10
10
|
token: string;
|
|
11
11
|
knownOrganizationId?: string;
|
|
12
12
|
knownProjectId?: string;
|
|
13
|
-
logger:
|
|
13
|
+
logger: Logger;
|
|
14
14
|
}): Promise<{
|
|
15
15
|
projectId: string;
|
|
16
16
|
displayName: string;
|
|
@@ -26,7 +26,7 @@ export declare function promptForProject({ token, knownOrganizationId, knownProj
|
|
|
26
26
|
export declare function promptForStack({ projectId, token, logger, }: {
|
|
27
27
|
projectId: string;
|
|
28
28
|
token: string;
|
|
29
|
-
logger:
|
|
29
|
+
logger: Logger;
|
|
30
30
|
}): Promise<{
|
|
31
31
|
stackId: string;
|
|
32
32
|
name: string;
|
|
@@ -95,7 +95,7 @@ export async function promptForStack({ projectId, token, logger, }) {
|
|
|
95
95
|
stackChoices.push({ name: styleText('bold', 'New Stack ✨'), value: NEW_STACK_ID });
|
|
96
96
|
stackChoices.push(new Separator(styleText('underline', 'Use an existing Stack:')));
|
|
97
97
|
stackChoices.push(...stacks.map((s) => ({
|
|
98
|
-
name: `"${s.name}" ${niceId(s.id)} ${styleText('dim', `(${s.resourceCount}
|
|
98
|
+
name: `"${s.name}" ${niceId(s.id)} ${styleText('dim', `(${s.resourceCount} ${s.resourceCount === 1 ? 'resource' : 'resources'})`)}`,
|
|
99
99
|
value: s.id,
|
|
100
100
|
})));
|
|
101
101
|
pickedStackId = await select({
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { BlueprintCorsOriginResource, BlueprintDatasetResource, BlueprintDocumentWebhookResource, BlueprintRobotResource, BlueprintRoleResource } from '@sanity/blueprints';
|
|
2
|
+
import type { Resource } from '@sanity/blueprints-parser';
|
|
2
3
|
import type { TreeInput } from 'array-treeify';
|
|
3
|
-
|
|
4
|
-
export declare function arrayifyFunction(fn: FunctionResourceBase): TreeInput;
|
|
4
|
+
export declare function arrayifyFunction(fn: Resource): TreeInput;
|
|
5
5
|
export declare function arrayifyCors(resource: BlueprintCorsOriginResource): TreeInput;
|
|
6
6
|
export declare function arrayifyRobot(resource: BlueprintRobotResource): TreeInput;
|
|
7
7
|
export declare function arrayifyRole(resource: BlueprintRoleResource): TreeInput;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type ClientConfig } from '@sanity/client';
|
|
2
2
|
import type { Logger } from '../logger.js';
|
|
3
3
|
import type { FetchConfig } from '../types.js';
|
|
4
|
-
export declare function fetchDocument(documentId: string, { projectId, dataset, useCdn, apiVersion, apiHost, token }: ClientConfig, logger:
|
|
5
|
-
export declare function fetchAsset(documentId: string, { mediaLibraryId, apiVersion, apiHost, token }: FetchConfig, logger:
|
|
4
|
+
export declare function fetchDocument(documentId: string, { projectId, dataset, useCdn, apiVersion, apiHost, token }: ClientConfig, logger: Logger): Promise<Record<string, unknown>>;
|
|
5
|
+
export declare function fetchAsset(documentId: string, { mediaLibraryId, apiVersion, apiHost, token }: FetchConfig, logger: Logger): Promise<Record<string, unknown>>;
|
|
@@ -1,11 +1,6 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { AssetPrepResult, FunctionResource, InstallerType } from '../types.js';
|
|
2
2
|
export declare function prepareAsset({ resource, }: {
|
|
3
|
-
resource: FunctionResource
|
|
3
|
+
resource: FunctionResource;
|
|
4
4
|
}, { installer }?: {
|
|
5
5
|
installer?: InstallerType;
|
|
6
|
-
}): Promise<
|
|
7
|
-
success: boolean;
|
|
8
|
-
outputPath?: string;
|
|
9
|
-
cleanup?: () => Promise<void>;
|
|
10
|
-
error?: string;
|
|
11
|
-
}>;
|
|
6
|
+
}): Promise<AssetPrepResult>;
|
|
@@ -29,7 +29,7 @@ export async function prepareAsset({ resource, }, { installer } = {}) {
|
|
|
29
29
|
wasBundled = result.bundled;
|
|
30
30
|
}
|
|
31
31
|
catch (err) {
|
|
32
|
-
return { success: false, error: err instanceof Error ? err.message : `${err}` };
|
|
32
|
+
return { success: false, cleanup, error: err instanceof Error ? err.message : `${err}` };
|
|
33
33
|
}
|
|
34
34
|
}
|
|
35
35
|
const shouldResolveDependencies = await shouldAutoResolveDependencies(resource);
|
|
@@ -45,7 +45,7 @@ export async function prepareAsset({ resource, }, { installer } = {}) {
|
|
|
45
45
|
return { success: true, outputPath: functionPath, cleanup };
|
|
46
46
|
}
|
|
47
47
|
catch (err) {
|
|
48
|
-
return { success: false, error: err instanceof Error ? err.message : `${err}` };
|
|
48
|
+
return { success: false, cleanup, error: err instanceof Error ? err.message : `${err}` };
|
|
49
49
|
}
|
|
50
50
|
}
|
|
51
51
|
/**
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export async function shouldAutoResolveDependencies(resource) {
|
|
2
|
-
if (typeof resource.autoResolveDeps === 'boolean') {
|
|
2
|
+
if ('autoResolveDeps' in resource && typeof resource.autoResolveDeps === 'boolean') {
|
|
3
3
|
return resource.autoResolveDeps;
|
|
4
4
|
}
|
|
5
5
|
// otherwise hydrate is the default
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { findFunctionEntryPoint } from './find-entry-point.js';
|
|
2
2
|
export async function shouldTranspileFunction(resource) {
|
|
3
|
-
if (typeof resource.transpile === 'boolean') {
|
|
3
|
+
if ('transpile' in resource && typeof resource.transpile === 'boolean') {
|
|
4
4
|
return resource.transpile;
|
|
5
5
|
}
|
|
6
6
|
if (!resource.src) {
|
|
@@ -1,10 +1,4 @@
|
|
|
1
|
-
import { type FunctionGroqResource, type FunctionResource, type
|
|
1
|
+
import { type FunctionGroqResource, type FunctionResource, type InvocationResponse, type InvokeContextOptions, type InvokeExecutionOptions, type InvokeGroqPayloadOptions, type InvokePayloadOptions } from './types.js';
|
|
2
2
|
export declare function sanitizeLogs(logs: string): string;
|
|
3
|
-
export declare const DEFAULT_GROQ_RULE: {
|
|
4
|
-
on: string[];
|
|
5
|
-
filter: string;
|
|
6
|
-
projection: string;
|
|
7
|
-
};
|
|
8
|
-
export declare function isDefaultGROQRule(rule: GroqRuleBase | undefined): boolean;
|
|
9
3
|
export declare function applyGroqRule(resource: FunctionGroqResource, payload: InvokeGroqPayloadOptions, projectId: string | undefined, dataset: string | undefined): Promise<any>;
|
|
10
4
|
export default function invoke(resource: FunctionResource, payload: InvokePayloadOptions, context: InvokeContextOptions, options: InvokeExecutionOptions): Promise<InvocationResponse>;
|