diff --git a/packages/common/src/converter/payload-converter.ts b/packages/common/src/converter/payload-converter.ts index fbea9cb81..ecbb5b23a 100644 --- a/packages/common/src/converter/payload-converter.ts +++ b/packages/common/src/converter/payload-converter.ts @@ -126,6 +126,10 @@ export class RawValue { this._payload = payloadConverter.toPayload(value); } + static fromPayload(p: Payload): RawValue { + return new RawValue(p, identityPayloadConverter); + } + get payload(): Payload { return this._payload; } @@ -312,3 +316,18 @@ export class DefaultPayloadConverter extends CompositePayloadConverter { * `const myConverter = new DefaultPayloadConverter({ protobufRoot })` */ export const defaultPayloadConverter = new DefaultPayloadConverter(); + +/** + * The identity payload converter returns the inputs it was given. + */ +class IdentityPayloadConverter implements PayloadConverter { + toPayload(value: T): Payload { + return value as Payload; + } + + fromPayload(payload: Payload): T { + return payload as T; + } +} + +const identityPayloadConverter = new IdentityPayloadConverter(); diff --git a/packages/test/src/test-integration-workflows.ts b/packages/test/src/test-integration-workflows.ts index 56722cfd7..1a4c8e0c8 100644 --- a/packages/test/src/test-integration-workflows.ts +++ b/packages/test/src/test-integration-workflows.ts @@ -25,6 +25,8 @@ import { ActivityCancellationType, ApplicationFailure, defineSearchAttributeKey, + encodingKeys, + METADATA_ENCODING_KEY, RawValue, SearchAttributePair, SearchAttributeType, @@ -36,6 +38,7 @@ import { STACK_TRACE_QUERY_NAME, ENHANCED_STACK_TRACE_QUERY_NAME, } from '@temporalio/common/lib/reserved'; +import { encode } from '@temporalio/common/lib/encoding'; import { signalSchedulingWorkflow } from './activities/helpers'; import { activityStartedSignal } from './workflows/definitions'; import * as workflows from './workflows'; @@ -1318,17 +1321,29 @@ test.serial('can register search attributes to dev server', async (t) => { await env.teardown(); }); -export async function rawValueWorkflow(value: unknown): Promise { +export async function rawValueWorkflow(value: unknown, isPayload: boolean = false): Promise { const { rawValueActivity } = workflow.proxyActivities({ startToCloseTimeout: '10s' }); - return await rawValueActivity(new RawValue(value)); + const rv = isPayload + ? RawValue.fromPayload({ + metadata: { [METADATA_ENCODING_KEY]: encodingKeys.METADATA_ENCODING_RAW }, + data: value as Uint8Array, + }) + : new RawValue(value); + return await rawValueActivity(rv, isPayload); } test('workflow and activity can receive/return RawValue', async (t) => { const { executeWorkflow, createWorker } = helpers(t); const worker = await createWorker({ activities: { - async rawValueActivity(value: unknown): Promise { - return new RawValue(value); + async rawValueActivity(value: unknown, isPayload: boolean = false): Promise { + const rv = isPayload + ? RawValue.fromPayload({ + metadata: { [METADATA_ENCODING_KEY]: encodingKeys.METADATA_ENCODING_RAW }, + data: value as Uint8Array, + }) + : new RawValue(value); + return rv; }, }, }); @@ -1336,10 +1351,18 @@ test('workflow and activity can receive/return RawValue', async (t) => { await worker.runUntil(async () => { const testValue = 'test'; const rawValue = new RawValue(testValue); + const rawValuePayload = RawValue.fromPayload({ + metadata: { [METADATA_ENCODING_KEY]: encodingKeys.METADATA_ENCODING_RAW }, + data: encode(testValue), + }); const res = await executeWorkflow(rawValueWorkflow, { args: [rawValue], }); t.deepEqual(res, testValue); + const res2 = await executeWorkflow(rawValueWorkflow, { + args: [rawValuePayload, true], + }); + t.deepEqual(res2, encode(testValue)); }); });