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';
7 import { CommandOutputParameter } from "cwlts/mappings/v1.0/CommandOutputParameter";
9 export interface WorkflowResource extends Resource {
10 kind: ResourceKind.WORKFLOW;
15 export interface WorkflowResourceDefinition {
17 $graph?: Array<Workflow | CommandLineTool>;
19 export interface Workflow {
23 inputs: CommandInputParameter[];
26 hints?: ProcessRequirement[];
29 export interface CommandLineTool {
30 class: 'CommandLineTool';
32 inputs: CommandInputParameter[];
34 hints?: ProcessRequirement[];
37 export type ProcessRequirement = GenericProcessRequirement | WorkflowRunnerResources;
39 export interface GenericProcessRequirement {
43 export interface WorkflowRunnerResources {
44 class: 'http://arvados.org/cwl#WorkflowRunnerResources';
48 acrContainerImage?: string;
51 export type CommandInputParameter =
52 BooleanCommandInputParameter |
53 IntCommandInputParameter |
54 LongCommandInputParameter |
55 FloatCommandInputParameter |
56 DoubleCommandInputParameter |
57 StringCommandInputParameter |
58 FileCommandInputParameter |
59 DirectoryCommandInputParameter |
60 StringArrayCommandInputParameter |
61 IntArrayCommandInputParameter |
62 FloatArrayCommandInputParameter |
63 FileArrayCommandInputParameter |
64 DirectoryArrayCommandInputParameter |
65 EnumCommandInputParameter;
76 DIRECTORY = 'Directory',
79 export interface CommandInputEnumSchema {
86 export interface CommandInputArraySchema<ItemType> {
92 export interface File {
99 export interface Directory {
100 class: CWLType.DIRECTORY;
106 export interface GenericCommandInputParameter<Type, Value> {
109 doc?: string | string[];
111 type?: Type | Array<Type | CWLType.NULL>;
115 export type GenericArrayCommandInputParameter<Type, Value> = GenericCommandInputParameter<CommandInputArraySchema<Type>, Value[]>;
117 export type BooleanCommandInputParameter = GenericCommandInputParameter<CWLType.BOOLEAN, boolean>;
118 export type IntCommandInputParameter = GenericCommandInputParameter<CWLType.INT, number>;
119 export type LongCommandInputParameter = GenericCommandInputParameter<CWLType.LONG, number>;
120 export type FloatCommandInputParameter = GenericCommandInputParameter<CWLType.FLOAT, number>;
121 export type DoubleCommandInputParameter = GenericCommandInputParameter<CWLType.DOUBLE, number>;
122 export type StringCommandInputParameter = GenericCommandInputParameter<CWLType.STRING, string>;
123 export type FileCommandInputParameter = GenericCommandInputParameter<CWLType.FILE, File>;
124 export type DirectoryCommandInputParameter = GenericCommandInputParameter<CWLType.DIRECTORY, Directory>;
125 export type EnumCommandInputParameter = GenericCommandInputParameter<CommandInputEnumSchema, string>;
127 export type StringArrayCommandInputParameter = GenericArrayCommandInputParameter<CWLType.STRING, string>;
128 export type IntArrayCommandInputParameter = GenericArrayCommandInputParameter<CWLType.INT, string>;
129 export type FloatArrayCommandInputParameter = GenericArrayCommandInputParameter<CWLType.FLOAT, string>;
130 export type FileArrayCommandInputParameter = GenericArrayCommandInputParameter<CWLType.FILE, File>;
131 export type DirectoryArrayCommandInputParameter = GenericArrayCommandInputParameter<CWLType.DIRECTORY, Directory>;
133 export type WorkflowInputsData = {
134 [key: string]: boolean | number | string | File | Directory;
136 export const parseWorkflowDefinition = (workflow: WorkflowResource): WorkflowResourceDefinition => {
137 const definition = safeLoad(workflow.definition);
141 export const getWorkflow = (workflowDefinition: WorkflowResourceDefinition) => {
142 if (!workflowDefinition.$graph) { return undefined; }
143 const mainWorkflow = workflowDefinition.$graph.find(item => item.id === '#main');
149 export const getWorkflowInputs = (workflowDefinition: WorkflowResourceDefinition) => {
150 if (!workflowDefinition) { return undefined; }
151 return getWorkflow(workflowDefinition)
152 ? getWorkflow(workflowDefinition)!.inputs
156 export const getWorkflowOutputs = (workflowDefinition: WorkflowResourceDefinition) => {
157 if (!workflowDefinition) { return undefined; }
158 return getWorkflow(workflowDefinition)
159 ? getWorkflow(workflowDefinition)!.outputs
163 export const getInputLabel = (input: CommandInputParameter) => {
164 return `${input.label || input.id.split('/').pop()}`;
167 export const getIOParamId = (input: CommandInputParameter | CommandOutputParameter) => {
168 return `${input.id.split('/').pop()}`;
171 export const isRequiredInput = ({ type }: CommandInputParameter) => {
172 if (type instanceof Array) {
173 for (const t of type) {
174 if (t === CWLType.NULL) {
182 export const isPrimitiveOfType = (input: GenericCommandInputParameter<any, any>, type: CWLType) =>
183 input.type instanceof Array
184 ? input.type.indexOf(type) > -1
185 : input.type === type;
187 export const isArrayOfType = (input: GenericCommandInputParameter<any, any>, type: CWLType) =>
188 input.type instanceof Array
189 ? (input.type.filter(t => typeof t === 'object' &&
190 t.type === 'array' &&
191 t.items === type).length > 0)
192 : (typeof input.type === 'object' &&
193 input.type.type === 'array' &&
194 input.type.items === type);
196 export const getEnumType = (input: GenericCommandInputParameter<any, any>) => {
197 if (input.type instanceof Array) {
198 const f = input.type.filter(t => typeof t === 'object' &&
199 !(t instanceof Array) &&
205 if ((typeof input.type === 'object' &&
206 !(input.type instanceof Array) &&
207 input.type.type === 'enum')) {
214 export const stringifyInputType = ({ type }: CommandInputParameter) => {
215 if (typeof type === 'string') {
217 } else if (type instanceof Array) {
218 return type.join(' | ');
219 } else if (typeof type === 'object') {
220 if (type.type === 'enum') {
222 } else if (type.type === 'array') {
223 return `${type.items}[]`;