Files
wehub-resource-sync d25d482dc2
Publish CLI Package / publish-npm (push) Waiting to run
Publish Python SDK / publish-pypi (push) Waiting to run
Publish TypeScript SDK / publish-npm (push) Waiting to run
CI / Migrate Dev DB (push) Has been skipped
CI / Detect Version (push) Has been cancelled
CI / Migrate DB (push) Has been cancelled
CI / Build Dev ECR (./docker/app.Dockerfile, ECR_APP) (push) Has been cancelled
CI / Build Dev ECR (./docker/db.Dockerfile, ECR_MIGRATIONS) (push) Has been cancelled
CI / Build Dev ECR (./docker/pii.Dockerfile, ECR_PII) (push) Has been cancelled
CI / Build Dev ECR (./docker/realtime.Dockerfile, ECR_REALTIME) (push) Has been cancelled
CI / Deploy Trigger.dev (Dev) (push) Has been cancelled
CI / Build AMD64 (./docker/app.Dockerfile, ECR_APP, ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Build AMD64 (./docker/db.Dockerfile, ECR_MIGRATIONS, ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Build AMD64 (./docker/pii.Dockerfile, ECR_PII, ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Build AMD64 (./docker/realtime.Dockerfile, ECR_REALTIME, ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/app.Dockerfile, ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/db.Dockerfile, ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/pii.Dockerfile, ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/realtime.Dockerfile, ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Check Docs Changes (push) Has been cancelled
CI / Process Docs (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
CI / Test and Build (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 13:20:55 +08:00

128 lines
4.4 KiB
TypeScript

import { toError } from '@sim/utils/errors'
import { recordMaterializedAccessKeys } from '@/lib/execution/payloads/access-keys'
import {
isLargeArrayManifest,
LARGE_ARRAY_MANIFEST_MARKER,
materializeLargeArrayManifest,
} from '@/lib/execution/payloads/large-array-manifest'
import { isLargeValueRef, LARGE_VALUE_REF_MARKER } from '@/lib/execution/payloads/large-value-ref'
import { MAX_DURABLE_LARGE_VALUE_BYTES } from '@/lib/execution/payloads/materialization.server'
import { materializeLargeValueRef } from '@/lib/execution/payloads/store'
import { REFERENCE } from '@/executor/constants'
import type { ExecutionContext } from '@/executor/types'
import type { VariableResolver } from '@/executor/variables/resolver'
async function normalizeCollectionValue(ctx: ExecutionContext, value: unknown): Promise<any[]> {
if (Array.isArray(value)) {
return value
}
if (isLargeArrayManifest(value)) {
const materialized = await materializeLargeArrayManifest(value, {
workspaceId: ctx.workspaceId,
workflowId: ctx.workflowId,
executionId: ctx.executionId,
largeValueExecutionIds: ctx.largeValueExecutionIds,
largeValueKeys: ctx.largeValueKeys,
fileKeys: ctx.fileKeys,
allowLargeValueWorkflowScope: ctx.allowLargeValueWorkflowScope,
userId: ctx.userId,
maxBytes: MAX_DURABLE_LARGE_VALUE_BYTES,
})
recordMaterializedAccessKeys(ctx, materialized)
return materialized
}
if (isLargeValueRef(value)) {
const materialized = await materializeLargeValueRef(value, {
workspaceId: ctx.workspaceId,
workflowId: ctx.workflowId,
executionId: ctx.executionId,
largeValueExecutionIds: ctx.largeValueExecutionIds,
largeValueKeys: ctx.largeValueKeys,
fileKeys: ctx.fileKeys,
allowLargeValueWorkflowScope: ctx.allowLargeValueWorkflowScope,
userId: ctx.userId,
maxBytes: MAX_DURABLE_LARGE_VALUE_BYTES,
})
if (materialized === undefined) {
throw new Error('Large execution value is unavailable.')
}
recordMaterializedAccessKeys(ctx, materialized)
return normalizeCollectionValue(ctx, materialized)
}
if (typeof value === 'object' && value !== null) {
if ((value as Record<string, unknown>)[LARGE_ARRAY_MANIFEST_MARKER] === true) {
throw new Error('Invalid large array manifest.')
}
if ((value as Record<string, unknown>)[LARGE_VALUE_REF_MARKER] === true) {
throw new Error('Invalid large value ref.')
}
return Object.entries(value)
}
if (value === null) {
return []
}
throw new Error('Value did not resolve to an array or object')
}
/**
* Resolves loop/parallel collection inputs on the server, including durable
* execution values that cannot be imported into client-reachable utilities.
*/
export async function resolveArrayInputAsync(
ctx: ExecutionContext,
items: any,
resolver: VariableResolver | null,
currentNodeId = ''
): Promise<any[]> {
if (typeof items !== 'string') {
if (items === null) {
return []
}
if (!Array.isArray(items) && typeof items !== 'object') {
if (!resolver) {
return []
}
try {
const resolved = (await resolver.resolveInputs(ctx, currentNodeId, { items })).items
return normalizeCollectionValue(ctx, resolved)
} catch (error) {
if (error instanceof Error && error.message.startsWith('Resolved items')) {
throw error
}
throw new Error(`Failed to resolve items: ${toError(error).message}`)
}
}
return normalizeCollectionValue(ctx, items)
}
if (items.startsWith(REFERENCE.START) && items.endsWith(REFERENCE.END) && resolver) {
try {
const resolved = await resolver.resolveSingleReference(ctx, currentNodeId, items, undefined, {
allowLargeValueRefs: true,
})
return normalizeCollectionValue(ctx, resolved)
} catch (error) {
if (error instanceof Error && error.message.startsWith('Reference "')) {
throw error
}
throw new Error(`Failed to resolve reference "${items}": ${toError(error).message}`)
}
}
try {
const normalized = items.replace(/'/g, '"')
const parsed = JSON.parse(normalized)
return normalizeCollectionValue(ctx, parsed)
} catch (error) {
if (error instanceof Error && error.message.startsWith('Parsed value')) {
throw error
}
throw new Error(`Failed to parse items as JSON: "${items}"`)
}
}