Add workflow definition parser
[arvados-workbench2.git] / src / models / workflow.ts
1 // Copyright (C) The Arvados Authors. All rights reserved.
2 //
3 // SPDX-License-Identifier: AGPL-3.0
4
5 import { Resource, ResourceKind } from "./resource";
6 import { safeLoad } from 'js-yaml';
7
8 export interface WorkflowResource extends Resource {
9     kind: ResourceKind.WORKFLOW;
10     name: string;
11     description: string;
12     definition: string;
13 }
14 export interface WorkflowResoruceDefinition {
15     cwlVersion: string;
16     $graph: Array<Workflow | CommandLineTool>;
17 }
18 export interface Workflow {
19     class: 'Workflow';
20     doc?: string;
21     id?: string;
22     inputs: CommandInputParameter[];
23     outputs: any[];
24     steps: any[];
25 }
26
27 export interface CommandLineTool {
28     class: 'CommandLineTool';
29     id: string;
30     inputs: CommandInputParameter[];
31     outputs: any[];
32 }
33
34 export interface CommandInputParameter {
35     id: string;
36     label?: string;
37     doc?: string | string[];
38     default?: any;
39     type?: CWLType | CWLType[] | CommandInputEnumSchema | CommandInputArraySchema;
40 }
41
42 export enum CWLType {
43     NULL = 'null',
44     BOOLEAN = 'boolean',
45     INT = 'int',
46     LONG = 'long',
47     FLOAT = 'float',
48     DOUBLE = 'double',
49     STRING = 'string',
50     FILE = 'File',
51     DIRECTORY = 'Directory',
52 }
53
54 export interface CommandInputEnumSchema {
55     symbols: string[];
56     type: 'enum';
57     label?: string;
58     name?: string;
59 }
60
61 export interface CommandInputArraySchema {
62     items: CWLType;
63     type: 'array';
64     label?: string;
65 }
66
67 export interface File {
68     class: CWLType.FILE;
69     location?: string;
70     path?: string;
71     basename?: string;
72 }
73
74 export interface Directory {
75     class: CWLType.DIRECTORY;
76     location?: string;
77     path?: string;
78     basename?: string;
79 }
80
81 export const parseWorkflowDefinition = (workflow: WorkflowResource): WorkflowResoruceDefinition => {
82     const definition = safeLoad(workflow.definition);
83     return definition;
84 };
85
86 export const getWorkflowInputs = (workflowDefinition: WorkflowResoruceDefinition) => {
87     const mainWorkflow = workflowDefinition.$graph.find(item => item.class === 'Workflow' && item.id === '#main');
88     return mainWorkflow
89         ? mainWorkflow.inputs
90         : undefined;
91 };
92
93 export const stringifyInputType = ({ type }: CommandInputParameter) => {
94     if (typeof type === 'string') {
95         return type;
96     } else if (type instanceof Array) {
97         return type.join(' | ');
98     } else if (typeof type === 'object') {
99         if (type.type === 'enum') {
100             return 'enum';
101         } else if (type.type === 'array') {
102             return `${type.items}[]`;
103         } else {
104             return 'unknown';
105         }
106     } else {
107         return 'unknown';
108     }
109 };