@mastra/temporal 0.4.19 → 0.5.0-alpha.0
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/dist/index.cjs +4 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +4 -2
- package/dist/index.js.map +1 -1
- package/dist/plugin.d.ts.map +1 -1
- package/dist/run.d.ts.map +1 -1
- package/dist/temporal-workflow-runtime.mjs +3 -0
- package/dist/transforms/activities.d.ts.map +1 -1
- package/dist/transforms/temporal-workflow-runtime.d.mts +2 -0
- package/dist/transforms/temporal-workflow-runtime.d.mts.map +1 -1
- package/dist/transforms/workflows.d.ts.map +1 -1
- package/dist/worker.cjs +93 -26
- package/dist/worker.cjs.map +1 -1
- package/dist/worker.js +93 -26
- package/dist/worker.js.map +1 -1
- package/package.json +4 -4
package/dist/worker.js
CHANGED
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
import { t as toWorkflowType } from "./utils-R6cB86BM.js";
|
|
2
2
|
import { builtinModules } from "module";
|
|
3
|
+
import { validateStepInput, validateStepRequestContext } from "@mastra/core/workflows";
|
|
3
4
|
import { readFileSync } from "fs";
|
|
4
5
|
import { writeFile } from "fs/promises";
|
|
5
6
|
import path, { basename, join } from "path";
|
|
6
7
|
import { fileURLToPath, pathToFileURL } from "url";
|
|
8
|
+
import { RequestContext } from "@mastra/core/di";
|
|
9
|
+
import { MastraError } from "@mastra/core/error";
|
|
10
|
+
import { toStandardSchema } from "@mastra/core/schema";
|
|
11
|
+
import { ApplicationFailure } from "@temporalio/activity";
|
|
7
12
|
import { generate } from "@babel/generator";
|
|
8
13
|
import { parse } from "@babel/parser";
|
|
9
14
|
import * as t from "@babel/types";
|
|
@@ -407,26 +412,18 @@ function createTemporalActivitiesHelperStatements(mastraImportPath, hasMastraBin
|
|
|
407
412
|
};
|
|
408
413
|
}
|
|
409
414
|
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
}
|
|
423
|
-
` : `
|
|
424
|
-
function createStep(args) {
|
|
425
|
-
return async (params) => {
|
|
426
|
-
return args.execute(withRequestContext(params));
|
|
427
|
-
};
|
|
428
|
-
}
|
|
429
|
-
`}
|
|
415
|
+
function createStep(args) {
|
|
416
|
+
return {
|
|
417
|
+
inputSchema: args.inputSchema,
|
|
418
|
+
requestContextSchema: args.requestContextSchema,
|
|
419
|
+
execute: async (params) => {
|
|
420
|
+
${mastraImportPath ? `
|
|
421
|
+
const { mastra } = await import(${JSON.stringify(mastraImportPath)});
|
|
422
|
+
return args.execute({ ...withRequestContext(params), mastra });
|
|
423
|
+
` : hasMastraBinding ? "return args.execute({ ...withRequestContext(params), mastra });" : "return args.execute(withRequestContext(params));"}
|
|
424
|
+
},
|
|
425
|
+
};
|
|
426
|
+
}
|
|
430
427
|
`;
|
|
431
428
|
return parse(helperSource, {
|
|
432
429
|
sourceType: "module",
|
|
@@ -669,6 +666,43 @@ function getWorkflowIdMetadata(workflowConfig, workflowName, filePath) {
|
|
|
669
666
|
}
|
|
670
667
|
throw new Error(`Unable to determine workflow id for ${workflowName} in ${filePath}`);
|
|
671
668
|
}
|
|
669
|
+
function getStaticKey(property) {
|
|
670
|
+
if (property.computed && t.isTemplateLiteral(property.key) && property.key.expressions.length === 0) return property.key.quasis[0]?.value.cooked ?? null;
|
|
671
|
+
if (property.computed && t.isStringLiteral(property.key)) return property.key.value;
|
|
672
|
+
return getObjectPropertyName(property);
|
|
673
|
+
}
|
|
674
|
+
function isDynamicKey(property) {
|
|
675
|
+
return property.computed && !t.isStringLiteral(property.key) && !(t.isTemplateLiteral(property.key) && property.key.expressions.length === 0);
|
|
676
|
+
}
|
|
677
|
+
function findStaticProperty(object, name) {
|
|
678
|
+
let found = { readable: true };
|
|
679
|
+
for (const property of object.properties) {
|
|
680
|
+
if (t.isSpreadElement(property) || isDynamicKey(property)) {
|
|
681
|
+
found = { readable: false };
|
|
682
|
+
continue;
|
|
683
|
+
}
|
|
684
|
+
if (getStaticKey(property) === name) found = t.isObjectProperty(property) ? {
|
|
685
|
+
readable: true,
|
|
686
|
+
value: property.value
|
|
687
|
+
} : { readable: false };
|
|
688
|
+
}
|
|
689
|
+
return found;
|
|
690
|
+
}
|
|
691
|
+
/**
|
|
692
|
+
* Read at build time so runs started outside `TemporalRun` (Schedules, the Temporal CLI) use the
|
|
693
|
+
* workflow's setting too. `TemporalRun` also sends the setting, which covers `options` the build
|
|
694
|
+
* cannot read.
|
|
695
|
+
*/
|
|
696
|
+
function getWorkflowValidateInputs(workflowConfig, workflowName, filePath) {
|
|
697
|
+
const options = findStaticProperty(workflowConfig, "options");
|
|
698
|
+
if (options.readable && !options.value) return;
|
|
699
|
+
if (options.readable && t.isObjectExpression(options.value)) {
|
|
700
|
+
const validateInputs = findStaticProperty(options.value, "validateInputs");
|
|
701
|
+
if (validateInputs.readable && !validateInputs.value) return;
|
|
702
|
+
if (validateInputs.readable && t.isBooleanLiteral(validateInputs.value)) return validateInputs.value.value;
|
|
703
|
+
}
|
|
704
|
+
console.warn(`[@mastra/temporal] Could not read options.validateInputs of ${workflowName} in ${filePath} at build time. Runs started with run.start() or run.startAsync() use the workflow setting. Runs started another way, such as from a Temporal Schedule, check step input.`);
|
|
705
|
+
}
|
|
672
706
|
/**
|
|
673
707
|
* The helper runtime lives in its own `.mjs` module so it can be linted and unit-tested
|
|
674
708
|
* like normal code. We parse that file directly here instead of using `Function#toString()`,
|
|
@@ -889,9 +923,11 @@ function getExportedName(node) {
|
|
|
889
923
|
* we emit a deterministic exported function whose name matches Temporal's runtime
|
|
890
924
|
* lookup and whose body delegates into the injected helper runtime.
|
|
891
925
|
*/
|
|
892
|
-
function createTemporalWorkflowStatements(exportName, workflowId, workflowIdValue, methods, filePath, includeCommit, stepBindings, workflowBindings, runtimeOptions) {
|
|
926
|
+
function createTemporalWorkflowStatements(exportName, workflowId, workflowIdValue, methods, filePath, includeCommit, stepBindings, workflowBindings, runtimeOptions, validateInputs) {
|
|
893
927
|
const createWorkflowArgs = [t.cloneNode(workflowId, true)];
|
|
894
|
-
|
|
928
|
+
const optionProperties = runtimeOptions ? runtimeOptions.properties.map((property) => t.cloneNode(property, true)) : [];
|
|
929
|
+
if (validateInputs !== void 0) optionProperties.push(t.objectProperty(t.identifier("validateInputs"), t.booleanLiteral(validateInputs)));
|
|
930
|
+
if (optionProperties.length > 0) createWorkflowArgs.push(t.objectExpression(optionProperties));
|
|
895
931
|
let expression = t.callExpression(t.identifier("createWorkflow"), createWorkflowArgs);
|
|
896
932
|
let mappingOrdinal = 0;
|
|
897
933
|
for (const method of methods) {
|
|
@@ -1026,7 +1062,7 @@ function rewriteWorkflowVariableDeclaration(statement, filePath, state) {
|
|
|
1026
1062
|
if (!workflowExport) throw new Error(`Unable to determine workflow export for ${declaration.id.name} in ${filePath}`);
|
|
1027
1063
|
const { exportName } = workflowExport;
|
|
1028
1064
|
state.workflowExports.push(workflowExport);
|
|
1029
|
-
state.statements.push(...createTemporalWorkflowStatements(exportName, workflowId, workflowIdValue, workflowChain.methods, filePath, state.committedWorkflowNames.has(declaration.id.name), state.stepBindings, state.workflowBindings, state.runtimeOptions));
|
|
1065
|
+
state.statements.push(...createTemporalWorkflowStatements(exportName, workflowId, workflowIdValue, workflowChain.methods, filePath, state.committedWorkflowNames.has(declaration.id.name), state.stepBindings, state.workflowBindings, state.runtimeOptions, getWorkflowValidateInputs(workflowConfig, declaration.id.name, filePath)));
|
|
1030
1066
|
}
|
|
1031
1067
|
if (declarations.length > 0) {
|
|
1032
1068
|
const cloned = declarations.map((declaration) => t.cloneNode(declaration, true));
|
|
@@ -1120,6 +1156,36 @@ function getGeneratedActivitiesModulePath(outputDir) {
|
|
|
1120
1156
|
function getActivityBindingsPath(outputDir) {
|
|
1121
1157
|
return path.join(outputDir, ACTIVITY_BINDINGS_FILE_NAME);
|
|
1122
1158
|
}
|
|
1159
|
+
/**
|
|
1160
|
+
* Activities queued by a Workflow built before `validateInputs` existed carry no flag and run
|
|
1161
|
+
* unchecked. A mismatch is non-retryable because a retry gets the same input.
|
|
1162
|
+
*/
|
|
1163
|
+
async function checkStepParams(stepId, { inputSchema, requestContextSchema }, { validateInputs, ...params }) {
|
|
1164
|
+
if (validateInputs !== true) return params;
|
|
1165
|
+
const [input, requestContext] = await Promise.all([validateStepInput({
|
|
1166
|
+
prevOutput: params.inputData,
|
|
1167
|
+
step: { inputSchema: inputSchema && toStandardSchema(inputSchema) },
|
|
1168
|
+
validateInputs: true
|
|
1169
|
+
}), validateStepRequestContext({
|
|
1170
|
+
requestContext: new RequestContext(Object.entries(params.requestContext ?? {})),
|
|
1171
|
+
step: {
|
|
1172
|
+
id: stepId,
|
|
1173
|
+
requestContextSchema: requestContextSchema && toStandardSchema(requestContextSchema)
|
|
1174
|
+
},
|
|
1175
|
+
validateInputs: true
|
|
1176
|
+
})]);
|
|
1177
|
+
const error = input.validationError ?? requestContext.validationError;
|
|
1178
|
+
if (error) throw ApplicationFailure.create({
|
|
1179
|
+
type: error instanceof MastraError ? error.id : error.name,
|
|
1180
|
+
message: error.message,
|
|
1181
|
+
nonRetryable: true,
|
|
1182
|
+
cause: error
|
|
1183
|
+
});
|
|
1184
|
+
return {
|
|
1185
|
+
...params,
|
|
1186
|
+
inputData: input.inputData
|
|
1187
|
+
};
|
|
1188
|
+
}
|
|
1123
1189
|
var MastraPlugin = class {
|
|
1124
1190
|
entryFile;
|
|
1125
1191
|
projectRoot;
|
|
@@ -1175,10 +1241,11 @@ var MastraPlugin = class {
|
|
|
1175
1241
|
const generatedActivities = {};
|
|
1176
1242
|
for (const binding of activityBindings) {
|
|
1177
1243
|
if (generatedActivities[binding.stepId]) continue;
|
|
1178
|
-
generatedActivities[binding.stepId] = async (
|
|
1244
|
+
generatedActivities[binding.stepId] = async (params) => {
|
|
1179
1245
|
const activity = (await this.#loadCompiledActivitiesModule(compiledActivitiesPath))[binding.exportName];
|
|
1180
|
-
if (typeof activity
|
|
1181
|
-
|
|
1246
|
+
if (typeof activity === "function") return activity(params);
|
|
1247
|
+
if (typeof activity?.execute !== "function") throw new Error(`Unable to load activity '${binding.exportName}' from ${compiledActivitiesPath}`);
|
|
1248
|
+
return activity.execute(await checkStepParams(binding.stepId, activity, params));
|
|
1182
1249
|
};
|
|
1183
1250
|
}
|
|
1184
1251
|
return generatedActivities;
|