155 lines
6.7 KiB
JavaScript
155 lines
6.7 KiB
JavaScript
"use strict";
|
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
if (k2 === undefined) k2 = k;
|
|
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
}
|
|
Object.defineProperty(o, k2, desc);
|
|
}) : (function(o, m, k, k2) {
|
|
if (k2 === undefined) k2 = k;
|
|
o[k2] = m[k];
|
|
}));
|
|
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
}) : function(o, v) {
|
|
o["default"] = v;
|
|
});
|
|
var __importStar = (this && this.__importStar) || function (mod) {
|
|
if (mod && mod.__esModule) return mod;
|
|
var result = {};
|
|
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
__setModuleDefault(result, mod);
|
|
return result;
|
|
};
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.historyFromJSON = historyFromJSON;
|
|
exports.historyToJSON = historyToJSON;
|
|
exports.fixBuffers = fixBuffers;
|
|
exports.payloadToJSON = payloadToJSON;
|
|
exports.JSONToPayload = JSONToPayload;
|
|
const proto3_json_serializer_1 = require("proto3-json-serializer");
|
|
const proto = __importStar(require("@temporalio/proto"));
|
|
const patch_protobuf_root_1 = require("@temporalio/proto/lib/patch-protobuf-root");
|
|
// Cast to any because the generated proto module types are missing the lookupType method
|
|
const patched = (0, patch_protobuf_root_1.patchProtobufRoot)(proto);
|
|
const historyType = patched.lookupType('temporal.api.history.v1.History');
|
|
const payloadType = patched.lookupType('temporal.api.common.v1.Payload');
|
|
/**
|
|
* Convert a proto JSON representation of History to a valid History object
|
|
*/
|
|
function historyFromJSON(history) {
|
|
function pascalCaseToConstantCase(s) {
|
|
return s.replace(/[^\b][A-Z]/g, (m) => `${m[0]}_${m[1]}`).toUpperCase();
|
|
}
|
|
function fixEnumValue(obj, attr, prefix) {
|
|
return (obj[attr] && {
|
|
[attr]: obj[attr].startsWith(prefix) ? obj[attr] : `${prefix}_${pascalCaseToConstantCase(obj[attr])}`,
|
|
});
|
|
}
|
|
// fromProto3JSON doesn't allow null values on 'bytes' fields. This turns out to be a problem for payloads.
|
|
// Recursively descend on objects and array, and fix in-place any payload that has a null data field
|
|
function fixPayloads(e) {
|
|
function isPayload(p) {
|
|
return p && typeof p === 'object' && 'metadata' in p && 'data' in p;
|
|
}
|
|
if (e && typeof e === 'object') {
|
|
if (isPayload(e)) {
|
|
if (e.data === null) {
|
|
const { data: _data, ...rest } = e;
|
|
return rest;
|
|
}
|
|
return e;
|
|
}
|
|
if (Array.isArray(e))
|
|
return e.map(fixPayloads);
|
|
return Object.fromEntries(Object.entries(e).map(([k, v]) => [k, fixPayloads(v)]));
|
|
}
|
|
return e;
|
|
}
|
|
function fixHistoryEvent(e) {
|
|
const type = Object.keys(e).find((k) => k.endsWith('EventAttributes'));
|
|
if (!type) {
|
|
throw new TypeError(`Missing attributes in history event: ${JSON.stringify(e)}`);
|
|
}
|
|
// Fix payloads with null data
|
|
e = fixPayloads(e);
|
|
return {
|
|
...e,
|
|
...fixEnumValue(e, 'eventType', 'EVENT_TYPE'),
|
|
[type]: {
|
|
...e[type],
|
|
...(e[type].taskQueue && {
|
|
taskQueue: { ...e[type].taskQueue, ...fixEnumValue(e[type].taskQueue, 'kind', 'TASK_QUEUE_KIND') },
|
|
}),
|
|
...fixEnumValue(e[type], 'parentClosePolicy', 'PARENT_CLOSE_POLICY'),
|
|
...fixEnumValue(e[type], 'workflowIdReusePolicy', 'WORKFLOW_ID_REUSE_POLICY'),
|
|
...fixEnumValue(e[type], 'initiator', 'CONTINUE_AS_NEW_INITIATOR'),
|
|
...fixEnumValue(e[type], 'retryState', 'RETRY_STATE'),
|
|
...(e[type].childWorkflowExecutionFailureInfo && {
|
|
childWorkflowExecutionFailureInfo: {
|
|
...e[type].childWorkflowExecutionFailureInfo,
|
|
...fixEnumValue(e[type].childWorkflowExecutionFailureInfo, 'retryState', 'RETRY_STATE'),
|
|
},
|
|
}),
|
|
},
|
|
};
|
|
}
|
|
function fixHistory(h) {
|
|
return {
|
|
events: h.events.map(fixHistoryEvent),
|
|
};
|
|
}
|
|
if (typeof history !== 'object' || history == null || !Array.isArray(history.events)) {
|
|
throw new TypeError('Invalid history, expected an object with an array of events');
|
|
}
|
|
const loaded = (0, proto3_json_serializer_1.fromProto3JSON)(historyType, fixHistory(history));
|
|
if (loaded === null) {
|
|
throw new TypeError('Invalid history');
|
|
}
|
|
return loaded;
|
|
}
|
|
/**
|
|
* Convert an History object, e.g. as returned by `WorkflowClient.list().withHistory()`, to a JSON
|
|
* string that adheres to the same norm as JSON history files produced by other Temporal tools.
|
|
*/
|
|
function historyToJSON(history) {
|
|
const protoJson = (0, proto3_json_serializer_1.toProto3JSON)(proto.temporal.api.history.v1.History.fromObject(history));
|
|
return JSON.stringify(fixBuffers(protoJson), null, 2);
|
|
}
|
|
/**
|
|
* toProto3JSON doesn't correctly handle some of our "bytes" fields, passing them untouched to the
|
|
* output, after which JSON.stringify() would convert them to an array of numbers. As a workaround,
|
|
* recursively walk the object and convert all Buffer instances to base64 strings. Note this only
|
|
* works on proto3-json-serializer v2.0.0. v2.0.2 throws an error before we even get the chance
|
|
* to fix the buffers. See https://github.com/googleapis/proto3-json-serializer-nodejs/issues/103.
|
|
*/
|
|
function fixBuffers(e) {
|
|
if (e && typeof e === 'object') {
|
|
if (e instanceof Buffer)
|
|
return e.toString('base64');
|
|
if (e instanceof Uint8Array)
|
|
return Buffer.from(e).toString('base64');
|
|
if (Array.isArray(e))
|
|
return e.map(fixBuffers);
|
|
return Object.fromEntries(Object.entries(e).map(([k, v]) => [k, fixBuffers(v)]));
|
|
}
|
|
return e;
|
|
}
|
|
/**
|
|
* Convert from protobuf payload to JSON
|
|
*/
|
|
function payloadToJSON(payload) {
|
|
return fixBuffers((0, proto3_json_serializer_1.toProto3JSON)(patched.temporal.api.common.v1.Payload.create(payload)));
|
|
}
|
|
/**
|
|
* Convert from JSON to protobuf payload
|
|
*/
|
|
function JSONToPayload(json) {
|
|
const loaded = (0, proto3_json_serializer_1.fromProto3JSON)(payloadType, json);
|
|
if (loaded === null) {
|
|
throw new TypeError('Invalid payload');
|
|
}
|
|
return loaded;
|
|
}
|
|
//# sourceMappingURL=proto-utils.js.map
|