@openfn/project 0.3.1 → 0.4.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/dist/index.d.ts CHANGED
@@ -97,10 +97,12 @@ declare class Project {
97
97
  declare class Workspace {
98
98
  private config?;
99
99
  private projects;
100
+ private projectPaths;
100
101
  private isValid;
101
102
  constructor(workspacePath: string);
102
103
  list(): Project[];
103
104
  get(id: string): Project | undefined;
105
+ getProjectPath(id: string): string | undefined;
104
106
  getActiveProject(): Project | undefined;
105
107
  getConfig(): OpenfnConfig | undefined;
106
108
  get activeProjectId(): string | undefined;
@@ -110,4 +112,16 @@ declare class Workspace {
110
112
  declare function yamlToJson(y: string): any;
111
113
  declare function jsonToYaml(json: string | JSONObject): string;
112
114
 
113
- export { Workspace, Project as default, jsonToYaml, yamlToJson };
115
+ type GenerateWorkflowOptions = {
116
+ name: string;
117
+ uuidSeed: number;
118
+ openfnUuid: boolean;
119
+ };
120
+ /**
121
+ * Generate a Workflow from a simple text based representation
122
+ * The def array contains strings of pairs of nodes
123
+ * eg, ['a-b', 'b-c']
124
+ */
125
+ declare function generateWorkflow(def: string[], options?: Partial<GenerateWorkflowOptions>): Workflow;
126
+
127
+ export { Workspace, Project as default, generateWorkflow as generate, jsonToYaml, yamlToJson };
package/dist/index.js CHANGED
@@ -943,6 +943,7 @@ function merge(source, target, options) {
943
943
  }
944
944
 
945
945
  // src/Project.ts
946
+ var maybeCreateWorkflow = (wf) => wf instanceof Workflow_default ? wf : new Workflow_default(wf);
946
947
  var setConfigDefaults = (config = {}) => ({
947
948
  workflowRoot: config.workflowRoot ?? "workflows",
948
949
  formats: {
@@ -1007,7 +1008,7 @@ var Project = class {
1007
1008
  this.description = data.description;
1008
1009
  this.openfn = data.openfn;
1009
1010
  this.options = data.options;
1010
- this.workflows = data.workflows?.map((w) => new Workflow_default(w)) ?? [];
1011
+ this.workflows = data.workflows?.map(maybeCreateWorkflow) ?? [];
1011
1012
  this.collections = data.collections;
1012
1013
  this.credentials = data.credentials;
1013
1014
  this.meta = data.meta;
@@ -1072,6 +1073,7 @@ var PROJECT_EXTENSIONS = [".yaml", ".yml"];
1072
1073
  var Workspace = class {
1073
1074
  config;
1074
1075
  projects = [];
1076
+ projectPaths = /* @__PURE__ */ new Map();
1075
1077
  isValid = false;
1076
1078
  constructor(workspacePath) {
1077
1079
  const projectsPath = path2.join(workspacePath, PROJECTS_DIRECTORY);
@@ -1086,8 +1088,11 @@ var Workspace = class {
1086
1088
  (fileName) => PROJECT_EXTENSIONS.includes(path2.extname(fileName))
1087
1089
  );
1088
1090
  this.projects = stateFiles.map((file) => {
1089
- const data = fs3.readFileSync(path2.join(projectsPath, file), "utf-8");
1090
- return from_app_state_default(data, { format: "yaml" });
1091
+ const stateFilePath = path2.join(projectsPath, file);
1092
+ const data = fs3.readFileSync(stateFilePath, "utf-8");
1093
+ const project = from_app_state_default(data, { format: "yaml" });
1094
+ this.projectPaths.set(project.name, stateFilePath);
1095
+ return project;
1091
1096
  });
1092
1097
  }
1093
1098
  }
@@ -1097,6 +1102,9 @@ var Workspace = class {
1097
1102
  get(id) {
1098
1103
  return this.projects.find((p) => p.name === id);
1099
1104
  }
1105
+ getProjectPath(id) {
1106
+ return this.projectPaths.get(id);
1107
+ }
1100
1108
  getActiveProject() {
1101
1109
  return this.projects.find((p) => p.name === this.config?.name);
1102
1110
  }
@@ -1111,11 +1119,75 @@ var Workspace = class {
1111
1119
  }
1112
1120
  };
1113
1121
 
1122
+ // src/gen/workflow-generator.ts
1123
+ import { randomUUID as randomUUID2 } from "node:crypto";
1124
+
1125
+ // src/util/slugify.ts
1126
+ function slugify2(text) {
1127
+ return text.replace(/\W/g, " ").trim().replace(/\s+/g, "-").toLowerCase();
1128
+ }
1129
+
1130
+ // src/gen/workflow-generator.ts
1131
+ function gen(def, name = "workflow", uuidSeed, openfnUuid) {
1132
+ const ids = /* @__PURE__ */ new Map();
1133
+ const nodes = {};
1134
+ for (const conn of def) {
1135
+ const [from, to] = conn.split("-");
1136
+ if (nodes[from]) {
1137
+ if (to) {
1138
+ if (!nodes[from].next?.[to]) {
1139
+ nodes[from].next ??= {};
1140
+ nodes[from].next[to] = edge(`${from}-${to}`);
1141
+ }
1142
+ }
1143
+ } else {
1144
+ let props;
1145
+ if (to) {
1146
+ props = { next: { [to]: edge(`${from}-${to}`) } };
1147
+ }
1148
+ nodes[from] = node(from, props);
1149
+ }
1150
+ if (to && !nodes[to]) {
1151
+ nodes[to] = node(to);
1152
+ }
1153
+ }
1154
+ return {
1155
+ name,
1156
+ id: slugify2(name),
1157
+ steps: Object.values(nodes),
1158
+ ...openfnUuid ? { openfn: { uuid: randomUUID2() } } : {}
1159
+ };
1160
+ function node(id, props = {}) {
1161
+ return {
1162
+ id,
1163
+ ...props,
1164
+ openfn: { uuid: uuid(id) }
1165
+ };
1166
+ }
1167
+ function edge(id, props = {}) {
1168
+ return {
1169
+ ...props,
1170
+ openfn: { uuid: uuid(id) }
1171
+ };
1172
+ }
1173
+ function uuid(id) {
1174
+ const muuid = !isNaN(uuidSeed) ? ++uuidSeed : randomUUID2();
1175
+ ids.set(id, muuid);
1176
+ return muuid;
1177
+ }
1178
+ }
1179
+ function generateWorkflow(def, options = {}) {
1180
+ const { name, uuidSeed, openfnUuid } = options;
1181
+ const wf = gen(def, name, uuidSeed, openfnUuid);
1182
+ return new Workflow_default(wf);
1183
+ }
1184
+
1114
1185
  // src/index.ts
1115
1186
  var src_default = Project;
1116
1187
  export {
1117
1188
  Workspace,
1118
1189
  src_default as default,
1190
+ generateWorkflow as generate,
1119
1191
  jsonToYaml,
1120
1192
  yamlToJson
1121
1193
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openfn/project",
3
- "version": "0.3.1",
3
+ "version": "0.4.1",
4
4
  "description": "Read, serialize, replicate and sync OpenFn projects",
5
5
  "type": "module",
6
6
  "exports": {