@openfn/project 0.5.1 → 0.6.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.d.ts CHANGED
@@ -32,6 +32,7 @@ declare class Workflow {
32
32
  getUUID(id: any): string;
33
33
  toJSON(): JSON.Object;
34
34
  getUUIDMap(): Record<string, string>;
35
+ getVersionHash(): string;
35
36
  }
36
37
 
37
38
  type FromFsConfig = {
@@ -95,7 +96,7 @@ declare class Project {
95
96
  constructor(data: l.Project, repoConfig?: RepoOptions);
96
97
  serialize(type?: 'json' | 'yaml' | 'fs' | 'state', options?: any): any;
97
98
  getVersionHash(): void;
98
- getWorkflow(id: string): Workflow | undefined;
99
+ getWorkflow(idOrName: string): Workflow | undefined;
99
100
  getIdentifier(): string;
100
101
  compare(proj: Project): void;
101
102
  getUUID(workflow: string | Workflow, stepId: string, otherStep?: string): any;
package/dist/index.js CHANGED
@@ -9,6 +9,74 @@ function slugify(text) {
9
9
  return text?.replace(/\W/g, " ").trim().replace(/\s+/g, "-").toLowerCase();
10
10
  }
11
11
 
12
+ // src/util/version.ts
13
+ import crypto from "node:crypto";
14
+ var SHORT_HASH_LENGTH = 12;
15
+ function isDefined(v) {
16
+ return v !== void 0 && v !== null;
17
+ }
18
+ var generateHash = (workflow, source = "cli") => {
19
+ const parts = [];
20
+ const wfKeys = ["name", "credentials"].sort();
21
+ const stepKeys = [
22
+ "name",
23
+ "adaptors",
24
+ "adaptor",
25
+ // there's ao adaptor & adaptors key in steps somehow.
26
+ "expression",
27
+ "configuration",
28
+ // assumes a string credential id
29
+ "expression"
30
+ // TODO need to model trigger types in this, which I think are currently ignored
31
+ ].sort();
32
+ const edgeKeys = [
33
+ "condition",
34
+ "label",
35
+ "disabled"
36
+ // This feels more like an option - should be excluded?
37
+ ].sort();
38
+ wfKeys.forEach((key) => {
39
+ if (isDefined(workflow[key])) {
40
+ parts.push(key, serializeValue(workflow[key]));
41
+ }
42
+ });
43
+ const steps = (workflow.steps || []).slice().sort((a, b) => {
44
+ const aName = a.name ?? "";
45
+ const bName = b.name ?? "";
46
+ return aName.localeCompare(bName);
47
+ });
48
+ for (const step of steps) {
49
+ stepKeys.forEach((key) => {
50
+ if (isDefined(step[key])) {
51
+ parts.push(key, serializeValue(step[key]));
52
+ }
53
+ });
54
+ if (step.next && Array.isArray(step.next)) {
55
+ const edges = step.next.slice().sort((a, b) => {
56
+ const aLabel = a.label || "";
57
+ const bLabel = b.label || "";
58
+ return aLabel.localeCompare(bLabel);
59
+ });
60
+ for (const edge of edges) {
61
+ edgeKeys.forEach((key) => {
62
+ if (isDefined(edge[key])) {
63
+ parts.push(key, serializeValue(edge[key]));
64
+ }
65
+ });
66
+ }
67
+ }
68
+ }
69
+ const str = parts.join("");
70
+ const hash = crypto.createHash("sha256").update(str).digest("hex");
71
+ return `${source}:${hash.substring(0, SHORT_HASH_LENGTH)}`;
72
+ };
73
+ function serializeValue(val) {
74
+ if (typeof val === "object") {
75
+ return JSON.stringify(val);
76
+ }
77
+ return String(val);
78
+ }
79
+
12
80
  // src/Workflow.ts
13
81
  var clone = (obj) => JSON.parse(JSON.stringify(obj));
14
82
  var Workflow = class {
@@ -138,6 +206,9 @@ var Workflow = class {
138
206
  getUUIDMap() {
139
207
  return this.index.uuid;
140
208
  }
209
+ getVersionHash() {
210
+ return generateHash(this);
211
+ }
141
212
  };
142
213
  var Workflow_default = Workflow;
143
214
 
@@ -1031,7 +1102,7 @@ var Project = class {
1031
1102
  // collections for the project
1032
1103
  // TODO to be well typed
1033
1104
  collections;
1034
- static from(type, data, options) {
1105
+ static from(type, data, options = {}) {
1035
1106
  if (type === "state") {
1036
1107
  return from_app_state_default(data, options);
1037
1108
  } else if (type === "fs") {
@@ -1079,8 +1150,8 @@ var Project = class {
1079
1150
  // what else might we need?
1080
1151
  // get workflow by name or id
1081
1152
  // this is fuzzy, but is that wrong?
1082
- getWorkflow(id) {
1083
- return this.workflows.find((wf) => wf.id == id);
1153
+ getWorkflow(idOrName) {
1154
+ return this.workflows.find((wf) => wf.id == idOrName) || this.workflows.find((wf) => wf.name === idOrName);
1084
1155
  }
1085
1156
  // it's the name of the project.yaml file
1086
1157
  // qualified name? Remote name? App name?
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openfn/project",
3
- "version": "0.5.1",
3
+ "version": "0.6.0",
4
4
  "description": "Read, serialize, replicate and sync OpenFn projects",
5
5
  "type": "module",
6
6
  "exports": {