@temporalio/common 0.22.0 → 1.0.0-rc.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 +3 -3
- package/lib/converter/data-converter.d.ts +10 -6
- package/lib/converter/data-converter.js +3 -4
- package/lib/converter/data-converter.js.map +1 -1
- package/lib/converter/json-payload-converter.d.ts +10 -0
- package/lib/converter/json-payload-converter.js +39 -0
- package/lib/converter/json-payload-converter.js.map +1 -0
- package/lib/converter/payload-codec.d.ts +0 -7
- package/lib/converter/payload-codec.js +0 -8
- package/lib/converter/payload-codec.js.map +1 -1
- package/lib/converter/payload-converter.d.ts +13 -44
- package/lib/converter/payload-converter.js +8 -85
- package/lib/converter/payload-converter.js.map +1 -1
- package/lib/converter/payload-converters.d.ts +47 -11
- package/lib/converter/payload-converters.js +75 -36
- package/lib/converter/payload-converters.js.map +1 -1
- package/lib/converter/protobuf-payload-converters.d.ts +1 -2
- package/lib/converter/protobuf-payload-converters.js +7 -5
- package/lib/converter/protobuf-payload-converters.js.map +1 -1
- package/lib/converter/search-attribute-payload-converter.d.ts +12 -0
- package/lib/converter/search-attribute-payload-converter.js +64 -0
- package/lib/converter/search-attribute-payload-converter.js.map +1 -0
- package/lib/converter/types.d.ts +1 -2
- package/lib/converter/types.js.map +1 -1
- package/lib/failure.d.ts +52 -40
- package/lib/failure.js +85 -56
- package/lib/failure.js.map +1 -1
- package/lib/index.d.ts +1 -0
- package/lib/index.js +1 -0
- package/lib/index.js.map +1 -1
- package/lib/otel.d.ts +26 -0
- package/lib/otel.js +87 -0
- package/lib/otel.js.map +1 -0
- package/lib/proto-utils.d.ts +28 -0
- package/lib/proto-utils.js +85 -0
- package/lib/proto-utils.js.map +1 -0
- package/lib/protobufs.d.ts +2 -2
- package/lib/protobufs.js +4 -2
- package/lib/protobufs.js.map +1 -1
- package/package.json +11 -8
- package/src/converter/data-converter.ts +14 -9
- package/src/converter/json-payload-converter.ts +37 -0
- package/src/converter/payload-codec.ts +0 -8
- package/src/converter/payload-converter.ts +17 -99
- package/src/converter/payload-converters.ts +99 -40
- package/src/converter/protobuf-payload-converters.ts +8 -4
- package/src/converter/search-attribute-payload-converter.ts +71 -0
- package/src/converter/types.ts +1 -2
- package/src/failure.ts +87 -56
- package/src/index.ts +1 -0
- package/src/otel.ts +63 -0
- package/src/proto-utils.ts +103 -0
- package/src/protobufs.ts +2 -2
- package/lib/converter/patch-protobuf-root.d.ts +0 -1
- package/lib/converter/patch-protobuf-root.js +0 -6
- package/lib/converter/patch-protobuf-root.js.map +0 -1
- package/src/converter/patch-protobuf-root.ts +0 -1
- package/tsconfig.json +0 -9
- package/tsconfig.tsbuildinfo +0 -1
|
@@ -1,24 +1,22 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
BinaryPayloadConverter,
|
|
4
|
-
JsonPayloadConverter,
|
|
5
|
-
PayloadConverterWithEncoding,
|
|
6
|
-
UndefinedPayloadConverter,
|
|
7
|
-
} from './payload-converters';
|
|
8
|
-
import { METADATA_ENCODING_KEY, Payload, str } from './types';
|
|
1
|
+
import { Payload } from './types';
|
|
9
2
|
|
|
10
3
|
/**
|
|
11
|
-
* Used by the framework to serialize/deserialize parameters and return values.
|
|
4
|
+
* Used by the framework to serialize/deserialize data like parameters and return values.
|
|
12
5
|
*
|
|
13
|
-
* This is called inside the
|
|
6
|
+
* This is called inside the {@link https://docs.temporal.io/typescript/determinism | Workflow isolate}.
|
|
14
7
|
* To write async code or use Node APIs (or use packages that use Node APIs), use a {@link PayloadCodec}.
|
|
15
8
|
*/
|
|
16
9
|
export interface PayloadConverter {
|
|
17
10
|
/**
|
|
18
11
|
* Converts a value to a {@link Payload}.
|
|
19
|
-
*
|
|
12
|
+
*
|
|
13
|
+
* @param value The value to convert. Example values include the Workflow args sent from the Client and the values returned by a Workflow or Activity.
|
|
14
|
+
*
|
|
15
|
+
* @returns The {@link Payload}.
|
|
16
|
+
*
|
|
17
|
+
* Should throw {@link ValueError} if unable to convert.
|
|
20
18
|
*/
|
|
21
|
-
toPayload<T>(value: T): Payload
|
|
19
|
+
toPayload<T>(value: T): Payload;
|
|
22
20
|
|
|
23
21
|
/**
|
|
24
22
|
* Converts a {@link Payload} back to a value.
|
|
@@ -26,69 +24,13 @@ export interface PayloadConverter {
|
|
|
26
24
|
fromPayload<T>(payload: Payload): T;
|
|
27
25
|
}
|
|
28
26
|
|
|
29
|
-
export class CompositePayloadConverter implements PayloadConverter {
|
|
30
|
-
readonly converters: PayloadConverterWithEncoding[];
|
|
31
|
-
readonly converterByEncoding: Map<string, PayloadConverterWithEncoding> = new Map();
|
|
32
|
-
|
|
33
|
-
constructor(...converters: PayloadConverterWithEncoding[]) {
|
|
34
|
-
this.converters = converters;
|
|
35
|
-
for (const converter of converters) {
|
|
36
|
-
this.converterByEncoding.set(converter.encodingType, converter);
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
/**
|
|
41
|
-
* Tries to run `.toPayload(value)` on each converter in the order provided at construction.
|
|
42
|
-
* Returns the first successful result, or `undefined` if there is no converter that can handle the value.
|
|
43
|
-
*
|
|
44
|
-
* @throws UnsupportedJsonTypeError
|
|
45
|
-
*/
|
|
46
|
-
public toPayload<T>(value: T): Payload | undefined {
|
|
47
|
-
for (const converter of this.converters) {
|
|
48
|
-
const result = converter.toPayload(value);
|
|
49
|
-
if (result !== undefined) {
|
|
50
|
-
return result;
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
return undefined;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
/**
|
|
57
|
-
* Run {@link PayloadConverterWithEncoding.fromPayload} based on the {@link encodingTypes | encoding type} of the {@link Payload}.
|
|
58
|
-
*/
|
|
59
|
-
public fromPayload<T>(payload: Payload): T {
|
|
60
|
-
if (payload.metadata === undefined || payload.metadata === null) {
|
|
61
|
-
throw new ValueError('Missing payload metadata');
|
|
62
|
-
}
|
|
63
|
-
const encoding = str(payload.metadata[METADATA_ENCODING_KEY]);
|
|
64
|
-
const converter = this.converterByEncoding.get(encoding);
|
|
65
|
-
if (converter === undefined) {
|
|
66
|
-
throw new ValueError(`Unknown encoding: ${encoding}`);
|
|
67
|
-
}
|
|
68
|
-
return converter.fromPayload(payload);
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
/**
|
|
73
|
-
* Tries to convert `value` to a {@link Payload}. Throws if conversion fails.
|
|
74
|
-
*
|
|
75
|
-
* @throws {@link PayloadConverterError}
|
|
76
|
-
*/
|
|
77
|
-
export function toPayload(converter: PayloadConverter, value: unknown): Payload {
|
|
78
|
-
const payload = converter.toPayload(value);
|
|
79
|
-
if (payload === undefined) {
|
|
80
|
-
throw new PayloadConverterError(`Failed to convert value: ${value}`);
|
|
81
|
-
}
|
|
82
|
-
return payload;
|
|
83
|
-
}
|
|
84
|
-
|
|
85
27
|
/**
|
|
86
28
|
* Implements conversion of a list of values.
|
|
87
29
|
*
|
|
88
30
|
* @param converter
|
|
89
31
|
* @param values JS values to convert to Payloads
|
|
90
|
-
* @return
|
|
91
|
-
* @throws
|
|
32
|
+
* @return list of {@link Payload}s
|
|
33
|
+
* @throws {@link ValueError} if conversion of the value passed as parameter failed for any
|
|
92
34
|
* reason.
|
|
93
35
|
*/
|
|
94
36
|
export function toPayloads(converter: PayloadConverter, ...values: unknown[]): Payload[] | undefined {
|
|
@@ -96,17 +38,17 @@ export function toPayloads(converter: PayloadConverter, ...values: unknown[]): P
|
|
|
96
38
|
return undefined;
|
|
97
39
|
}
|
|
98
40
|
|
|
99
|
-
return values.map((value) => toPayload(
|
|
41
|
+
return values.map((value) => converter.toPayload(value));
|
|
100
42
|
}
|
|
101
43
|
|
|
102
44
|
/**
|
|
103
45
|
* Run {@link PayloadConverter.toPayload} on each value in the map.
|
|
104
46
|
*
|
|
105
|
-
* @throws {@link
|
|
47
|
+
* @throws {@link ValueError} if conversion of any value in the map fails
|
|
106
48
|
*/
|
|
107
49
|
export function mapToPayloads<K extends string>(converter: PayloadConverter, map: Record<K, any>): Record<K, Payload> {
|
|
108
50
|
return Object.fromEntries(
|
|
109
|
-
Object.entries(map).map(([k, v]): [K, Payload] => [k as K, toPayload(
|
|
51
|
+
Object.entries(map).map(([k, v]): [K, Payload] => [k as K, converter.toPayload(v)])
|
|
110
52
|
) as Record<K, Payload>;
|
|
111
53
|
}
|
|
112
54
|
|
|
@@ -142,8 +84,8 @@ export function arrayFromPayloads(converter: PayloadConverter, payloads?: Payloa
|
|
|
142
84
|
export function mapFromPayloads<K extends string>(
|
|
143
85
|
converter: PayloadConverter,
|
|
144
86
|
map?: Record<K, Payload> | null | undefined
|
|
145
|
-
): Record<K, unknown> | undefined {
|
|
146
|
-
if (map
|
|
87
|
+
): Record<K, unknown> | undefined | null {
|
|
88
|
+
if (map == null) return map;
|
|
147
89
|
return Object.fromEntries(
|
|
148
90
|
Object.entries(map).map(([k, payload]): [K, unknown] => {
|
|
149
91
|
const value = converter.fromPayload(payload as Payload);
|
|
@@ -151,27 +93,3 @@ export function mapFromPayloads<K extends string>(
|
|
|
151
93
|
})
|
|
152
94
|
) as Record<K, unknown>;
|
|
153
95
|
}
|
|
154
|
-
|
|
155
|
-
export const searchAttributePayloadConverter = new JsonPayloadConverter();
|
|
156
|
-
|
|
157
|
-
export class DefaultPayloadConverter extends CompositePayloadConverter {
|
|
158
|
-
// Match the order used in other SDKs, but exclude Protobuf converters so that the code, including
|
|
159
|
-
// `proto3-json-serializer`, doesn't take space in Workflow bundles that don't use Protobufs. To use Protobufs, use
|
|
160
|
-
// {@link DefaultPayloadConverterWithProtobufs}.
|
|
161
|
-
//
|
|
162
|
-
// Go SDK:
|
|
163
|
-
// https://github.com/temporalio/sdk-go/blob/5e5645f0c550dcf717c095ae32c76a7087d2e985/converter/default_data_converter.go#L28
|
|
164
|
-
constructor() {
|
|
165
|
-
super(new UndefinedPayloadConverter(), new BinaryPayloadConverter(), new JsonPayloadConverter());
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
/**
|
|
170
|
-
* The default {@link PayloadConverter} used by the SDK.
|
|
171
|
-
* Supports `Uint8Array` and JSON serializables (so if [`JSON.stringify(yourArgOrRetval)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#description) works, the default payload converter will work).
|
|
172
|
-
*
|
|
173
|
-
* To also support Protobufs, create a custom payload converter with {@link DefaultPayloadConverter}:
|
|
174
|
-
*
|
|
175
|
-
* `const myConverter = new DefaultPayloadConverter({ protobufRoot })`
|
|
176
|
-
*/
|
|
177
|
-
export const defaultPayloadConverter = new DefaultPayloadConverter();
|
|
@@ -1,67 +1,98 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { PayloadConverterError, ValueError } from '@temporalio/internal-workflow-common';
|
|
2
|
+
import { JsonPayloadConverter } from './json-payload-converter';
|
|
2
3
|
import { PayloadConverter } from './payload-converter';
|
|
3
|
-
import {
|
|
4
|
+
import { SearchAttributePayloadConverter } from './search-attribute-payload-converter';
|
|
5
|
+
import { encodingKeys, encodingTypes, METADATA_ENCODING_KEY, Payload, str } from './types';
|
|
6
|
+
|
|
7
|
+
export interface PayloadConverterWithEncoding {
|
|
8
|
+
/**
|
|
9
|
+
* Converts a value to a {@link Payload}.
|
|
10
|
+
*
|
|
11
|
+
* @param value The value to convert. Example values include the Workflow args sent from the Client and the values returned by a Workflow or Activity.
|
|
12
|
+
* @returns The {@link Payload}, or `undefined` if unable to convert.
|
|
13
|
+
*/
|
|
14
|
+
toPayload<T>(value: T): Payload | undefined;
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Converts a {@link Payload} back to a value.
|
|
18
|
+
*/
|
|
19
|
+
fromPayload<T>(payload: Payload): T;
|
|
4
20
|
|
|
5
|
-
export interface PayloadConverterWithEncoding extends PayloadConverter {
|
|
6
21
|
readonly encodingType: string;
|
|
7
22
|
}
|
|
8
23
|
|
|
9
24
|
/**
|
|
10
|
-
*
|
|
25
|
+
* Tries to convert values to {@link Payload}s using the {@link PayloadConverterWithEncoding}s provided to the constructor, in the order provided.
|
|
26
|
+
*
|
|
27
|
+
* Converts Payloads to values based on the `Payload.metadata.encoding` field, which matches the {@link PayloadConverterWithEncoding.encodingType}
|
|
28
|
+
* of the converter that created the Payload.
|
|
11
29
|
*/
|
|
12
|
-
export class
|
|
13
|
-
|
|
30
|
+
export class CompositePayloadConverter implements PayloadConverter {
|
|
31
|
+
readonly converters: PayloadConverterWithEncoding[];
|
|
32
|
+
readonly converterByEncoding: Map<string, PayloadConverterWithEncoding> = new Map();
|
|
14
33
|
|
|
15
|
-
|
|
16
|
-
if (
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
34
|
+
constructor(...converters: PayloadConverterWithEncoding[]) {
|
|
35
|
+
if (converters.length === 0) {
|
|
36
|
+
throw new PayloadConverterError('Must provide at least one PayloadConverterWithEncoding');
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
this.converters = converters;
|
|
40
|
+
for (const converter of converters) {
|
|
41
|
+
this.converterByEncoding.set(converter.encodingType, converter);
|
|
42
|
+
}
|
|
22
43
|
}
|
|
23
44
|
|
|
24
|
-
|
|
25
|
-
|
|
45
|
+
/**
|
|
46
|
+
* Tries to run `.toPayload(value)` on each converter in the order provided at construction.
|
|
47
|
+
* Returns the first successful result, throws {@link ValueError} if there is no converter that can handle the value.
|
|
48
|
+
*/
|
|
49
|
+
public toPayload<T>(value: T): Payload {
|
|
50
|
+
for (const converter of this.converters) {
|
|
51
|
+
const result = converter.toPayload(value);
|
|
52
|
+
if (result !== undefined) {
|
|
53
|
+
return result;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
throw new ValueError(`Unable to convert ${value} to payload`);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Run {@link PayloadConverterWithEncoding.fromPayload} based on the {@link encodingTypes | encoding type} of the {@link Payload}.
|
|
62
|
+
*/
|
|
63
|
+
public fromPayload<T>(payload: Payload): T {
|
|
64
|
+
if (payload.metadata === undefined || payload.metadata === null) {
|
|
65
|
+
throw new ValueError('Missing payload metadata');
|
|
66
|
+
}
|
|
67
|
+
const encoding = str(payload.metadata[METADATA_ENCODING_KEY]);
|
|
68
|
+
const converter = this.converterByEncoding.get(encoding);
|
|
69
|
+
if (converter === undefined) {
|
|
70
|
+
throw new ValueError(`Unknown encoding: ${encoding}`);
|
|
71
|
+
}
|
|
72
|
+
return converter.fromPayload(payload);
|
|
26
73
|
}
|
|
27
74
|
}
|
|
28
75
|
|
|
29
76
|
/**
|
|
30
|
-
* Converts between
|
|
31
|
-
*
|
|
32
|
-
* @throws UnsupportedJsonTypeError
|
|
77
|
+
* Converts between JS undefined and NULL Payload
|
|
33
78
|
*/
|
|
34
|
-
export class
|
|
35
|
-
public encodingType = encodingTypes.
|
|
79
|
+
export class UndefinedPayloadConverter implements PayloadConverterWithEncoding {
|
|
80
|
+
public encodingType = encodingTypes.METADATA_ENCODING_NULL;
|
|
36
81
|
|
|
37
82
|
public toPayload(value: unknown): Payload | undefined {
|
|
38
|
-
if (value
|
|
39
|
-
|
|
40
|
-
let json;
|
|
41
|
-
try {
|
|
42
|
-
json = JSON.stringify(value);
|
|
43
|
-
} catch (e) {
|
|
44
|
-
throw new UnsupportedJsonTypeError(
|
|
45
|
-
`Can't run JSON.stringify on this value: ${value}. Either convert it (or its properties) to JSON-serializable values (see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#description ), or use a custom data converter: https://docs.temporal.io/docs/typescript/data-converters . JSON.stringify error message: ${errorMessage(
|
|
46
|
-
e
|
|
47
|
-
)}`,
|
|
48
|
-
e as Error
|
|
49
|
-
);
|
|
83
|
+
if (value !== undefined) {
|
|
84
|
+
return undefined;
|
|
50
85
|
}
|
|
51
86
|
|
|
52
87
|
return {
|
|
53
88
|
metadata: {
|
|
54
|
-
[METADATA_ENCODING_KEY]: encodingKeys.
|
|
89
|
+
[METADATA_ENCODING_KEY]: encodingKeys.METADATA_ENCODING_NULL,
|
|
55
90
|
},
|
|
56
|
-
data: u8(json),
|
|
57
91
|
};
|
|
58
92
|
}
|
|
59
93
|
|
|
60
|
-
public fromPayload<T>(
|
|
61
|
-
|
|
62
|
-
throw new ValueError('Got payload with no data');
|
|
63
|
-
}
|
|
64
|
-
return JSON.parse(str(content.data));
|
|
94
|
+
public fromPayload<T>(_content: Payload): T {
|
|
95
|
+
return undefined as any; // Just return undefined
|
|
65
96
|
}
|
|
66
97
|
}
|
|
67
98
|
|
|
@@ -73,7 +104,10 @@ export class BinaryPayloadConverter implements PayloadConverterWithEncoding {
|
|
|
73
104
|
|
|
74
105
|
public toPayload(value: unknown): Payload | undefined {
|
|
75
106
|
// TODO: support any DataView or ArrayBuffer?
|
|
76
|
-
if (!(value instanceof Uint8Array))
|
|
107
|
+
if (!(value instanceof Uint8Array)) {
|
|
108
|
+
return undefined;
|
|
109
|
+
}
|
|
110
|
+
|
|
77
111
|
return {
|
|
78
112
|
metadata: {
|
|
79
113
|
[METADATA_ENCODING_KEY]: encodingKeys.METADATA_ENCODING_RAW,
|
|
@@ -87,3 +121,28 @@ export class BinaryPayloadConverter implements PayloadConverterWithEncoding {
|
|
|
87
121
|
return content.data as any;
|
|
88
122
|
}
|
|
89
123
|
}
|
|
124
|
+
|
|
125
|
+
export const searchAttributePayloadConverter = new SearchAttributePayloadConverter();
|
|
126
|
+
|
|
127
|
+
export class DefaultPayloadConverter extends CompositePayloadConverter {
|
|
128
|
+
// Match the order used in other SDKs, but exclude Protobuf converters so that the code, including
|
|
129
|
+
// `proto3-json-serializer`, doesn't take space in Workflow bundles that don't use Protobufs. To use Protobufs, use
|
|
130
|
+
// {@link DefaultPayloadConverterWithProtobufs}.
|
|
131
|
+
//
|
|
132
|
+
// Go SDK:
|
|
133
|
+
// https://github.com/temporalio/sdk-go/blob/5e5645f0c550dcf717c095ae32c76a7087d2e985/converter/default_data_converter.go#L28
|
|
134
|
+
constructor() {
|
|
135
|
+
super(new UndefinedPayloadConverter(), new BinaryPayloadConverter(), new JsonPayloadConverter());
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* The default {@link PayloadConverter} used by the SDK. Supports `Uint8Array` and JSON serializables (so if
|
|
141
|
+
* {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#description | `JSON.stringify(yourArgOrRetval)`}
|
|
142
|
+
* works, the default payload converter will work).
|
|
143
|
+
*
|
|
144
|
+
* To also support Protobufs, create a custom payload converter with {@link DefaultPayloadConverter}:
|
|
145
|
+
*
|
|
146
|
+
* `const myConverter = new DefaultPayloadConverter({ protobufRoot })`
|
|
147
|
+
*/
|
|
148
|
+
export const defaultPayloadConverter = new DefaultPayloadConverter();
|
|
@@ -8,10 +8,10 @@ import {
|
|
|
8
8
|
} from '@temporalio/internal-workflow-common';
|
|
9
9
|
import * as protoJsonSerializer from 'proto3-json-serializer';
|
|
10
10
|
import type { Message, Namespace, Root, Type } from 'protobufjs';
|
|
11
|
-
import {
|
|
11
|
+
import { JsonPayloadConverter } from './json-payload-converter';
|
|
12
12
|
import {
|
|
13
13
|
BinaryPayloadConverter,
|
|
14
|
-
|
|
14
|
+
CompositePayloadConverter,
|
|
15
15
|
PayloadConverterWithEncoding,
|
|
16
16
|
UndefinedPayloadConverter,
|
|
17
17
|
} from './payload-converters';
|
|
@@ -96,7 +96,9 @@ export class ProtobufBinaryPayloadConverter extends ProtobufPayloadConverter {
|
|
|
96
96
|
}
|
|
97
97
|
|
|
98
98
|
public toPayload(value: unknown): Payload | undefined {
|
|
99
|
-
if (!isProtobufMessage(value))
|
|
99
|
+
if (!isProtobufMessage(value)) {
|
|
100
|
+
return undefined;
|
|
101
|
+
}
|
|
100
102
|
|
|
101
103
|
return this.constructPayload({
|
|
102
104
|
messageTypeName: getNamespacedTypeName(value.$type),
|
|
@@ -124,7 +126,9 @@ export class ProtobufJsonPayloadConverter extends ProtobufPayloadConverter {
|
|
|
124
126
|
}
|
|
125
127
|
|
|
126
128
|
public toPayload(value: unknown): Payload | undefined {
|
|
127
|
-
if (!isProtobufMessage(value))
|
|
129
|
+
if (!isProtobufMessage(value)) {
|
|
130
|
+
return undefined;
|
|
131
|
+
}
|
|
128
132
|
|
|
129
133
|
const jsonValue = protoJsonSerializer.toProto3JSON(value);
|
|
130
134
|
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { IllegalStateError, ValueError } from '@temporalio/internal-workflow-common';
|
|
2
|
+
import { PayloadConverter } from './payload-converter';
|
|
3
|
+
import { JsonPayloadConverter } from './json-payload-converter';
|
|
4
|
+
import { Payload, str } from './types';
|
|
5
|
+
|
|
6
|
+
const jsonConverter = new JsonPayloadConverter();
|
|
7
|
+
const validNonDateTypes = ['string', 'number', 'boolean'];
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Converts Search Attribute values using JsonPayloadConverter
|
|
11
|
+
*/
|
|
12
|
+
export class SearchAttributePayloadConverter implements PayloadConverter {
|
|
13
|
+
public toPayload(values: unknown): Payload {
|
|
14
|
+
if (!(values instanceof Array)) {
|
|
15
|
+
throw new ValueError(`SearchAttribute value must be an array`);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
if (values.length > 0) {
|
|
19
|
+
const firstValue = values[0];
|
|
20
|
+
const firstType = typeof firstValue;
|
|
21
|
+
if (firstType === 'object') {
|
|
22
|
+
for (const idx in values) {
|
|
23
|
+
const value = values[idx];
|
|
24
|
+
if (!(value instanceof Date)) {
|
|
25
|
+
throw new ValueError(
|
|
26
|
+
`SearchAttribute values must arrays of strings, numbers, booleans, or Dates. The value ${value} at index ${idx} is of type ${typeof value}`
|
|
27
|
+
);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
} else {
|
|
31
|
+
if (!validNonDateTypes.includes(firstType)) {
|
|
32
|
+
throw new ValueError(`SearchAttribute array values must be: string | number | boolean | Date`);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
for (const idx in values) {
|
|
36
|
+
const value = values[idx];
|
|
37
|
+
if (typeof value !== firstType) {
|
|
38
|
+
throw new ValueError(
|
|
39
|
+
`All SearchAttribute array values must be of the same type. The first value ${firstValue} of type ${firstType} doesn't match value ${value} of type ${typeof value} at index ${idx}`
|
|
40
|
+
);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// JSON.stringify takes care of converting Dates to ISO strings
|
|
47
|
+
const ret = jsonConverter.toPayload(values);
|
|
48
|
+
if (ret === undefined) {
|
|
49
|
+
throw new IllegalStateError('Could not convert search attributes to payloads');
|
|
50
|
+
}
|
|
51
|
+
return ret;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Datetime Search Attribute values are converted to `Date`s
|
|
56
|
+
*/
|
|
57
|
+
public fromPayload<T>(payload: Payload): T {
|
|
58
|
+
if (payload.metadata === undefined || payload.metadata === null) {
|
|
59
|
+
throw new ValueError('Missing payload metadata');
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
const value = jsonConverter.fromPayload(payload);
|
|
63
|
+
let arrayWrappedValue = value instanceof Array ? value : [value];
|
|
64
|
+
|
|
65
|
+
const searchAttributeType = str(payload.metadata.type);
|
|
66
|
+
if (searchAttributeType === 'Datetime') {
|
|
67
|
+
arrayWrappedValue = arrayWrappedValue.map((dateString) => new Date(dateString));
|
|
68
|
+
}
|
|
69
|
+
return arrayWrappedValue as unknown as T;
|
|
70
|
+
}
|
|
71
|
+
}
|
package/src/converter/types.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import type { coresdk } from '@temporalio/proto';
|
|
2
1
|
import { TextDecoder, TextEncoder } from './encoding';
|
|
3
2
|
|
|
4
|
-
export
|
|
3
|
+
export { Payload } from '@temporalio/internal-workflow-common';
|
|
5
4
|
|
|
6
5
|
/**
|
|
7
6
|
* Transform an *ascii* string into a Uint8Array
|