@sanity/runtime-cli 17.15.0 → 17.16.0-next.g05d3b7f
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 +19 -19
- package/dist/actions/blueprints/assets.d.ts +3 -3
- package/dist/actions/blueprints/assets.js +3 -3
- package/dist/actions/blueprints/blueprint.d.ts +20 -9
- package/dist/actions/blueprints/blueprint.js +25 -79
- package/dist/actions/blueprints/config.d.ts +1 -0
- package/dist/actions/blueprints/config.js +7 -1
- package/dist/actions/blueprints/pre-deploy.js +3 -3
- package/dist/actions/blueprints/process-assets.js +3 -2
- package/dist/baseCommands.js +3 -3
- package/dist/config.d.ts +1 -2
- package/dist/config.js +1 -2
- package/dist/cores/blueprints/doctor.js +2 -2
- package/dist/cores/blueprints/init.js +11 -2
- package/dist/cores/functions/logs.d.ts +7 -0
- package/dist/cores/functions/logs.js +17 -6
- package/dist/cores/functions/test.js +43 -9
- package/dist/server/app.js +4 -4
- package/dist/server/static/components/app.css +8 -1
- package/dist/utils/blueprints/group-resources.d.ts +2 -1
- package/dist/utils/blueprints/group-resources.js +3 -3
- package/dist/utils/blueprints/resolve-deployed-resources.d.ts +2 -2
- package/dist/utils/blueprints/resolve-deployed-resources.js +4 -4
- package/dist/utils/bundles/prepare-asset.d.ts +3 -3
- package/dist/utils/bundles/prepare-asset.js +8 -7
- package/dist/utils/functions/child-process-wrapper.js +1 -1
- package/dist/utils/functions/child-runtime/durable.js +141 -23
- package/dist/utils/functions/child-runtime/getBatchResults.js +75 -0
- package/dist/utils/functions/child-runtime/invoke.d.ts +1 -0
- package/dist/utils/functions/child-runtime/invoke.js +26 -9
- package/dist/utils/functions/child-runtime/step-history.d.ts +15 -0
- package/dist/utils/functions/child-runtime/step-history.js +52 -0
- package/dist/utils/functions/extract-durable-config.js +1 -4
- package/dist/utils/functions/invoke/local.js +27 -11
- package/dist/utils/functions/invoke/nested.js +2 -1
- package/dist/utils/functions/invoke/resolve-invoke-type.d.ts +2 -2
- package/dist/utils/functions/invoke/resolve-invoke-type.js +2 -2
- package/dist/utils/functions/transpile/function.js +3 -0
- package/dist/utils/types.d.ts +24 -13
- package/dist/utils/types.js +1 -1
- package/oclif.manifest.json +1 -1
- package/package.json +3 -3
- package/dist/actions/blueprints/resolve.d.ts +0 -51
- package/dist/actions/blueprints/resolve.js +0 -52
|
@@ -10,6 +10,17 @@ export function createInvoker() {
|
|
|
10
10
|
const pending = new Map()
|
|
11
11
|
let invokeSeq = 0
|
|
12
12
|
|
|
13
|
+
function sendInvokeRequest(name, payload = {}, metadata = {}) {
|
|
14
|
+
if (typeof name !== 'string' || name.length === 0) {
|
|
15
|
+
return Promise.reject(new Error('context.invoke requires a function name'))
|
|
16
|
+
}
|
|
17
|
+
const id = String(++invokeSeq)
|
|
18
|
+
return new Promise((resolve, reject) => {
|
|
19
|
+
pending.set(id, {resolve, reject})
|
|
20
|
+
process.send(JSON.stringify({type: 'invoke-request', id, name, payload, metadata}))
|
|
21
|
+
})
|
|
22
|
+
}
|
|
23
|
+
|
|
13
24
|
/**
|
|
14
25
|
* `context.invoke(name, payload)` — ask the parent to execute another blueprint
|
|
15
26
|
* function and resolve with its return value. Sent over IPC and correlated by id.
|
|
@@ -18,14 +29,20 @@ export function createInvoker() {
|
|
|
18
29
|
* @returns {Promise<unknown>}
|
|
19
30
|
*/
|
|
20
31
|
function invoke(name, payload = {}) {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
32
|
+
return sendInvokeRequest(name, payload)
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* durable `step.delegate(name, payload)` — ask the parent durable to execute another blueprint function
|
|
37
|
+
* and resolve with its return value. Sent over IPC and correlated by id. Adds an `origin` field to the message so the parent can
|
|
38
|
+
* distinguish between a normal invoke and a durable delegate for logging purposes.
|
|
39
|
+
* @param {string} name
|
|
40
|
+
* @param {Record<string, unknown>} [payload]
|
|
41
|
+
* @returns {Promise<unknown>}
|
|
42
|
+
*/
|
|
43
|
+
function delegate(name, payload = {}) {
|
|
44
|
+
const metadata = {origin: 'step.delegate'}
|
|
45
|
+
return sendInvokeRequest(name, payload, metadata)
|
|
29
46
|
}
|
|
30
47
|
|
|
31
48
|
function handleResponse(msg) {
|
|
@@ -43,5 +60,5 @@ export function createInvoker() {
|
|
|
43
60
|
}
|
|
44
61
|
}
|
|
45
62
|
|
|
46
|
-
return {invoke, handleResponse}
|
|
63
|
+
return {delegate, invoke, handleResponse}
|
|
47
64
|
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type {DurableStepEvent} from './types'
|
|
2
|
+
|
|
3
|
+
type PendingRetry = {index: number; event: DurableStepEvent; delayMs: number}
|
|
4
|
+
|
|
5
|
+
export function createStepHistory(): {
|
|
6
|
+
startRun: () => void
|
|
7
|
+
nextStep: () => {index: number; saved: DurableStepEvent | undefined}
|
|
8
|
+
recordSuccess: (index: number, event: DurableStepEvent) => void
|
|
9
|
+
recordFailure: (
|
|
10
|
+
index: number,
|
|
11
|
+
failure: {event: DurableStepEvent; error: unknown; delayMs: number},
|
|
12
|
+
) => boolean
|
|
13
|
+
getPending: () => PendingRetry | null
|
|
14
|
+
settle: (pending: PendingRetry) => void
|
|
15
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
const createStepHistory = () => {
|
|
2
|
+
const history = new Map([])
|
|
3
|
+
let cursor = 0
|
|
4
|
+
let pending = null
|
|
5
|
+
|
|
6
|
+
const startRun = () => {
|
|
7
|
+
cursor = 0
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
const nextStep = () => {
|
|
11
|
+
const index = cursor
|
|
12
|
+
cursor++
|
|
13
|
+
return {index, saved: history.get(index)}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const recordSuccess = (index, event) => {
|
|
17
|
+
history.set(index, event)
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const recordFailure = (index, {event, error, delayMs}) => {
|
|
21
|
+
const retryable = event.attempt <= event.retries && error?.name !== 'UnrecoverableError'
|
|
22
|
+
|
|
23
|
+
if (retryable) {
|
|
24
|
+
history.set(index, {...event, output: error, retryDelayMs: delayMs})
|
|
25
|
+
pending = {index, event, delayMs}
|
|
26
|
+
} else {
|
|
27
|
+
history.set(index, {...event, output: error})
|
|
28
|
+
}
|
|
29
|
+
return retryable
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const getPending = () => {
|
|
33
|
+
const item = pending
|
|
34
|
+
pending = null
|
|
35
|
+
return item
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const settle = ({index, event}) => {
|
|
39
|
+
history.set(index, {...event, output: history.get(index).output})
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
return {
|
|
43
|
+
startRun,
|
|
44
|
+
nextStep,
|
|
45
|
+
recordSuccess,
|
|
46
|
+
recordFailure,
|
|
47
|
+
getPending,
|
|
48
|
+
settle,
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export {createStepHistory}
|
|
@@ -5,7 +5,7 @@ import { SANITY_FUNCTION_DURABLE } from '../../constants.js';
|
|
|
5
5
|
import { isLocalFunctionResource } from '../types.js';
|
|
6
6
|
import { findFunctionEntryPoint } from './find-entry-point.js';
|
|
7
7
|
import { transpileFunction } from './transpile/function.js';
|
|
8
|
-
const DURABLE_CONFIG_KEYS = ['event', 'concurrency', 'debounce'
|
|
8
|
+
const DURABLE_CONFIG_KEYS = ['event', 'concurrency', 'debounce'];
|
|
9
9
|
/**
|
|
10
10
|
* Extracts the blueprint config from the function source code and mutates it to the resource object.
|
|
11
11
|
* This is used for durable functions that may not have a config defined in the blueprint.
|
|
@@ -47,9 +47,6 @@ export const extractDurableConfig = async (resource, blueprintFileDir) => {
|
|
|
47
47
|
if (resource.debounce === undefined && config?.debounce !== undefined) {
|
|
48
48
|
resource.debounce = config.debounce;
|
|
49
49
|
}
|
|
50
|
-
if (resource.debounceKey === undefined && config?.debounceKey !== undefined) {
|
|
51
|
-
resource.debounceKey = config.debounceKey;
|
|
52
|
-
}
|
|
53
50
|
// Validate the resource after merging the config values
|
|
54
51
|
const errors = validateDurableFunction(resource);
|
|
55
52
|
if (errors.length > 0) {
|
|
@@ -64,10 +64,11 @@ export default async function invoke(resource, payload, context, options) {
|
|
|
64
64
|
// Apply the GROQ rule before preparing a build so a filtered-out event skips
|
|
65
65
|
// the (potentially expensive) transpile entirely.
|
|
66
66
|
if (isGroqInvocation(resource)) {
|
|
67
|
-
if (!
|
|
67
|
+
if (!('clientOptions' in context)) {
|
|
68
68
|
throw new Error('GROQ-based functions require a context with clientOptions');
|
|
69
69
|
}
|
|
70
|
-
const
|
|
70
|
+
const projectId = 'projectId' in context.clientOptions ? context.clientOptions.projectId : undefined;
|
|
71
|
+
const dataset = 'dataset' in context.clientOptions ? context.clientOptions.dataset : undefined;
|
|
71
72
|
if ('before' in payload) {
|
|
72
73
|
filteredData = await applyGroqRule(resource, payload, projectId, dataset);
|
|
73
74
|
const filter = resource.event && 'filter' in resource.event ? resource.event.filter : '';
|
|
@@ -156,14 +157,14 @@ export default async function invoke(resource, payload, context, options) {
|
|
|
156
157
|
// Resolve a nested `context.invoke(name, payload)` by re-entering the invoke
|
|
157
158
|
// pipeline via the supplied callback, then hand the result back to the child.
|
|
158
159
|
async function handleNestedInvoke(msg) {
|
|
159
|
-
const { id, name, payload: nestedPayload } = msg;
|
|
160
|
+
const { id, name, payload: nestedPayload, metadata } = msg;
|
|
160
161
|
pauseTimer();
|
|
161
162
|
const nestedStart = performance.now();
|
|
162
163
|
try {
|
|
163
164
|
if (!onNestedInvoke) {
|
|
164
165
|
throw new Error('Nested context.invoke is not supported in this context');
|
|
165
166
|
}
|
|
166
|
-
const nested = await onNestedInvoke(name, nestedPayload ?? {}, context, depth + 1, callStack);
|
|
167
|
+
const nested = await onNestedInvoke(name, nestedPayload ?? {}, context, depth + 1, callStack, metadata);
|
|
167
168
|
nestedTimings[`invoke:${name}`] =
|
|
168
169
|
(nestedTimings[`invoke:${name}`] ?? 0) + (performance.now() - nestedStart);
|
|
169
170
|
// Fire-and-forget contract: in production `context.invoke` returns once the
|
|
@@ -173,12 +174,22 @@ export default async function invoke(resource, payload, context, options) {
|
|
|
173
174
|
// of `nested.error`. The error isn't lost: it travels back in the returned
|
|
174
175
|
// result and is logged/streamed to the UI by the caller (app/test core).
|
|
175
176
|
if (child && !child.killed) {
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
177
|
+
// step.delegate errors need to be surfaced to the caller for retry behavior and for the durable step to be marked as failed.
|
|
178
|
+
const origin = metadata?.origin || undefined;
|
|
179
|
+
const error = nested.error || undefined;
|
|
180
|
+
const response = origin === 'step.delegate' && error
|
|
181
|
+
? {
|
|
182
|
+
type: 'invoke-response',
|
|
183
|
+
id,
|
|
184
|
+
ok: false,
|
|
185
|
+
error,
|
|
186
|
+
}
|
|
187
|
+
: {
|
|
188
|
+
type: 'invoke-response',
|
|
189
|
+
id,
|
|
190
|
+
ok: true,
|
|
191
|
+
result: { json: nested.json },
|
|
192
|
+
};
|
|
182
193
|
child.send(JSON.stringify(response));
|
|
183
194
|
}
|
|
184
195
|
}
|
|
@@ -231,7 +242,12 @@ export default async function invoke(resource, payload, context, options) {
|
|
|
231
242
|
}
|
|
232
243
|
// Nested invoke request — handle without tearing down the child.
|
|
233
244
|
if (msg?.type === 'invoke-request') {
|
|
234
|
-
handleNestedInvoke({
|
|
245
|
+
handleNestedInvoke({
|
|
246
|
+
id: msg.id,
|
|
247
|
+
name: msg.name,
|
|
248
|
+
payload: msg.payload,
|
|
249
|
+
metadata: msg.metadata,
|
|
250
|
+
});
|
|
235
251
|
return;
|
|
236
252
|
}
|
|
237
253
|
// Terminal result message.
|
|
@@ -28,7 +28,7 @@ export function assertNestedInvokeAllowed(name, depth, callStack) {
|
|
|
28
28
|
* stack extended by this function, and normalize timings.
|
|
29
29
|
*/
|
|
30
30
|
export async function runFunction(resource, payload, context, options) {
|
|
31
|
-
const { forceColor, timeout, depth = 0, callStack = [], onNestedInvoke } = options;
|
|
31
|
+
const { forceColor, timeout, depth = 0, callStack = [], onNestedInvoke, onStepEvent } = options;
|
|
32
32
|
assertNestedInvokeAllowed(resource.name, depth, callStack);
|
|
33
33
|
const response = await invoke(resource, payload, context, {
|
|
34
34
|
forceColor,
|
|
@@ -36,6 +36,7 @@ export async function runFunction(resource, payload, context, options) {
|
|
|
36
36
|
onNestedInvoke,
|
|
37
37
|
depth,
|
|
38
38
|
callStack: [...callStack, resource.name],
|
|
39
|
+
onStepEvent,
|
|
39
40
|
});
|
|
40
41
|
return { ...response, timings: response.timings ?? {} };
|
|
41
42
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { BlueprintResource } from '@sanity/blueprints';
|
|
2
2
|
import type { Logger } from '../../logger.js';
|
|
3
|
-
import type { EventType, FunctionGroqResource, FunctionResource, FunctionTestFlags, InvokeContextOptions, InvokePayloadOptions } from '../../types.js';
|
|
3
|
+
import type { EventType, FunctionGroqResource, FunctionResource, FunctionTestFlags, InvokeContextOptions, InvokePayloadOptions, ResolvedResource } from '../../types.js';
|
|
4
4
|
import buildPayload from '../build-payload.js';
|
|
5
5
|
import { fetchAsset, fetchDocument } from '../fetch-document.js';
|
|
6
6
|
export type InvocationPlan = {
|
|
@@ -23,7 +23,7 @@ export type InputContext = {
|
|
|
23
23
|
apiHost: string;
|
|
24
24
|
token?: string;
|
|
25
25
|
withUserToken?: boolean;
|
|
26
|
-
|
|
26
|
+
resolvedResources: ResolvedResource<BlueprintResource>[];
|
|
27
27
|
blueprintFileDir: string;
|
|
28
28
|
log: Logger;
|
|
29
29
|
};
|
|
@@ -51,7 +51,7 @@ export const buildContext = (plan, input) => {
|
|
|
51
51
|
if (plan.kind === 'plain') {
|
|
52
52
|
return {
|
|
53
53
|
clientOptions: { ...withToken },
|
|
54
|
-
resources: input.
|
|
54
|
+
resources: input.resolvedResources,
|
|
55
55
|
blueprintFileDir: input.blueprintFileDir,
|
|
56
56
|
};
|
|
57
57
|
}
|
|
@@ -69,7 +69,7 @@ export const buildContext = (plan, input) => {
|
|
|
69
69
|
'',
|
|
70
70
|
functionResourceType: 'project',
|
|
71
71
|
functionResourceId: input.projectId || '',
|
|
72
|
-
resources: input.
|
|
72
|
+
resources: input.resolvedResources,
|
|
73
73
|
blueprintFileDir: input.blueprintFileDir,
|
|
74
74
|
};
|
|
75
75
|
};
|
|
@@ -37,6 +37,9 @@ export async function transpileFunction({ resource, functionPath, entryPoint, in
|
|
|
37
37
|
const bundle = !!find.file('pnpm-workspace.yaml') || installer === 'pnpm';
|
|
38
38
|
const result = await viteBuild({
|
|
39
39
|
root: fnRootDir,
|
|
40
|
+
// Don't pick up the surrounding project's public/ folder or vite.config.*
|
|
41
|
+
publicDir: false,
|
|
42
|
+
configFile: false,
|
|
40
43
|
logLevel: 'silent',
|
|
41
44
|
build: {
|
|
42
45
|
target: 'node20',
|
package/dist/utils/types.d.ts
CHANGED
|
@@ -40,6 +40,11 @@ export interface BlueprintResourceRecord extends BlueprintResource {
|
|
|
40
40
|
export interface DeployedResource extends BlueprintResourceRecord {
|
|
41
41
|
externalId: string;
|
|
42
42
|
}
|
|
43
|
+
/** Wrap a resource and its externalId if it has one. */
|
|
44
|
+
export interface ResolvedResource<R extends BlueprintResource> {
|
|
45
|
+
resource: R;
|
|
46
|
+
externalId?: string;
|
|
47
|
+
}
|
|
43
48
|
export declare function isLocalFunctionResource(r: BlueprintResource): r is FunctionResource;
|
|
44
49
|
export declare function hasEventSource(r: FunctionResource): r is EventFunctionResource;
|
|
45
50
|
export declare function isScheduleEvent(e: unknown): e is BlueprintScheduledFunctionResource['event'];
|
|
@@ -134,8 +139,14 @@ export type InvokePayloadMetadata = Pick<InvokeGroqPayloadOptions, 'event' | 'be
|
|
|
134
139
|
export type EventType = 'create' | 'update' | 'delete';
|
|
135
140
|
export type NonGroqEventType = 'plain' | 'nested' | 'durable';
|
|
136
141
|
export declare function isEventType(arg: string): arg is EventType;
|
|
142
|
+
interface BaseContextOptions {
|
|
143
|
+
/** All resources declared by the blueprint, used to populate `context.resources` at invoke time. */
|
|
144
|
+
resources?: ResolvedResource<BlueprintResource>[];
|
|
145
|
+
/** The directory where the blueprint manifest is located. */
|
|
146
|
+
blueprintFileDir: string;
|
|
147
|
+
}
|
|
137
148
|
/** @internal */
|
|
138
|
-
export interface InvokeGroqContextOptions {
|
|
149
|
+
export interface InvokeGroqContextOptions extends BaseContextOptions {
|
|
139
150
|
clientOptions: {
|
|
140
151
|
apiVersion?: string;
|
|
141
152
|
dataset?: string;
|
|
@@ -151,20 +162,12 @@ export interface InvokeGroqContextOptions {
|
|
|
151
162
|
functionResourceType: string;
|
|
152
163
|
/** The resource ID of the function container; resource ID that houses the function. */
|
|
153
164
|
functionResourceId: string;
|
|
154
|
-
/** All resources declared by the blueprint, used to populate `context.resources` at invoke time. */
|
|
155
|
-
resources?: BlueprintResource[];
|
|
156
|
-
/** The directory where the blueprint manifest is located. */
|
|
157
|
-
blueprintFileDir: string;
|
|
158
165
|
}
|
|
159
166
|
/** @internal */
|
|
160
|
-
export interface InvokeScheduleContextOptions {
|
|
167
|
+
export interface InvokeScheduleContextOptions extends BaseContextOptions {
|
|
161
168
|
clientOptions: {
|
|
162
169
|
token?: string;
|
|
163
170
|
};
|
|
164
|
-
/** All resources declared by the blueprint, used to populate `context.resources` at invoke time. */
|
|
165
|
-
resources?: BlueprintResource[];
|
|
166
|
-
/** The directory where the blueprint manifest is located. */
|
|
167
|
-
blueprintFileDir: string;
|
|
168
171
|
}
|
|
169
172
|
export type InvokeContextOptions = InvokeGroqContextOptions | InvokeScheduleContextOptions;
|
|
170
173
|
export declare function isGroqContextOptions(context: InvokeContextOptions): context is InvokeGroqContextOptions;
|
|
@@ -187,12 +190,15 @@ export interface InvokeExecutionOptions {
|
|
|
187
190
|
/** Don't wait the full duration during a wait durable event @internal */
|
|
188
191
|
noWait?: boolean;
|
|
189
192
|
}
|
|
193
|
+
export type NestedInvokeMetadata = {
|
|
194
|
+
origin?: 'step.delegate';
|
|
195
|
+
};
|
|
190
196
|
/**
|
|
191
197
|
* Re-entrant callback that executes a named function from the blueprint on behalf
|
|
192
198
|
* of a nested `context.invoke(name, payload)` and returns its invocation result.
|
|
193
199
|
* @internal
|
|
194
200
|
*/
|
|
195
|
-
export type NestedInvoke = (name: string, payload: Record<string, unknown>, context: InvokeContextOptions, depth: number, callStack: string[]) => Promise<InvocationResponse & {
|
|
201
|
+
export type NestedInvoke = (name: string, payload: Record<string, unknown>, context: InvokeContextOptions, depth: number, callStack: string[], metadata?: NestedInvokeMetadata) => Promise<InvocationResponse & {
|
|
196
202
|
timings: Record<string, number>;
|
|
197
203
|
}>;
|
|
198
204
|
/**
|
|
@@ -233,6 +239,7 @@ export type ChildToParentMessage = {
|
|
|
233
239
|
name: string;
|
|
234
240
|
payload: Record<string, unknown>;
|
|
235
241
|
isDurable?: boolean;
|
|
242
|
+
metadata?: NestedInvokeMetadata;
|
|
236
243
|
} | {
|
|
237
244
|
type: 'result';
|
|
238
245
|
json?: JsonInvocationResponse;
|
|
@@ -334,7 +341,7 @@ export type AssetPrepResult = {
|
|
|
334
341
|
error: string;
|
|
335
342
|
};
|
|
336
343
|
export type PrepAssetFn<R extends BlueprintResource> = (options: {
|
|
337
|
-
|
|
344
|
+
resolvedResource: ResolvedResource<R>;
|
|
338
345
|
blueprintFileDir: string;
|
|
339
346
|
installer?: InstallerType;
|
|
340
347
|
}) => Promise<AssetPrepResult>;
|
|
@@ -351,7 +358,7 @@ export type PreDeployConfig = {
|
|
|
351
358
|
prepareResource?: PrepResourceFn<BlueprintResource>;
|
|
352
359
|
};
|
|
353
360
|
export type AssetResource<R extends BlueprintResource> = {
|
|
354
|
-
resource: R
|
|
361
|
+
resource: ResolvedResource<R>;
|
|
355
362
|
prepareAsset: PrepAssetFn<R>;
|
|
356
363
|
};
|
|
357
364
|
export type Warning = {
|
|
@@ -372,6 +379,10 @@ export interface DurableStepEvent {
|
|
|
372
379
|
output?: unknown;
|
|
373
380
|
error?: InvocationError;
|
|
374
381
|
durationMs?: number;
|
|
382
|
+
retryDelayMs?: number;
|
|
383
|
+
attempt?: number;
|
|
384
|
+
retries?: number;
|
|
385
|
+
maxAttempts?: number;
|
|
375
386
|
}
|
|
376
387
|
export interface DurableLogEvent {
|
|
377
388
|
kind: 'log';
|
package/dist/utils/types.js
CHANGED
|
@@ -38,7 +38,7 @@ export function isEventType(arg) {
|
|
|
38
38
|
return ['create', 'update', 'delete'].includes(arg);
|
|
39
39
|
}
|
|
40
40
|
export function isGroqContextOptions(context) {
|
|
41
|
-
return '
|
|
41
|
+
return 'eventResourceType' in context;
|
|
42
42
|
}
|
|
43
43
|
/** @internal */
|
|
44
44
|
export var BlueprintParserErrorType;
|
package/oclif.manifest.json
CHANGED
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sanity/runtime-cli",
|
|
3
3
|
"description": "Sanity's Runtime CLI for Blueprints and Functions",
|
|
4
|
-
"version": "17.
|
|
4
|
+
"version": "17.16.0-next.g05d3b7f",
|
|
5
5
|
"author": "Sanity Runtime Team",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"license": "MIT",
|
|
@@ -68,7 +68,7 @@
|
|
|
68
68
|
"@oclif/core": "^4.14.0",
|
|
69
69
|
"@oclif/plugin-help": "^6.3.0",
|
|
70
70
|
"@sanity-labs/oclif-plugin-skills-flag": "^0.2.1",
|
|
71
|
-
"@sanity/blueprints": "^0.
|
|
71
|
+
"@sanity/blueprints": "^0.28.0",
|
|
72
72
|
"@sanity/blueprints-parser": "^0.5.0",
|
|
73
73
|
"@sanity/cli-build": "^6.3.0",
|
|
74
74
|
"@sanity/cli-core": "^3.7.0",
|
|
@@ -100,7 +100,7 @@
|
|
|
100
100
|
"@oclif/test": "^4.2.0",
|
|
101
101
|
"@playwright/test": "^1.63.0",
|
|
102
102
|
"@sanity-labs/design-tokens": "^0.0.2-alpha.2",
|
|
103
|
-
"@sanity/functions": "^1.
|
|
103
|
+
"@sanity/functions": "^1.10.1",
|
|
104
104
|
"@types/cardinal": "^2.1.1",
|
|
105
105
|
"@types/mime-types": "^3.0.1",
|
|
106
106
|
"@types/node": "^22",
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
import type { ScopeType } from '../../utils/types.js';
|
|
2
|
-
/**
|
|
3
|
-
* Source of a resolved config value.
|
|
4
|
-
* - flags: from CLI flags like `--project-id`
|
|
5
|
-
* - env: from the environment - usually CLI var like `SANITY_ORGANIZATION_ID`
|
|
6
|
-
* - module: from the blueprint module - undocumented escape hatch
|
|
7
|
-
* - config: from the config file - .sanity/blueprint.config.json most common
|
|
8
|
-
* - inferred: legacy `ST-<projectId>` stacks from launch
|
|
9
|
-
*/
|
|
10
|
-
export type ConfigSource = 'flags' | 'env' | 'module' | 'config' | 'inferred';
|
|
11
|
-
/** A set of optional IDs from a single source. */
|
|
12
|
-
export interface IdValues {
|
|
13
|
-
organizationId?: string;
|
|
14
|
-
projectId?: string;
|
|
15
|
-
stackId?: string;
|
|
16
|
-
}
|
|
17
|
-
/**
|
|
18
|
-
* Sources to resolve IDs from, in descending priority.
|
|
19
|
-
* Each key maps to a source; the first non-empty value wins.
|
|
20
|
-
*
|
|
21
|
-
* - `env` defaults to reading SANITY_* process.env vars
|
|
22
|
-
* - `module` and `config` accept any object with `{organizationId?, projectId?, stackId?}`
|
|
23
|
-
*/
|
|
24
|
-
export interface IdSources {
|
|
25
|
-
flags?: IdValues | null;
|
|
26
|
-
env?: IdValues | null;
|
|
27
|
-
module?: IdValues | null;
|
|
28
|
-
config?: IdValues | null;
|
|
29
|
-
}
|
|
30
|
-
export interface ResolvedIds {
|
|
31
|
-
organizationId?: string;
|
|
32
|
-
projectId?: string;
|
|
33
|
-
stackId?: string;
|
|
34
|
-
scopeType?: ScopeType;
|
|
35
|
-
scopeId?: string;
|
|
36
|
-
sources: {
|
|
37
|
-
organizationId?: ConfigSource;
|
|
38
|
-
projectId?: ConfigSource;
|
|
39
|
-
stackId?: ConfigSource;
|
|
40
|
-
};
|
|
41
|
-
}
|
|
42
|
-
/**
|
|
43
|
-
* Resolve organization, project, and stack IDs from a prioritized set of sources.
|
|
44
|
-
* Precedence: flags > env > module > config.
|
|
45
|
-
* Derives scopeType/scopeId from the resolved IDs (project > organization).
|
|
46
|
-
*
|
|
47
|
-
* Env vars are read from process.env by default (SANITY_ORGANIZATION_ID,
|
|
48
|
-
* SANITY_PROJECT_ID, SANITY_BLUEPRINT_STACK_ID). Pass `env` explicitly to
|
|
49
|
-
* override, or `null` to skip.
|
|
50
|
-
*/
|
|
51
|
-
export declare function resolveIds(sources?: IdSources): ResolvedIds;
|
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
import { env as processEnv } from 'node:process';
|
|
2
|
-
/**
|
|
3
|
-
* Resolve organization, project, and stack IDs from a prioritized set of sources.
|
|
4
|
-
* Precedence: flags > env > module > config.
|
|
5
|
-
* Derives scopeType/scopeId from the resolved IDs (project > organization).
|
|
6
|
-
*
|
|
7
|
-
* Env vars are read from process.env by default (SANITY_ORGANIZATION_ID,
|
|
8
|
-
* SANITY_PROJECT_ID, SANITY_BLUEPRINT_STACK_ID). Pass `env` explicitly to
|
|
9
|
-
* override, or `null` to skip.
|
|
10
|
-
*/
|
|
11
|
-
export function resolveIds(sources = {}) {
|
|
12
|
-
const envValues = sources.env !== undefined
|
|
13
|
-
? sources.env
|
|
14
|
-
: {
|
|
15
|
-
organizationId: processEnv.SANITY_ORGANIZATION_ID,
|
|
16
|
-
projectId: processEnv.SANITY_PROJECT_ID,
|
|
17
|
-
stackId: processEnv.SANITY_BLUEPRINT_STACK_ID,
|
|
18
|
-
};
|
|
19
|
-
const ordered = [
|
|
20
|
-
{ source: 'flags', values: sources.flags },
|
|
21
|
-
{ source: 'env', values: envValues },
|
|
22
|
-
{ source: 'module', values: sources.module },
|
|
23
|
-
{ source: 'config', values: sources.config },
|
|
24
|
-
];
|
|
25
|
-
const result = { sources: {} };
|
|
26
|
-
for (const { source, values } of ordered) {
|
|
27
|
-
if (values === null || values === undefined)
|
|
28
|
-
continue;
|
|
29
|
-
if (!result.organizationId && values.organizationId) {
|
|
30
|
-
result.organizationId = values.organizationId;
|
|
31
|
-
result.sources.organizationId = source;
|
|
32
|
-
}
|
|
33
|
-
if (!result.projectId && values.projectId) {
|
|
34
|
-
result.projectId = values.projectId;
|
|
35
|
-
result.sources.projectId = source;
|
|
36
|
-
}
|
|
37
|
-
if (!result.stackId && values.stackId) {
|
|
38
|
-
result.stackId = values.stackId;
|
|
39
|
-
result.sources.stackId = source;
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
// Scope is as specific as possible; project > organization
|
|
43
|
-
if (result.projectId) {
|
|
44
|
-
result.scopeType = 'project';
|
|
45
|
-
result.scopeId = result.projectId;
|
|
46
|
-
}
|
|
47
|
-
else if (result.organizationId) {
|
|
48
|
-
result.scopeType = 'organization';
|
|
49
|
-
result.scopeId = result.organizationId;
|
|
50
|
-
}
|
|
51
|
-
return result;
|
|
52
|
-
}
|