@openfn/project 0.13.0 → 0.14.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 +13 -2
- package/dist/index.js +97 -14
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -89,6 +89,7 @@ type FromFsConfig = {
|
|
|
89
89
|
config?: Partial<l.WorkspaceConfig>;
|
|
90
90
|
logger?: Logger;
|
|
91
91
|
alias?: string;
|
|
92
|
+
name?: string;
|
|
92
93
|
};
|
|
93
94
|
|
|
94
95
|
type SerializedProject = Omit<Partial<l.Project>, 'workflows'> & {
|
|
@@ -98,7 +99,7 @@ type SerializedProject = Omit<Partial<l.Project>, 'workflows'> & {
|
|
|
98
99
|
type SerializedWorkflow = {
|
|
99
100
|
id: string;
|
|
100
101
|
name: string;
|
|
101
|
-
steps: WithMeta<l.
|
|
102
|
+
steps: WithMeta<Array<l.Job | l.Trigger>>;
|
|
102
103
|
openfn?: l.ProjectMeta;
|
|
103
104
|
};
|
|
104
105
|
|
|
@@ -157,6 +158,11 @@ type CLIMeta = {
|
|
|
157
158
|
alias?: string;
|
|
158
159
|
forked_from?: Record<string, string>;
|
|
159
160
|
};
|
|
161
|
+
type Credential = {
|
|
162
|
+
uuid: string;
|
|
163
|
+
name: string;
|
|
164
|
+
owner: string;
|
|
165
|
+
};
|
|
160
166
|
declare class Project {
|
|
161
167
|
/** Human readable project name. This corresponds to the label in Lightning */
|
|
162
168
|
name?: string;
|
|
@@ -174,7 +180,7 @@ declare class Project {
|
|
|
174
180
|
workspace?: Workspace;
|
|
175
181
|
config: l__default.WorkspaceConfig;
|
|
176
182
|
collections: any;
|
|
177
|
-
credentials:
|
|
183
|
+
credentials: Credential[];
|
|
178
184
|
sandbox?: SandboxMeta;
|
|
179
185
|
static from(type: 'project', data: any, options: never): Promise<Project>;
|
|
180
186
|
static from(type: 'state', data: Provisioner.Project, meta?: Partial<l__default.ProjectMeta>, config?: fromAppStateConfig): Promise<Project>;
|
|
@@ -201,6 +207,11 @@ declare class Project {
|
|
|
201
207
|
* Returns a map of ids:uuids for everything in the project
|
|
202
208
|
*/
|
|
203
209
|
getUUIDMap(): UUIDMap;
|
|
210
|
+
/**
|
|
211
|
+
* Find all project credentials referenced in all
|
|
212
|
+
* workflows and return it
|
|
213
|
+
*/
|
|
214
|
+
buildCredentialMap(): Credential[];
|
|
204
215
|
diff(project: Project, workflows?: string[]): WorkflowDiff[];
|
|
205
216
|
canMergeInto(target: Project): boolean;
|
|
206
217
|
/**
|
package/dist/index.js
CHANGED
|
@@ -44,6 +44,14 @@ function jsonToYaml(json) {
|
|
|
44
44
|
return yaml.stringify(doc, null, 2);
|
|
45
45
|
}
|
|
46
46
|
|
|
47
|
+
// src/util/get-credential-name.ts
|
|
48
|
+
var DELIMETER = "|";
|
|
49
|
+
var get_credential_name_default = (cred) => `${cred.owner}${DELIMETER}${cred.name}`;
|
|
50
|
+
var parse = (credentialName) => {
|
|
51
|
+
const [owner, name] = credentialName.split("|");
|
|
52
|
+
return { owner, name };
|
|
53
|
+
};
|
|
54
|
+
|
|
47
55
|
// src/serialize/to-app-state.ts
|
|
48
56
|
var defaultJobProps = {
|
|
49
57
|
// TODO why does the provisioner throw if these keys are not set?
|
|
@@ -58,16 +66,27 @@ function to_app_state_default(project, options = {}) {
|
|
|
58
66
|
env,
|
|
59
67
|
id,
|
|
60
68
|
fetched_at,
|
|
69
|
+
alias,
|
|
70
|
+
// shouldn't be written but has been caught in some legacy files
|
|
61
71
|
...rest
|
|
62
72
|
} = project.openfn ?? {};
|
|
63
73
|
const state = omitBy(
|
|
64
74
|
pick(project, ["name", "description", "collections"]),
|
|
65
75
|
isNil
|
|
66
76
|
);
|
|
67
|
-
state.id = uuid;
|
|
77
|
+
state.id = uuid ?? randomUUID();
|
|
68
78
|
Object.assign(state, rest, project.options);
|
|
69
|
-
|
|
70
|
-
|
|
79
|
+
const credentialsWithUuids = project.credentials?.map((c) => ({
|
|
80
|
+
...c,
|
|
81
|
+
uuid: c.uuid ?? randomUUID()
|
|
82
|
+
})) ?? [];
|
|
83
|
+
state.project_credentials = credentialsWithUuids.map((c) => ({
|
|
84
|
+
// note the subtle conversion here
|
|
85
|
+
id: c.uuid,
|
|
86
|
+
name: c.name,
|
|
87
|
+
owner: c.owner
|
|
88
|
+
}));
|
|
89
|
+
state.workflows = project.workflows.map((w) => mapWorkflow(w, credentialsWithUuids)).reduce((obj, wf) => {
|
|
71
90
|
obj[slugify(wf.name ?? wf.id)] = wf;
|
|
72
91
|
return obj;
|
|
73
92
|
}, {});
|
|
@@ -77,7 +96,7 @@ function to_app_state_default(project, options = {}) {
|
|
|
77
96
|
}
|
|
78
97
|
return state;
|
|
79
98
|
}
|
|
80
|
-
var mapWorkflow = (workflow) => {
|
|
99
|
+
var mapWorkflow = (workflow, credentials = []) => {
|
|
81
100
|
if (workflow instanceof Workflow_default) {
|
|
82
101
|
workflow = workflow.toJSON();
|
|
83
102
|
}
|
|
@@ -122,7 +141,21 @@ var mapWorkflow = (workflow) => {
|
|
|
122
141
|
node.body = s.expression;
|
|
123
142
|
}
|
|
124
143
|
if (typeof s.configuration === "string" && !s.configuration.endsWith(".json")) {
|
|
125
|
-
|
|
144
|
+
let projectCredentialId = s.configuration;
|
|
145
|
+
if (projectCredentialId) {
|
|
146
|
+
const mappedCredential = credentials.find((c) => {
|
|
147
|
+
const name = get_credential_name_default(c);
|
|
148
|
+
return name === projectCredentialId;
|
|
149
|
+
});
|
|
150
|
+
if (mappedCredential) {
|
|
151
|
+
projectCredentialId = mappedCredential.uuid;
|
|
152
|
+
} else {
|
|
153
|
+
console.warn(`WARING! Failed to map credential ${projectCredentialId} - Lightning may throw an error.
|
|
154
|
+
|
|
155
|
+
Ensure the credential exists in project.yaml and try again (maybe ensure the credential is attached to the project in the app and run project fetch)`);
|
|
156
|
+
}
|
|
157
|
+
otherOpenFnProps.project_credential_id = projectCredentialId;
|
|
158
|
+
}
|
|
126
159
|
}
|
|
127
160
|
Object.assign(node, defaultJobProps, otherOpenFnProps);
|
|
128
161
|
wfState.jobs[s.id ?? slugify(s.name)] = node;
|
|
@@ -175,7 +208,7 @@ var SHORT_HASH_LENGTH = 12;
|
|
|
175
208
|
function isDefined(v) {
|
|
176
209
|
return v !== void 0 && v !== null;
|
|
177
210
|
}
|
|
178
|
-
var
|
|
211
|
+
var parse2 = (version) => {
|
|
179
212
|
if (version.match(":")) {
|
|
180
213
|
const [source, hash] = version.split(":");
|
|
181
214
|
return { source, hash };
|
|
@@ -183,7 +216,7 @@ var parse = (version) => {
|
|
|
183
216
|
return { hash: version };
|
|
184
217
|
};
|
|
185
218
|
var match = (a, b) => {
|
|
186
|
-
return
|
|
219
|
+
return parse2(a).hash === parse2(b).hash;
|
|
187
220
|
};
|
|
188
221
|
var generateHash = (workflow, { source = "cli", sha = true } = {}) => {
|
|
189
222
|
const parts = [];
|
|
@@ -725,13 +758,18 @@ var from_app_state_default = (state, meta = {}, config = {}) => {
|
|
|
725
758
|
name,
|
|
726
759
|
description,
|
|
727
760
|
workflows,
|
|
728
|
-
project_credentials
|
|
761
|
+
project_credentials = [],
|
|
729
762
|
collections,
|
|
730
763
|
inserted_at,
|
|
731
764
|
updated_at,
|
|
732
765
|
parent_id,
|
|
733
766
|
...options
|
|
734
767
|
} = stateJson;
|
|
768
|
+
const credentials = project_credentials.map((c) => ({
|
|
769
|
+
uuid: c.id,
|
|
770
|
+
name: c.name,
|
|
771
|
+
owner: c.owner
|
|
772
|
+
}));
|
|
735
773
|
const proj = {
|
|
736
774
|
name,
|
|
737
775
|
description: description ?? void 0,
|
|
@@ -753,7 +791,9 @@ var from_app_state_default = (state, meta = {}, config = {}) => {
|
|
|
753
791
|
parentId: parent_id
|
|
754
792
|
};
|
|
755
793
|
}
|
|
756
|
-
proj.workflows = Object.values(stateJson.workflows).map(
|
|
794
|
+
proj.workflows = Object.values(stateJson.workflows).map(
|
|
795
|
+
(w) => mapWorkflow2(w, proj.credentials)
|
|
796
|
+
);
|
|
757
797
|
return new Project(proj, config);
|
|
758
798
|
};
|
|
759
799
|
var mapEdge = (edge) => {
|
|
@@ -775,7 +815,7 @@ var mapEdge = (edge) => {
|
|
|
775
815
|
}
|
|
776
816
|
return e;
|
|
777
817
|
};
|
|
778
|
-
var mapWorkflow2 = (workflow) => {
|
|
818
|
+
var mapWorkflow2 = (workflow, credentials = []) => {
|
|
779
819
|
const { jobs, edges, triggers, name, version_history, ...remoteProps } = workflow;
|
|
780
820
|
const mapped = {
|
|
781
821
|
name: workflow.name,
|
|
@@ -831,7 +871,14 @@ var mapWorkflow2 = (workflow) => {
|
|
|
831
871
|
openfn: renameKeys(remoteProps2, { id: "uuid" })
|
|
832
872
|
};
|
|
833
873
|
if (project_credential_id) {
|
|
834
|
-
|
|
874
|
+
const mappedCredential = credentials.find(
|
|
875
|
+
(c) => c.uuid == project_credential_id
|
|
876
|
+
);
|
|
877
|
+
if (mappedCredential) {
|
|
878
|
+
s.configuration = get_credential_name_default(mappedCredential);
|
|
879
|
+
} else {
|
|
880
|
+
s.configuration = project_credential_id;
|
|
881
|
+
}
|
|
835
882
|
}
|
|
836
883
|
if (outboundEdges.length) {
|
|
837
884
|
s.next = outboundEdges.reduce((next, edge) => {
|
|
@@ -894,8 +941,8 @@ var parseProject = async (options) => {
|
|
|
894
941
|
const context = loadWorkspaceFile(content, type);
|
|
895
942
|
const config = buildConfig(options.config ?? context.workspace);
|
|
896
943
|
const proj = {
|
|
897
|
-
id: context.project?.id,
|
|
898
|
-
name: context.project?.name,
|
|
944
|
+
id: options.name ? slugify(options.name) : context.project?.id,
|
|
945
|
+
name: options.name ? slugify(options.name) : context.project?.name,
|
|
899
946
|
openfn: omit2(context.project, ["id", "forked_from"]),
|
|
900
947
|
config,
|
|
901
948
|
workflows: [],
|
|
@@ -1415,13 +1462,32 @@ Pass --force to force the merge anyway`
|
|
|
1415
1462
|
name: source.name ?? target.name,
|
|
1416
1463
|
alias: source.alias ?? target.alias,
|
|
1417
1464
|
description: source.description ?? target.description,
|
|
1418
|
-
|
|
1465
|
+
// when mapping credentials, we prefer the UUIDs on the target
|
|
1466
|
+
credentials: replaceCredentials(
|
|
1467
|
+
source.credentials,
|
|
1468
|
+
target.credentials
|
|
1469
|
+
),
|
|
1419
1470
|
collections: source.collections ?? target.collections
|
|
1420
1471
|
};
|
|
1421
1472
|
return new Project(
|
|
1422
1473
|
baseMerge(target, source, ["collections"], assigns)
|
|
1423
1474
|
);
|
|
1424
1475
|
}
|
|
1476
|
+
var replaceCredentials = (sourceCreds = [], targetCreds = []) => {
|
|
1477
|
+
const result = [...targetCreds];
|
|
1478
|
+
const targetCredNames = targetCreds.reduce((acc, cred) => {
|
|
1479
|
+
acc[get_credential_name_default(cred)] = true;
|
|
1480
|
+
return acc;
|
|
1481
|
+
}, {});
|
|
1482
|
+
for (const sourceCred of sourceCreds) {
|
|
1483
|
+
const credName = get_credential_name_default(sourceCred);
|
|
1484
|
+
if (!targetCredNames[credName]) {
|
|
1485
|
+
const { uuid, ...credWithoutUuid } = sourceCred;
|
|
1486
|
+
result.push(credWithoutUuid);
|
|
1487
|
+
}
|
|
1488
|
+
}
|
|
1489
|
+
return result;
|
|
1490
|
+
};
|
|
1425
1491
|
|
|
1426
1492
|
// src/util/project-diff.ts
|
|
1427
1493
|
function diff(a, b, workflows) {
|
|
@@ -1582,6 +1648,22 @@ var Project = class _Project {
|
|
|
1582
1648
|
}
|
|
1583
1649
|
return result;
|
|
1584
1650
|
}
|
|
1651
|
+
/**
|
|
1652
|
+
* Find all project credentials referenced in all
|
|
1653
|
+
* workflows and return it
|
|
1654
|
+
*/
|
|
1655
|
+
buildCredentialMap() {
|
|
1656
|
+
const creds = {};
|
|
1657
|
+
for (const wf of this.workflows) {
|
|
1658
|
+
for (const step of wf.steps) {
|
|
1659
|
+
if (typeof step.configuration === "string" && !creds[step.configuration]) {
|
|
1660
|
+
const { name, owner } = parse(step.configuration);
|
|
1661
|
+
creds[step.configuration] = { name, owner };
|
|
1662
|
+
}
|
|
1663
|
+
}
|
|
1664
|
+
}
|
|
1665
|
+
return Object.values(creds);
|
|
1666
|
+
}
|
|
1585
1667
|
// Compare this project with another and return a list of workflow changes
|
|
1586
1668
|
diff(project, workflows = []) {
|
|
1587
1669
|
return diff(this, project, workflows);
|
|
@@ -1776,6 +1858,7 @@ var expectedNodeProps = [
|
|
|
1776
1858
|
// TODO need to clarify adaptor/adaptors confusion
|
|
1777
1859
|
"adaptor",
|
|
1778
1860
|
"adaptors",
|
|
1861
|
+
"configuration",
|
|
1779
1862
|
"expression",
|
|
1780
1863
|
"condition",
|
|
1781
1864
|
"label",
|