@openfn/project 0.10.0 → 0.11.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 +6 -0
- package/dist/index.js +74 -28
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -15,6 +15,8 @@ declare class Workflow {
|
|
|
15
15
|
options: any;
|
|
16
16
|
constructor(workflow: l.Workflow);
|
|
17
17
|
get steps(): WithMeta<l.Job & l.Trigger>[];
|
|
18
|
+
get start(): string | undefined;
|
|
19
|
+
set start(s: string);
|
|
18
20
|
_buildIndex(): void;
|
|
19
21
|
set(id: string, props: Partial<l.Job | l.StepEdge>): this;
|
|
20
22
|
get(id: string): WithMeta<l.Step | l.Trigger | l.StepEdge>;
|
|
@@ -43,6 +45,7 @@ type FromPathConfig = l.WorkspaceConfig & {
|
|
|
43
45
|
|
|
44
46
|
type FromFsConfig = {
|
|
45
47
|
root: string;
|
|
48
|
+
config?: Partial<l.WorkspaceConfig>;
|
|
46
49
|
logger?: Logger;
|
|
47
50
|
};
|
|
48
51
|
|
|
@@ -66,6 +69,7 @@ type MergeProjectOptions = {
|
|
|
66
69
|
declare class Workspace {
|
|
67
70
|
config: l.WorkspaceConfig;
|
|
68
71
|
activeProject?: l.ProjectMeta;
|
|
72
|
+
root: string;
|
|
69
73
|
private projects;
|
|
70
74
|
private projectPaths;
|
|
71
75
|
private isValid;
|
|
@@ -77,6 +81,8 @@ declare class Workspace {
|
|
|
77
81
|
get(nameyThing: string): Project | null;
|
|
78
82
|
getProjectPath(id: string): string | undefined;
|
|
79
83
|
getActiveProject(): Project | undefined;
|
|
84
|
+
getCheckedOutProject(): Promise<Project>;
|
|
85
|
+
getCredentialMap(): string | undefined;
|
|
80
86
|
getConfig(): Partial<l.WorkspaceConfig>;
|
|
81
87
|
get activeProjectId(): unknown;
|
|
82
88
|
get valid(): boolean;
|
package/dist/index.js
CHANGED
|
@@ -105,7 +105,16 @@ var Workflow = class {
|
|
|
105
105
|
};
|
|
106
106
|
this.workflow = clone(workflow);
|
|
107
107
|
this.workflow.history = workflow.history?.length ? workflow.history : [];
|
|
108
|
-
const {
|
|
108
|
+
const {
|
|
109
|
+
id,
|
|
110
|
+
name,
|
|
111
|
+
openfn,
|
|
112
|
+
steps,
|
|
113
|
+
history,
|
|
114
|
+
start: _start,
|
|
115
|
+
options,
|
|
116
|
+
...rest
|
|
117
|
+
} = workflow;
|
|
109
118
|
if (!(id || name)) {
|
|
110
119
|
throw new Error("A Workflow MUST have a name or id");
|
|
111
120
|
}
|
|
@@ -116,12 +125,18 @@ var Workflow = class {
|
|
|
116
125
|
this.workflow.name = this.name;
|
|
117
126
|
}
|
|
118
127
|
this.openfn = openfn;
|
|
119
|
-
this.options = options;
|
|
128
|
+
this.options = Object.assign({}, options, rest);
|
|
120
129
|
this._buildIndex();
|
|
121
130
|
}
|
|
122
131
|
get steps() {
|
|
123
132
|
return this.workflow.steps;
|
|
124
133
|
}
|
|
134
|
+
get start() {
|
|
135
|
+
return this.workflow.start;
|
|
136
|
+
}
|
|
137
|
+
set start(s) {
|
|
138
|
+
this.workflow.start = s;
|
|
139
|
+
}
|
|
125
140
|
_buildIndex() {
|
|
126
141
|
for (const step of this.workflow.steps) {
|
|
127
142
|
const s = step;
|
|
@@ -361,11 +376,17 @@ var mapWorkflow = (workflow) => {
|
|
|
361
376
|
} else {
|
|
362
377
|
e.source_job_id = node.id;
|
|
363
378
|
}
|
|
364
|
-
if (rules.condition
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
379
|
+
if (rules.condition) {
|
|
380
|
+
if (typeof rules.condition === "boolean") {
|
|
381
|
+
e.condition_type = rules.condition ? "always" : "never";
|
|
382
|
+
} else if (rules.condition.match(
|
|
383
|
+
/^(always|never|on_job_success|on_job_failure)$/
|
|
384
|
+
)) {
|
|
385
|
+
e.condition_type = rules.condition;
|
|
386
|
+
} else {
|
|
387
|
+
e.condition_type = "js_expression";
|
|
388
|
+
e.condition_expression = rules.condition;
|
|
389
|
+
}
|
|
369
390
|
}
|
|
370
391
|
wfState.edges.push(e);
|
|
371
392
|
});
|
|
@@ -383,6 +404,7 @@ import { readFileSync } from "node:fs";
|
|
|
383
404
|
import path from "node:path";
|
|
384
405
|
import { pickBy, isNil as isNil2 } from "lodash-es";
|
|
385
406
|
var buildConfig = (config = {}) => ({
|
|
407
|
+
credentials: "credentials.yaml",
|
|
386
408
|
...config,
|
|
387
409
|
dirs: {
|
|
388
410
|
projects: config.dirs?.projects ?? ".projects",
|
|
@@ -499,6 +521,7 @@ var extractWorkflow = (project, workflowId) => {
|
|
|
499
521
|
const wf = {
|
|
500
522
|
id: workflow.id,
|
|
501
523
|
name: workflow.name,
|
|
524
|
+
start: workflow.start,
|
|
502
525
|
// Note: if no options are defined, options will serialize to an empty object
|
|
503
526
|
// Not crazy about this - maybe we should do something better? Or do we like the consistency?
|
|
504
527
|
options: workflow.options,
|
|
@@ -652,20 +675,23 @@ var from_app_state_default = (state, meta = {}, config = {}) => {
|
|
|
652
675
|
proj.workflows = stateJson.workflows.map(mapWorkflow2);
|
|
653
676
|
return new Project(proj, config);
|
|
654
677
|
};
|
|
655
|
-
var
|
|
678
|
+
var mapEdge = (edge) => {
|
|
656
679
|
const e = {
|
|
657
680
|
disabled: !edge.enabled
|
|
658
681
|
};
|
|
659
|
-
if (edge.condition_type === "
|
|
660
|
-
e.condition = true;
|
|
661
|
-
} else if (edge.condition_type === "never") {
|
|
662
|
-
e.condition = false;
|
|
663
|
-
} else {
|
|
682
|
+
if (edge.condition_type === "js_expression") {
|
|
664
683
|
e.condition = edge.condition_expression;
|
|
684
|
+
} else if (edge.condition_type) {
|
|
685
|
+
e.condition = edge.condition_type;
|
|
686
|
+
}
|
|
687
|
+
if (edge.condition_label) {
|
|
688
|
+
e.name = edge.condition_label;
|
|
689
|
+
}
|
|
690
|
+
if (edge.id) {
|
|
691
|
+
e.openfn = {
|
|
692
|
+
uuid: edge.id
|
|
693
|
+
};
|
|
665
694
|
}
|
|
666
|
-
e.openfn = {
|
|
667
|
-
uuid: edge.id
|
|
668
|
-
};
|
|
669
695
|
return e;
|
|
670
696
|
};
|
|
671
697
|
var mapWorkflow2 = (workflow) => {
|
|
@@ -681,6 +707,9 @@ var mapWorkflow2 = (workflow) => {
|
|
|
681
707
|
}
|
|
682
708
|
workflow.triggers.forEach((trigger) => {
|
|
683
709
|
const { type, ...otherProps } = trigger;
|
|
710
|
+
if (!mapped.start) {
|
|
711
|
+
mapped.start = `trigger-${type}`;
|
|
712
|
+
}
|
|
684
713
|
const connectedEdges = edges.filter(
|
|
685
714
|
(e) => e.source_trigger_id === trigger.id
|
|
686
715
|
);
|
|
@@ -693,7 +722,7 @@ var mapWorkflow2 = (workflow) => {
|
|
|
693
722
|
if (!target) {
|
|
694
723
|
throw new Error(`Failed to find ${edge.target_job_id}`);
|
|
695
724
|
}
|
|
696
|
-
obj[slugify(target.name)] =
|
|
725
|
+
obj[slugify(target.name)] = mapEdge(edge);
|
|
697
726
|
return obj;
|
|
698
727
|
}, {})
|
|
699
728
|
});
|
|
@@ -723,7 +752,7 @@ var mapWorkflow2 = (workflow) => {
|
|
|
723
752
|
if (outboundEdges.length) {
|
|
724
753
|
s.next = outboundEdges.reduce((next, edge) => {
|
|
725
754
|
const target = jobs.find((j) => j.id === edge.target_job_id);
|
|
726
|
-
next[slugify(target.name)] =
|
|
755
|
+
next[slugify(target.name)] = mapEdge(edge);
|
|
727
756
|
return next;
|
|
728
757
|
}, {});
|
|
729
758
|
}
|
|
@@ -739,16 +768,13 @@ import path2 from "node:path";
|
|
|
739
768
|
// src/parse/from-project.ts
|
|
740
769
|
var from_project_default = (data, config) => {
|
|
741
770
|
let rawJson = ensure_json_default(data);
|
|
742
|
-
let json;
|
|
743
771
|
if (rawJson.cli?.version ?? rawJson.version) {
|
|
744
|
-
|
|
745
|
-
} else {
|
|
746
|
-
json = from_v1(rawJson);
|
|
772
|
+
return new Project_default(from_v2(rawJson), config);
|
|
747
773
|
}
|
|
748
|
-
return
|
|
774
|
+
return from_v1(rawJson, config);
|
|
749
775
|
};
|
|
750
|
-
var from_v1 = (data) => {
|
|
751
|
-
return from_app_state_default(data);
|
|
776
|
+
var from_v1 = (data, config = {}) => {
|
|
777
|
+
return from_app_state_default(data, {}, config);
|
|
752
778
|
};
|
|
753
779
|
var from_v2 = (data) => {
|
|
754
780
|
return {
|
|
@@ -780,7 +806,7 @@ var parseProject = async (options) => {
|
|
|
780
806
|
const { root, logger } = options;
|
|
781
807
|
const { type, content } = findWorkspaceFile(root);
|
|
782
808
|
const context = loadWorkspaceFile(content, type);
|
|
783
|
-
const config = buildConfig(context.workspace);
|
|
809
|
+
const config = buildConfig(options.config ?? context.workspace);
|
|
784
810
|
const proj = {
|
|
785
811
|
id: context.project?.id,
|
|
786
812
|
name: context.project?.name,
|
|
@@ -790,14 +816,26 @@ var parseProject = async (options) => {
|
|
|
790
816
|
};
|
|
791
817
|
const workflowDir = config.workflowRoot ?? config.dirs?.workflows ?? "workflows";
|
|
792
818
|
const fileType = config.formats?.workflow ?? "yaml";
|
|
793
|
-
const pattern =
|
|
819
|
+
const pattern = path3.resolve(root, workflowDir) + `/**/*.${fileType}`;
|
|
794
820
|
const candidateWfs = await glob(pattern, {
|
|
795
821
|
ignore: ["**node_modules/**", "**tmp**"]
|
|
796
822
|
});
|
|
797
823
|
for (const filePath of candidateWfs) {
|
|
798
824
|
const candidate = await fs.readFile(filePath, "utf-8");
|
|
799
825
|
try {
|
|
800
|
-
|
|
826
|
+
let wf = fileType === "yaml" ? yamlToJson(candidate) : JSON.parse(candidate);
|
|
827
|
+
if (wf.workflow) {
|
|
828
|
+
if (wf.options) {
|
|
829
|
+
const { start, ...rest } = wf.options;
|
|
830
|
+
if (start) {
|
|
831
|
+
wf.workflow.start = start;
|
|
832
|
+
}
|
|
833
|
+
if (rest) {
|
|
834
|
+
wf.workflow.options = Object.assign({}, wf.workflow.options, rest);
|
|
835
|
+
}
|
|
836
|
+
}
|
|
837
|
+
wf = wf.workflow;
|
|
838
|
+
}
|
|
801
839
|
if (wf.id && Array.isArray(wf.steps)) {
|
|
802
840
|
for (const step of wf.steps) {
|
|
803
841
|
if (step.expression && step.expression.endsWith(".js")) {
|
|
@@ -1445,6 +1483,7 @@ var Workspace = class {
|
|
|
1445
1483
|
config;
|
|
1446
1484
|
// TODO activeProject should be the actual project
|
|
1447
1485
|
activeProject;
|
|
1486
|
+
root;
|
|
1448
1487
|
projects = [];
|
|
1449
1488
|
projectPaths = /* @__PURE__ */ new Map();
|
|
1450
1489
|
isValid = false;
|
|
@@ -1452,6 +1491,7 @@ var Workspace = class {
|
|
|
1452
1491
|
// Set validate to false to suppress warnings if a Workspace doesn't exist
|
|
1453
1492
|
// This is appropriate if, say, fetching a project for the first time
|
|
1454
1493
|
constructor(workspacePath, logger, validate = true) {
|
|
1494
|
+
this.root = workspacePath;
|
|
1455
1495
|
this.logger = logger ?? createLogger("Workspace", { level: "info" });
|
|
1456
1496
|
let context = { workspace: void 0, project: void 0 };
|
|
1457
1497
|
try {
|
|
@@ -1517,6 +1557,12 @@ var Workspace = class {
|
|
|
1517
1557
|
getActiveProject() {
|
|
1518
1558
|
return this.projects.find((p) => p.openfn?.uuid === this.activeProject?.uuid) ?? this.projects.find((p) => p.id === this.activeProject?.id);
|
|
1519
1559
|
}
|
|
1560
|
+
getCheckedOutProject() {
|
|
1561
|
+
return Project.from("fs", { root: this.root, config: this.config });
|
|
1562
|
+
}
|
|
1563
|
+
getCredentialMap() {
|
|
1564
|
+
return this.config.credentials;
|
|
1565
|
+
}
|
|
1520
1566
|
// TODO this needs to return default values
|
|
1521
1567
|
// We should always rely on the workspace to load these values
|
|
1522
1568
|
getConfig() {
|