@openfn/cli 1.3.0 → 1.3.2

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.
@@ -909,6 +909,56 @@ var fuzzy_match_step_default = (plan, stepPattern) => {
909
909
  }
910
910
  };
911
911
 
912
+ // src/util/validate-plan.ts
913
+ var assertWorkflowStructure = (plan, logger) => {
914
+ const { workflow, options } = plan;
915
+ if (!workflow || typeof workflow !== "object") {
916
+ throw new Error(`Missing or invalid "workflow" key in execution plan`);
917
+ }
918
+ if (!Array.isArray(workflow.steps)) {
919
+ throw new Error("The workflow.steps key must be an array");
920
+ }
921
+ if (workflow.steps.length === 0) {
922
+ logger.warn("The workflow.steps array is empty");
923
+ }
924
+ workflow.steps.forEach((step, index) => {
925
+ assertStepStructure(step, index);
926
+ });
927
+ assertOptionsStructure(options, logger);
928
+ };
929
+ var assertStepStructure = (step, index) => {
930
+ const allowedKeys = [
931
+ "id",
932
+ "name",
933
+ "next",
934
+ "previous",
935
+ "adaptor",
936
+ "expression",
937
+ "state",
938
+ "configuration",
939
+ "linker"
940
+ ];
941
+ for (const key in step) {
942
+ if (!allowedKeys.includes(key)) {
943
+ throw new Error(`Invalid key "${key}" in step ${step.id || index}`);
944
+ }
945
+ }
946
+ if ("adaptor" in step && !("expression" in step)) {
947
+ throw new Error(
948
+ `Step ${step.id ?? index} with an adaptor must also have an expression`
949
+ );
950
+ }
951
+ };
952
+ var assertOptionsStructure = (options = {}, logger) => {
953
+ const allowedKeys = ["timeout", "stepTimeout", "start", "end", "sanitize"];
954
+ for (const key in options) {
955
+ if (!allowedKeys.includes(key)) {
956
+ logger.warn(`Unrecognized option "${key}" in options object`);
957
+ }
958
+ }
959
+ };
960
+ var validate_plan_default = assertWorkflowStructure;
961
+
912
962
  // src/execute/handler.ts
913
963
  var matchStep = (plan, stepPattern, stepName, logger) => {
914
964
  try {
@@ -934,6 +984,7 @@ var executeHandler = async (options, logger) => {
934
984
  assert_path_default(options.path);
935
985
  await validate_adaptors_default(options, logger);
936
986
  let plan = await load_plan_default(options, logger);
987
+ validate_plan_default(plan, logger);
937
988
  if (options.cacheSteps) {
938
989
  await clearCache(plan, options, logger);
939
990
  }
@@ -1086,7 +1137,12 @@ var testHandler = async (options, logger) => {
1086
1137
  }
1087
1138
  const state = await load_state_default(plan, opts, createNullLogger());
1088
1139
  const compiledPlan = await compile_default(plan, opts, logger);
1089
- const result = await execute_default(compiledPlan, state, opts, logger);
1140
+ const result = await execute_default(
1141
+ compiledPlan,
1142
+ state,
1143
+ opts,
1144
+ logger
1145
+ );
1090
1146
  logger.success(`Result: ${result.data.answer}`);
1091
1147
  return result;
1092
1148
  };
@@ -1245,7 +1301,9 @@ import { readFile as readFile3 } from "node:fs/promises";
1245
1301
  import c from "chalk";
1246
1302
  import { getNameAndVersion as getNameAndVersion4, getLatestVersion } from "@openfn/runtime";
1247
1303
  var describeFn = (adaptorName, fn) => [
1248
- c.green(`## ${fn.name}(${fn.parameters.map(({ name }) => name).join(",")})`),
1304
+ c.green(
1305
+ `## ${fn.name}(${fn.parameters.map(({ name }) => name).join(",")})`
1306
+ ),
1249
1307
  `${fn.description}`,
1250
1308
  c.green("### Usage Examples"),
1251
1309
  fn.examples.length ? fn.examples.map(({ code, caption }) => {
@@ -1264,7 +1322,9 @@ ${code}`;
1264
1322
  ].join("\n\n");
1265
1323
  var describeLib = (adaptorName, data) => c.green(`## ${adaptorName} ${data.version}`) + `
1266
1324
 
1267
- ${data.functions.map((fn) => ` ${c.yellow(fn.name)} (${fn.parameters.map((p) => p.name).join(", ")})`).sort().join("\n")}
1325
+ ${data.functions.map(
1326
+ (fn) => ` ${c.yellow(fn.name)} (${fn.parameters.map((p) => p.name).join(", ")})`
1327
+ ).sort().join("\n")}
1268
1328
  `;
1269
1329
  var docsHandler = async (options, logger) => {
1270
1330
  const { adaptor, operation, repoDir } = options;
@@ -1457,7 +1517,9 @@ async function pullHandler(options, logger) {
1457
1517
  try {
1458
1518
  assert_path_default(options.projectId);
1459
1519
  const config = mergeOverrides2(await getConfig2(options.configPath), options);
1460
- logger.always("Downloading existing project state (as JSON) from the server.");
1520
+ logger.always(
1521
+ "Downloading existing project state (as JSON) from the server."
1522
+ );
1461
1523
  const { data: project } = await getProject(config, options.projectId);
1462
1524
  if (!project) {
1463
1525
  logger.error("ERROR: Project not found.");
@@ -1472,9 +1534,7 @@ async function pullHandler(options, logger) {
1472
1534
  path7.resolve(config.statePath),
1473
1535
  JSON.stringify(state, null, 2)
1474
1536
  );
1475
- logger.always(
1476
- "Downloading the project spec (as YAML) from the server."
1477
- );
1537
+ logger.always("Downloading the project spec (as YAML) from the server.");
1478
1538
  const url2 = new URL(
1479
1539
  `api/provision/yaml?id=${options.projectId}`,
1480
1540
  config.endpoint
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openfn/cli",
3
- "version": "1.3.0",
3
+ "version": "1.3.2",
4
4
  "description": "CLI devtools for the openfn toolchain.",
5
5
  "engines": {
6
6
  "node": ">=18",
@@ -47,11 +47,11 @@
47
47
  "treeify": "^1.1.0",
48
48
  "ws": "^8.14.1",
49
49
  "yargs": "^17.7.2",
50
- "@openfn/describe-package": "0.0.19",
51
50
  "@openfn/compiler": "0.1.2",
52
- "@openfn/logger": "1.0.1",
53
51
  "@openfn/deploy": "0.4.6",
54
- "@openfn/runtime": "1.1.3"
52
+ "@openfn/logger": "1.0.1",
53
+ "@openfn/describe-package": "0.0.19",
54
+ "@openfn/runtime": "1.2.0"
55
55
  },
56
56
  "files": [
57
57
  "dist",