1 // Copyright (C) The Arvados Authors. All rights reserved.
3 // SPDX-License-Identifier: AGPL-3.0
5 import { Resource, ResourceKind } from "./resource";
6 import { safeLoad } from 'js-yaml';
8 export interface WorkflowResource extends Resource {
9 kind: ResourceKind.WORKFLOW;
14 export interface WorkflowResourceDefinition {
16 $graph?: Array<Workflow | CommandLineTool>;
18 export interface Workflow {
22 inputs: CommandInputParameter[];
25 hints?: ProcessRequirement[];
28 export interface CommandLineTool {
29 class: 'CommandLineTool';
31 inputs: CommandInputParameter[];
33 hints?: ProcessRequirement[];
36 export type ProcessRequirement = GenericProcessRequirement | WorkflowRunnerResources;
38 export interface GenericProcessRequirement {
42 export interface WorkflowRunnerResources {
43 class: 'http://arvados.org/cwl#WorkflowRunnerResources';
47 acrContainerImage?: string;
50 export type CommandInputParameter =
51 BooleanCommandInputParameter |
52 IntCommandInputParameter |
53 LongCommandInputParameter |
54 FloatCommandInputParameter |
55 DoubleCommandInputParameter |
56 StringCommandInputParameter |
57 FileCommandInputParameter |
58 DirectoryCommandInputParameter |
59 StringArrayCommandInputParameter |
60 IntArrayCommandInputParameter |
61 FloatArrayCommandInputParameter |
62 FileArrayCommandInputParameter |
63 DirectoryArrayCommandInputParameter |
64 EnumCommandInputParameter;
75 DIRECTORY = 'Directory',
78 export interface CommandInputEnumSchema {
85 export interface CommandInputArraySchema<ItemType> {
91 export interface File {
98 export interface Directory {
99 class: CWLType.DIRECTORY;
105 export interface GenericCommandInputParameter<Type, Value> {
108 doc?: string | string[];
110 type?: Type | Array<Type | CWLType.NULL>;
114 export type GenericArrayCommandInputParameter<Type, Value> = GenericCommandInputParameter<CommandInputArraySchema<Type>, Value[]>;
116 export type BooleanCommandInputParameter = GenericCommandInputParameter<CWLType.BOOLEAN, boolean>;
117 export type IntCommandInputParameter = GenericCommandInputParameter<CWLType.INT, number>;
118 export type LongCommandInputParameter = GenericCommandInputParameter<CWLType.LONG, number>;
119 export type FloatCommandInputParameter = GenericCommandInputParameter<CWLType.FLOAT, number>;
120 export type DoubleCommandInputParameter = GenericCommandInputParameter<CWLType.DOUBLE, number>;
121 export type StringCommandInputParameter = GenericCommandInputParameter<CWLType.STRING, string>;
122 export type FileCommandInputParameter = GenericCommandInputParameter<CWLType.FILE, File>;
123 export type DirectoryCommandInputParameter = GenericCommandInputParameter<CWLType.DIRECTORY, Directory>;
124 export type EnumCommandInputParameter = GenericCommandInputParameter<CommandInputEnumSchema, string>;
126 export type StringArrayCommandInputParameter = GenericArrayCommandInputParameter<CWLType.STRING, string>;
127 export type IntArrayCommandInputParameter = GenericArrayCommandInputParameter<CWLType.INT, string>;
128 export type FloatArrayCommandInputParameter = GenericArrayCommandInputParameter<CWLType.FLOAT, string>;
129 export type FileArrayCommandInputParameter = GenericArrayCommandInputParameter<CWLType.FILE, File>;
130 export type DirectoryArrayCommandInputParameter = GenericArrayCommandInputParameter<CWLType.DIRECTORY, Directory>;
132 export type WorkflowInputsData = {
133 [key: string]: boolean | number | string | File | Directory;
135 export const parseWorkflowDefinition = (workflow: WorkflowResource): WorkflowResourceDefinition => {
136 const definition = safeLoad(workflow.definition);
140 export const getWorkflow = (workflowDefinition: WorkflowResourceDefinition) => {
141 if (!workflowDefinition.$graph) { return undefined; }
142 const mainWorkflow = workflowDefinition.$graph.find(item => item.class === 'Workflow' && item.id === '#main');
148 export const getWorkflowInputs = (workflowDefinition: WorkflowResourceDefinition) => {
149 if (!workflowDefinition) { return undefined; }
150 return getWorkflow(workflowDefinition)
151 ? getWorkflow(workflowDefinition)!.inputs
155 export const getInputLabel = (input: CommandInputParameter) => {
156 return `${input.label || input.id}`;
159 export const isRequiredInput = ({ type }: CommandInputParameter) => {
160 if (type instanceof Array) {
161 for (const t of type) {
162 if (t === CWLType.NULL) {
170 export const isPrimitiveOfType = (input: GenericCommandInputParameter<any, any>, type: CWLType) =>
171 input.type instanceof Array
172 ? input.type.indexOf(type) > -1
173 : input.type === type;
175 export const isArrayOfType = (input: GenericCommandInputParameter<any, any>, type: CWLType) =>
176 typeof input.type === 'object' &&
177 input.type.type === 'array'
178 ? input.type.items === type
181 export const stringifyInputType = ({ type }: CommandInputParameter) => {
182 if (typeof type === 'string') {
184 } else if (type instanceof Array) {
185 return type.join(' | ');
186 } else if (typeof type === 'object') {
187 if (type.type === 'enum') {
189 } else if (type.type === 'array') {
190 return `${type.items}[]`;