@openfn/project 0.9.0 → 0.9.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 +13 -1
- package/dist/index.js +109 -68
- package/package.json +3 -3
package/dist/index.d.ts
CHANGED
|
@@ -2,6 +2,17 @@ import * as l from '@openfn/lexicon';
|
|
|
2
2
|
import l__default, { WorkspaceConfig, UUID } from '@openfn/lexicon';
|
|
3
3
|
import { Provisioner } from '@openfn/lexicon/lightning';
|
|
4
4
|
|
|
5
|
+
type SerializedProject = Omit<Partial<l.Project>, 'workflows'> & {
|
|
6
|
+
version: number;
|
|
7
|
+
workflows: SerializedWorkflow[];
|
|
8
|
+
};
|
|
9
|
+
type SerializedWorkflow = {
|
|
10
|
+
id: string;
|
|
11
|
+
name: string;
|
|
12
|
+
steps: l.Step[];
|
|
13
|
+
openfn?: l.ProjectMeta;
|
|
14
|
+
};
|
|
15
|
+
|
|
5
16
|
type WithMeta<T> = T & {
|
|
6
17
|
openfn?: l.NodeMeta;
|
|
7
18
|
};
|
|
@@ -89,6 +100,7 @@ declare class Project {
|
|
|
89
100
|
config: l__default.WorkspaceConfig;
|
|
90
101
|
collections: any;
|
|
91
102
|
credentials: string[];
|
|
103
|
+
static from(type: 'project', data: any, options: never): Promise<Project>;
|
|
92
104
|
static from(type: 'state', data: Provisioner.Project, meta?: Partial<l__default.ProjectMeta>, config?: fromAppStateConfig): Promise<Project>;
|
|
93
105
|
static from(type: 'fs', options: FromFsConfig): Promise<Project>;
|
|
94
106
|
static from(type: 'path', data: string, options?: {
|
|
@@ -97,7 +109,7 @@ declare class Project {
|
|
|
97
109
|
static merge(source: Project, target: Project, options?: Partial<MergeProjectOptions>): Project;
|
|
98
110
|
constructor(data: Partial<l__default.Project>, config?: Partial<l__default.WorkspaceConfig>);
|
|
99
111
|
setConfig(config: Partial<WorkspaceConfig>): void;
|
|
100
|
-
serialize(type?: '
|
|
112
|
+
serialize(type?: 'project' | 'fs' | 'state', options?: any): string | Record<string, string> | Provisioner.Project_v1 | SerializedProject;
|
|
101
113
|
getWorkflow(idOrName: string): Workflow | undefined;
|
|
102
114
|
getIdentifier(): string;
|
|
103
115
|
getUUID(workflow: string | Workflow, stepId: string, otherStep?: string): any;
|
package/dist/index.js
CHANGED
|
@@ -210,7 +210,7 @@ var Workflow = class {
|
|
|
210
210
|
return this.index.uuid[id];
|
|
211
211
|
}
|
|
212
212
|
toJSON() {
|
|
213
|
-
return this.workflow;
|
|
213
|
+
return clone(this.workflow);
|
|
214
214
|
}
|
|
215
215
|
getUUIDMap() {
|
|
216
216
|
return this.index.uuid;
|
|
@@ -235,28 +235,10 @@ var Workflow_default = Workflow;
|
|
|
235
235
|
var serialize_exports = {};
|
|
236
236
|
__export(serialize_exports, {
|
|
237
237
|
fs: () => to_fs_default,
|
|
238
|
-
|
|
238
|
+
project: () => to_project_default,
|
|
239
239
|
state: () => to_app_state_default
|
|
240
240
|
});
|
|
241
241
|
|
|
242
|
-
// src/serialize/to-json.ts
|
|
243
|
-
function to_json_default(project) {
|
|
244
|
-
return {
|
|
245
|
-
// There must be a better way to do this?
|
|
246
|
-
// Do we just serialize all public fields?
|
|
247
|
-
id: project.id,
|
|
248
|
-
name: project.name,
|
|
249
|
-
description: project.description,
|
|
250
|
-
config: project.config,
|
|
251
|
-
meta: project.meta,
|
|
252
|
-
workflows: project.workflows.map((w) => w.toJSON()),
|
|
253
|
-
collections: project.collections,
|
|
254
|
-
credentials: project.credentials,
|
|
255
|
-
openfn: project.openfn,
|
|
256
|
-
options: project.options
|
|
257
|
-
};
|
|
258
|
-
}
|
|
259
|
-
|
|
260
242
|
// src/serialize/to-app-state.ts
|
|
261
243
|
import { pick, omitBy, isNil, sortBy } from "lodash-es";
|
|
262
244
|
import { randomUUID } from "node:crypto";
|
|
@@ -291,7 +273,14 @@ var defaultJobProps = {
|
|
|
291
273
|
project_credential_id: null
|
|
292
274
|
};
|
|
293
275
|
function to_app_state_default(project, options = {}) {
|
|
294
|
-
const {
|
|
276
|
+
const {
|
|
277
|
+
uuid,
|
|
278
|
+
endpoint,
|
|
279
|
+
env,
|
|
280
|
+
id,
|
|
281
|
+
fetched_at,
|
|
282
|
+
...rest
|
|
283
|
+
} = project.openfn ?? {};
|
|
295
284
|
const state = omitBy(
|
|
296
285
|
pick(project, ["name", "description", "collections"]),
|
|
297
286
|
isNil
|
|
@@ -382,6 +371,7 @@ var mapWorkflow = (workflow) => {
|
|
|
382
371
|
|
|
383
372
|
// src/serialize/to-fs.ts
|
|
384
373
|
import nodepath from "path";
|
|
374
|
+
import { omit } from "lodash-es";
|
|
385
375
|
|
|
386
376
|
// src/util/config.ts
|
|
387
377
|
import { readFileSync } from "node:fs";
|
|
@@ -508,10 +498,16 @@ var extractWorkflow = (project, workflowId) => {
|
|
|
508
498
|
// Not crazy about this - maybe we should do something better? Or do we like the consistency?
|
|
509
499
|
options: workflow.options,
|
|
510
500
|
steps: workflow.steps.map((step) => {
|
|
511
|
-
const { openfn, expression, ...mapped } = step;
|
|
501
|
+
const { openfn, expression, next, ...mapped } = step;
|
|
512
502
|
if (expression) {
|
|
513
503
|
mapped.expression = `./${step.id}.js`;
|
|
514
504
|
}
|
|
505
|
+
if (next && typeof next === "object") {
|
|
506
|
+
mapped.next = {};
|
|
507
|
+
for (const id in next) {
|
|
508
|
+
mapped.next[id] = omit(next[id], ["openfn"]);
|
|
509
|
+
}
|
|
510
|
+
}
|
|
515
511
|
return mapped;
|
|
516
512
|
})
|
|
517
513
|
};
|
|
@@ -546,18 +542,52 @@ var handleOutput = (data, filePath, format) => {
|
|
|
546
542
|
return { path: path5, content };
|
|
547
543
|
};
|
|
548
544
|
|
|
549
|
-
// src/
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
545
|
+
// src/serialize/to-project.ts
|
|
546
|
+
import { omitBy as omitBy2, isNil as isNil3 } from "lodash-es";
|
|
547
|
+
var SERIALIZE_VERSION = 2;
|
|
548
|
+
var to_project_default = (project, options = {}) => {
|
|
549
|
+
const proj = omitBy2(
|
|
550
|
+
{
|
|
551
|
+
id: project.id,
|
|
552
|
+
name: project.name,
|
|
553
|
+
version: SERIALIZE_VERSION,
|
|
554
|
+
// important!
|
|
555
|
+
description: project.description,
|
|
556
|
+
collections: project.collections,
|
|
557
|
+
credentials: project.credentials,
|
|
558
|
+
openfn: project.openfn,
|
|
559
|
+
meta: project.meta,
|
|
560
|
+
options: omitBy2(project.options, isNil3),
|
|
561
|
+
//workflows: project.workflows.map(mapWorkflow) as SerializedWorkflow[],
|
|
562
|
+
workflows: project.workflows.map(
|
|
563
|
+
(w) => w.toJSON()
|
|
564
|
+
)
|
|
565
|
+
},
|
|
566
|
+
isNil3
|
|
567
|
+
);
|
|
568
|
+
const format = options.format ?? proj.config?.formats.project;
|
|
569
|
+
if (format === "json") {
|
|
570
|
+
return proj;
|
|
571
|
+
}
|
|
572
|
+
return jsonToYaml(proj);
|
|
573
|
+
};
|
|
574
|
+
|
|
575
|
+
// src/util/ensure-json.ts
|
|
576
|
+
var ensure_json_default = (obj) => {
|
|
577
|
+
if (typeof obj === "string") {
|
|
578
|
+
const firstChar = obj.trim()[0];
|
|
579
|
+
if (firstChar === "{" || firstChar === "[") {
|
|
580
|
+
return JSON.parse(obj);
|
|
555
581
|
} else {
|
|
556
|
-
|
|
582
|
+
return yamlToJson(obj);
|
|
557
583
|
}
|
|
558
|
-
} else {
|
|
559
|
-
stateJson = state;
|
|
560
584
|
}
|
|
585
|
+
return obj;
|
|
586
|
+
};
|
|
587
|
+
|
|
588
|
+
// src/parse/from-app-state.ts
|
|
589
|
+
var from_app_state_default = (state, meta = {}, config = {}) => {
|
|
590
|
+
let stateJson = ensure_json_default(state);
|
|
561
591
|
delete config.format;
|
|
562
592
|
const {
|
|
563
593
|
id,
|
|
@@ -660,24 +690,32 @@ var mapWorkflow2 = (workflow) => {
|
|
|
660
690
|
};
|
|
661
691
|
|
|
662
692
|
// src/parse/from-path.ts
|
|
663
|
-
import { extname } from "node:path";
|
|
664
693
|
import { readFile } from "node:fs/promises";
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
let
|
|
670
|
-
if (
|
|
671
|
-
|
|
672
|
-
state = JSON.parse(source);
|
|
673
|
-
} else if (ext.match(/(ya?ml)$/)) {
|
|
674
|
-
config.format = "yaml";
|
|
675
|
-
state = yamlToJson(source);
|
|
694
|
+
|
|
695
|
+
// src/parse/from-project.ts
|
|
696
|
+
var from_project_default = (data, config) => {
|
|
697
|
+
let rawJson = ensure_json_default(data);
|
|
698
|
+
let json;
|
|
699
|
+
if (rawJson.version) {
|
|
700
|
+
json = from_v2(rawJson);
|
|
676
701
|
} else {
|
|
677
|
-
|
|
702
|
+
json = from_v1(rawJson);
|
|
678
703
|
}
|
|
679
|
-
|
|
680
|
-
|
|
704
|
+
return new Project_default(json, config);
|
|
705
|
+
};
|
|
706
|
+
var from_v1 = (data) => {
|
|
707
|
+
return from_app_state_default(data);
|
|
708
|
+
};
|
|
709
|
+
var from_v2 = (data) => {
|
|
710
|
+
return {
|
|
711
|
+
...data
|
|
712
|
+
};
|
|
713
|
+
};
|
|
714
|
+
|
|
715
|
+
// src/parse/from-path.ts
|
|
716
|
+
var from_path_default = async (path5, config = {}) => {
|
|
717
|
+
const source = await readFile(path5, "utf8");
|
|
718
|
+
return from_project_default(source, config);
|
|
681
719
|
};
|
|
682
720
|
|
|
683
721
|
// src/parse/from-fs.ts
|
|
@@ -699,6 +737,7 @@ var get_identifier_default = (config = {}) => {
|
|
|
699
737
|
};
|
|
700
738
|
|
|
701
739
|
// src/parse/from-fs.ts
|
|
740
|
+
import { omit as omit2 } from "lodash-es";
|
|
702
741
|
var parseProject = async (options) => {
|
|
703
742
|
const { root } = options;
|
|
704
743
|
const { type, content } = findWorkspaceFile(root);
|
|
@@ -717,13 +756,13 @@ var parseProject = async (options) => {
|
|
|
717
756
|
`${identifier}.${format}`
|
|
718
757
|
);
|
|
719
758
|
const stateFile = await fs.readFile(statePath, "utf8");
|
|
720
|
-
state =
|
|
759
|
+
state = from_project_default(stateFile, config);
|
|
721
760
|
} catch (e) {
|
|
722
761
|
console.warn(`Failed to find state file for ${identifier}`);
|
|
723
762
|
}
|
|
724
763
|
const proj = {
|
|
725
764
|
name: state?.name,
|
|
726
|
-
openfn: context.project,
|
|
765
|
+
openfn: omit2(context.project, ["id"]),
|
|
727
766
|
config,
|
|
728
767
|
workflows: []
|
|
729
768
|
};
|
|
@@ -1210,6 +1249,7 @@ var Project = class {
|
|
|
1210
1249
|
options;
|
|
1211
1250
|
// local metadata used by the CLI
|
|
1212
1251
|
// This stuff is not synced back to lightning
|
|
1252
|
+
// TODO maybe rename cli or local
|
|
1213
1253
|
meta;
|
|
1214
1254
|
// this contains meta about the connected openfn project
|
|
1215
1255
|
openfn;
|
|
@@ -1218,17 +1258,23 @@ var Project = class {
|
|
|
1218
1258
|
collections;
|
|
1219
1259
|
credentials;
|
|
1220
1260
|
static async from(type, data, ...rest) {
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1261
|
+
switch (type) {
|
|
1262
|
+
case "project":
|
|
1263
|
+
var [config] = rest;
|
|
1264
|
+
return from_project_default(data, config);
|
|
1265
|
+
case "state":
|
|
1266
|
+
return from_app_state_default(data, rest[0], rest[1]);
|
|
1267
|
+
case "fs":
|
|
1268
|
+
return parseProject(data);
|
|
1269
|
+
case "path":
|
|
1270
|
+
var [config] = rest;
|
|
1271
|
+
return from_path_default(data, config);
|
|
1272
|
+
default:
|
|
1273
|
+
throw new Error(`Didn't recognize type ${type}`);
|
|
1227
1274
|
}
|
|
1228
|
-
throw new Error(`Didn't recognize type ${type}`);
|
|
1229
1275
|
}
|
|
1230
1276
|
// Diff two projects
|
|
1231
|
-
//
|
|
1277
|
+
// static diff(a: Project, b: Project) {}
|
|
1232
1278
|
// Merge a source project (staging) into the target project (main)
|
|
1233
1279
|
// Returns a new Project
|
|
1234
1280
|
// TODO: throw if histories have diverged
|
|
@@ -1254,7 +1300,7 @@ var Project = class {
|
|
|
1254
1300
|
setConfig(config) {
|
|
1255
1301
|
this.config = buildConfig(config);
|
|
1256
1302
|
}
|
|
1257
|
-
serialize(type = "
|
|
1303
|
+
serialize(type = "project", options) {
|
|
1258
1304
|
if (type in serialize_exports) {
|
|
1259
1305
|
return serialize_exports[type](this, options);
|
|
1260
1306
|
}
|
|
@@ -1317,7 +1363,7 @@ function pathExists(fpath, type) {
|
|
|
1317
1363
|
|
|
1318
1364
|
// src/Workspace.ts
|
|
1319
1365
|
var Workspace = class {
|
|
1320
|
-
// @ts-ignore config not
|
|
1366
|
+
// @ts-ignore config not definitely assigned - it sure is
|
|
1321
1367
|
config;
|
|
1322
1368
|
activeProject;
|
|
1323
1369
|
projects = [];
|
|
@@ -1345,14 +1391,9 @@ var Workspace = class {
|
|
|
1345
1391
|
const stateFilePath = path3.join(projectsPath, file);
|
|
1346
1392
|
try {
|
|
1347
1393
|
const data = fs3.readFileSync(stateFilePath, "utf-8");
|
|
1348
|
-
const project =
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
{
|
|
1352
|
-
...this.config,
|
|
1353
|
-
format: this.config?.formats.project
|
|
1354
|
-
}
|
|
1355
|
-
);
|
|
1394
|
+
const project = from_project_default(data, {
|
|
1395
|
+
...this.config
|
|
1396
|
+
});
|
|
1356
1397
|
this.projectPaths.set(project.id, stateFilePath);
|
|
1357
1398
|
return project;
|
|
1358
1399
|
} catch (e) {
|
|
@@ -1400,7 +1441,7 @@ import { randomUUID as randomUUID2 } from "node:crypto";
|
|
|
1400
1441
|
import path4 from "node:path";
|
|
1401
1442
|
import { readFileSync as readFileSync2 } from "node:fs";
|
|
1402
1443
|
import { grammar } from "ohm-js";
|
|
1403
|
-
import { isNil as
|
|
1444
|
+
import { isNil as isNil4, set } from "lodash-es";
|
|
1404
1445
|
var parser;
|
|
1405
1446
|
var expectedNodeProps = [
|
|
1406
1447
|
// TODO need to clarify adaptor/adaptors confusion
|
|
@@ -1571,7 +1612,7 @@ function generateWorkflow(def, options = {}) {
|
|
|
1571
1612
|
if (options.uuidMap && raw.id in options.uuidMap) {
|
|
1572
1613
|
uuid = options.uuidMap[raw.id];
|
|
1573
1614
|
}
|
|
1574
|
-
if (!
|
|
1615
|
+
if (!isNil4(uuid) && options.openfnUuid) {
|
|
1575
1616
|
raw.openfn ??= {};
|
|
1576
1617
|
raw.openfn.uuid = uuid;
|
|
1577
1618
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openfn/project",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.1",
|
|
4
4
|
"description": "Read, serialize, replicate and sync OpenFn projects",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -34,8 +34,8 @@
|
|
|
34
34
|
"lodash-es": "^4.17.21",
|
|
35
35
|
"ohm-js": "^17.2.1",
|
|
36
36
|
"yaml": "^2.2.2",
|
|
37
|
-
"@openfn/lexicon": "^1.2.
|
|
38
|
-
"@openfn/logger": "1.0
|
|
37
|
+
"@openfn/lexicon": "^1.2.7",
|
|
38
|
+
"@openfn/logger": "1.1.0"
|
|
39
39
|
},
|
|
40
40
|
"files": [
|
|
41
41
|
"dist",
|