@openfn/project 0.7.0 → 0.7.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 +10 -17
- package/dist/index.js +23 -31
- package/package.json +2 -1
package/dist/index.d.ts
CHANGED
|
@@ -37,16 +37,16 @@ declare class Workflow {
|
|
|
37
37
|
canMergeInto(target: Workflow): boolean;
|
|
38
38
|
}
|
|
39
39
|
|
|
40
|
-
type FileFormats
|
|
40
|
+
type FileFormats = 'yaml' | 'json';
|
|
41
41
|
interface WorkspaceConfig {
|
|
42
42
|
dirs: {
|
|
43
43
|
workflows: string;
|
|
44
44
|
projects: string;
|
|
45
45
|
};
|
|
46
46
|
formats: {
|
|
47
|
-
openfn: FileFormats
|
|
48
|
-
project: FileFormats
|
|
49
|
-
workflow: FileFormats
|
|
47
|
+
openfn: FileFormats;
|
|
48
|
+
project: FileFormats;
|
|
49
|
+
workflow: FileFormats;
|
|
50
50
|
};
|
|
51
51
|
}
|
|
52
52
|
|
|
@@ -66,13 +66,14 @@ type MergeProjectOptions = Partial<{
|
|
|
66
66
|
|
|
67
67
|
declare class Workspace {
|
|
68
68
|
config?: WorkspaceConfig;
|
|
69
|
-
|
|
69
|
+
activeProject: ProjectMeta;
|
|
70
70
|
private projects;
|
|
71
71
|
private projectPaths;
|
|
72
72
|
private isValid;
|
|
73
73
|
constructor(workspacePath: string);
|
|
74
74
|
loadProject(): void;
|
|
75
75
|
list(): Project[];
|
|
76
|
+
/** Get a project by its id or UUID */
|
|
76
77
|
get(id: string): Project | undefined;
|
|
77
78
|
getProjectPath(id: string): string | undefined;
|
|
78
79
|
getActiveProject(): Project | undefined;
|
|
@@ -81,18 +82,11 @@ declare class Workspace {
|
|
|
81
82
|
get valid(): boolean;
|
|
82
83
|
}
|
|
83
84
|
|
|
84
|
-
type RepoOptions = {
|
|
85
|
-
/**default workflow root when serializing to fs (relative to openfn.yaml) */
|
|
86
|
-
workflowRoot?: string;
|
|
87
|
-
formats: {
|
|
88
|
-
openfn: FileFormats;
|
|
89
|
-
workflow: FileFormats;
|
|
90
|
-
project: FileFormats;
|
|
91
|
-
};
|
|
92
|
-
};
|
|
93
85
|
declare class Project {
|
|
94
|
-
/** project name */
|
|
86
|
+
/** Human readable project name. This corresponds to the label in Lightning */
|
|
95
87
|
name?: string;
|
|
88
|
+
/** Project id. Must be url safe. May be derived from the name. NOT a UUID */
|
|
89
|
+
id: string;
|
|
96
90
|
description?: string;
|
|
97
91
|
history: string[];
|
|
98
92
|
workflows: Workflow[];
|
|
@@ -109,10 +103,9 @@ declare class Project {
|
|
|
109
103
|
}): Project;
|
|
110
104
|
static diff(a: Project, b: Project): void;
|
|
111
105
|
static merge(source: Project, target: Project, options: MergeProjectOptions): Project;
|
|
112
|
-
constructor(data: l.Project,
|
|
106
|
+
constructor(data: l.Project, config?: RepoOptions);
|
|
113
107
|
setConfig(config: Partial<WorkspaceConfig>): void;
|
|
114
108
|
serialize(type?: 'json' | 'yaml' | 'fs' | 'state', options?: any): any;
|
|
115
|
-
getVersionHash(): void;
|
|
116
109
|
getWorkflow(idOrName: string): Workflow | undefined;
|
|
117
110
|
getIdentifier(): string;
|
|
118
111
|
compare(proj: Project): void;
|
package/dist/index.js
CHANGED
|
@@ -4,6 +4,9 @@ var __export = (target, all) => {
|
|
|
4
4
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
5
5
|
};
|
|
6
6
|
|
|
7
|
+
// src/Project.ts
|
|
8
|
+
import { humanId } from "human-id";
|
|
9
|
+
|
|
7
10
|
// src/util/slugify.ts
|
|
8
11
|
function slugify(text) {
|
|
9
12
|
return text?.replace(/\W/g, " ").trim().replace(/\s+/g, "-").toLowerCase();
|
|
@@ -384,7 +387,8 @@ var buildConfig = (config = {}) => ({
|
|
|
384
387
|
});
|
|
385
388
|
var extractConfig = (source) => {
|
|
386
389
|
const project = {
|
|
387
|
-
...source.openfn || {}
|
|
390
|
+
...source.openfn || {},
|
|
391
|
+
id: source.id
|
|
388
392
|
};
|
|
389
393
|
const workspace = {
|
|
390
394
|
...source.config
|
|
@@ -438,13 +442,10 @@ var loadWorkspaceFile = (contents, format = "yaml") => {
|
|
|
438
442
|
return { project, workspace };
|
|
439
443
|
};
|
|
440
444
|
var findWorkspaceFile = (dir = ".") => {
|
|
441
|
-
console.log({ dir });
|
|
442
445
|
let content, type;
|
|
443
446
|
try {
|
|
444
447
|
type = "yaml";
|
|
445
|
-
console.log(path.resolve(path.join(dir, "openfn.yaml")));
|
|
446
448
|
content = readFileSync(path.resolve(path.join(dir, "openfn.yaml")), "utf8");
|
|
447
|
-
console.log({ content });
|
|
448
449
|
} catch (e) {
|
|
449
450
|
try {
|
|
450
451
|
type = "json";
|
|
@@ -710,6 +711,7 @@ var parseProject = async (options = {}) => {
|
|
|
710
711
|
console.warn(`Failed to find state file for ${identifier}`);
|
|
711
712
|
}
|
|
712
713
|
const proj = {
|
|
714
|
+
name: state?.name,
|
|
713
715
|
openfn: context.project,
|
|
714
716
|
config,
|
|
715
717
|
workflows: []
|
|
@@ -729,7 +731,7 @@ var parseProject = async (options = {}) => {
|
|
|
729
731
|
const wfState = (state && state.getWorkflow(wf.id)) ?? {};
|
|
730
732
|
wf.openfn = {
|
|
731
733
|
uuid: wfState.openfn?.uuid ?? null
|
|
732
|
-
// TODO do we need to transfer more stuff?
|
|
734
|
+
// TODO do we need to transfer more stuff? Options maybe?
|
|
733
735
|
};
|
|
734
736
|
for (const step of wf.steps) {
|
|
735
737
|
if (step.expression && step.expression.endsWith(".js")) {
|
|
@@ -1175,10 +1177,12 @@ var Project = class {
|
|
|
1175
1177
|
// what schema version is this?
|
|
1176
1178
|
// And how are we tracking this?
|
|
1177
1179
|
// version;
|
|
1178
|
-
/** project name */
|
|
1180
|
+
/** Human readable project name. This corresponds to the label in Lightning */
|
|
1179
1181
|
name;
|
|
1182
|
+
/** Project id. Must be url safe. May be derived from the name. NOT a UUID */
|
|
1183
|
+
id;
|
|
1180
1184
|
description;
|
|
1181
|
-
// array of version
|
|
1185
|
+
// array of version hashes
|
|
1182
1186
|
history = [];
|
|
1183
1187
|
workflows;
|
|
1184
1188
|
// option strings saved by the app
|
|
@@ -1191,11 +1195,6 @@ var Project = class {
|
|
|
1191
1195
|
openfn;
|
|
1192
1196
|
workspace;
|
|
1193
1197
|
config;
|
|
1194
|
-
// load a project from a state file (project.json)
|
|
1195
|
-
// or from a path (the file system)
|
|
1196
|
-
// TODO presumably we can detect a state file? Not a big deal?
|
|
1197
|
-
// collections for the project
|
|
1198
|
-
// TODO to be well typed
|
|
1199
1198
|
collections;
|
|
1200
1199
|
static from(type, data, options = {}) {
|
|
1201
1200
|
if (type === "state") {
|
|
@@ -1221,8 +1220,9 @@ var Project = class {
|
|
|
1221
1220
|
// maybe this second arg is config - like env, branch rules, serialisation rules
|
|
1222
1221
|
// stuff that's external to the actual project and managed by the repo
|
|
1223
1222
|
// TODO maybe the constructor is (data, Workspace)
|
|
1224
|
-
constructor(data,
|
|
1225
|
-
this.setConfig(
|
|
1223
|
+
constructor(data, config = {}) {
|
|
1224
|
+
this.setConfig(config);
|
|
1225
|
+
this.id = data.id ?? data.name ? slugify(data.name) : humanId({ separator: "-", capitalize: false });
|
|
1226
1226
|
this.name = data.name;
|
|
1227
1227
|
this.description = data.description;
|
|
1228
1228
|
this.openfn = data.openfn;
|
|
@@ -1241,16 +1241,9 @@ var Project = class {
|
|
|
1241
1241
|
}
|
|
1242
1242
|
throw new Error(`Cannot serialize ${type}`);
|
|
1243
1243
|
}
|
|
1244
|
-
//
|
|
1245
|
-
// stamp? id? sha?
|
|
1246
|
-
// this builds a version string for the current state
|
|
1247
|
-
getVersionHash() {
|
|
1248
|
-
}
|
|
1249
|
-
// what else might we need?
|
|
1250
|
-
// get workflow by name or id
|
|
1251
|
-
// this is fuzzy, but is that wrong?
|
|
1244
|
+
// get workflow by name, id or uuid
|
|
1252
1245
|
getWorkflow(idOrName) {
|
|
1253
|
-
return this.workflows.find((wf) => wf.id == idOrName) || this.workflows.find((wf) => wf.name === idOrName);
|
|
1246
|
+
return this.workflows.find((wf) => wf.id == idOrName) || this.workflows.find((wf) => wf.name === idOrName) || this.workflows.find((wf) => wf.openfn?.uuid === idOrName);
|
|
1254
1247
|
}
|
|
1255
1248
|
// it's the name of the project.yaml file
|
|
1256
1249
|
// qualified name? Remote name? App name?
|
|
@@ -1308,7 +1301,7 @@ function pathExists(fpath, type) {
|
|
|
1308
1301
|
var PROJECT_EXTENSIONS = [".yaml", ".yml"];
|
|
1309
1302
|
var Workspace = class {
|
|
1310
1303
|
config;
|
|
1311
|
-
|
|
1304
|
+
activeProject;
|
|
1312
1305
|
projects = [];
|
|
1313
1306
|
projectPaths = /* @__PURE__ */ new Map();
|
|
1314
1307
|
isValid = false;
|
|
@@ -1316,7 +1309,6 @@ var Workspace = class {
|
|
|
1316
1309
|
let context;
|
|
1317
1310
|
try {
|
|
1318
1311
|
const { type, content } = findWorkspaceFile(workspacePath);
|
|
1319
|
-
console.log(content);
|
|
1320
1312
|
context = loadWorkspaceFile(content, type);
|
|
1321
1313
|
this.isValid = true;
|
|
1322
1314
|
} catch (e) {
|
|
@@ -1324,7 +1316,7 @@ var Workspace = class {
|
|
|
1324
1316
|
return;
|
|
1325
1317
|
}
|
|
1326
1318
|
this.config = buildConfig(context.workspace);
|
|
1327
|
-
this.
|
|
1319
|
+
this.activeProject = context.project;
|
|
1328
1320
|
const projectsPath = path3.join(workspacePath, this.config.dirs.projects);
|
|
1329
1321
|
if (this.isValid && pathExists(projectsPath, "directory")) {
|
|
1330
1322
|
const stateFiles = fs3.readdirSync(projectsPath).filter(
|
|
@@ -1334,7 +1326,7 @@ var Workspace = class {
|
|
|
1334
1326
|
const stateFilePath = path3.join(projectsPath, file);
|
|
1335
1327
|
const data = fs3.readFileSync(stateFilePath, "utf-8");
|
|
1336
1328
|
const project = from_app_state_default(data, { format: "yaml" });
|
|
1337
|
-
this.projectPaths.set(project.
|
|
1329
|
+
this.projectPaths.set(project.id, stateFilePath);
|
|
1338
1330
|
return project;
|
|
1339
1331
|
}).filter((s) => s);
|
|
1340
1332
|
}
|
|
@@ -1349,15 +1341,15 @@ var Workspace = class {
|
|
|
1349
1341
|
list() {
|
|
1350
1342
|
return this.projects;
|
|
1351
1343
|
}
|
|
1352
|
-
|
|
1344
|
+
/** Get a project by its id or UUID */
|
|
1353
1345
|
get(id) {
|
|
1354
|
-
return this.projects.find((p) => p.
|
|
1346
|
+
return this.projects.find((p) => p.id === id) ?? this.projects.find((p) => p.openfn?.uuid === id);
|
|
1355
1347
|
}
|
|
1356
1348
|
getProjectPath(id) {
|
|
1357
1349
|
return this.projectPaths.get(id);
|
|
1358
1350
|
}
|
|
1359
1351
|
getActiveProject() {
|
|
1360
|
-
return this.projects.find((p) => p.
|
|
1352
|
+
return this.projects.find((p) => p.id === this.activeProject?.id) ?? this.projects.find((p) => p.openfn?.uuid === this.activeProject?.id);
|
|
1361
1353
|
}
|
|
1362
1354
|
// TODO this needs to return default values
|
|
1363
1355
|
// We should always rely on the workspace to load these values
|
|
@@ -1365,7 +1357,7 @@ var Workspace = class {
|
|
|
1365
1357
|
return this.config;
|
|
1366
1358
|
}
|
|
1367
1359
|
get activeProjectId() {
|
|
1368
|
-
return this.
|
|
1360
|
+
return this.activeProject?.id;
|
|
1369
1361
|
}
|
|
1370
1362
|
get valid() {
|
|
1371
1363
|
return this.isValid;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openfn/project",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.1",
|
|
4
4
|
"description": "Read, serialize, replicate and sync OpenFn projects",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -28,6 +28,7 @@
|
|
|
28
28
|
},
|
|
29
29
|
"dependencies": {
|
|
30
30
|
"glob": "^11.0.2",
|
|
31
|
+
"human-id": "^4.1.1",
|
|
31
32
|
"lodash": "^4.17.21",
|
|
32
33
|
"lodash-es": "^4.17.21",
|
|
33
34
|
"ohm-js": "^17.2.1",
|