Files
windmill/frontend/src/lib/inferArgSig.ts
T

193 lines
5.0 KiB
TypeScript

import type { SchemaProperty } from './common'
export function argSigToJsonSchemaType(
t:
| string
| { resource: string | null }
| {
list:
| (string | { object: { key: string; typ: any }[] })
| { str: any }
| { object: { key: string; typ: any }[] }
| null
}
| { dynselect: string }
| { str: string[] | null }
| { object: { key: string; typ: any }[] }
| {
oneof: [
{
label: string
properties: { key: string; typ: any }[]
}
]
},
oldS: SchemaProperty
): void {
const newS: SchemaProperty = { type: '' }
if (t === 'int') {
newS.type = 'integer'
} else if (t === 'float') {
newS.type = 'number'
} else if (t === 'bool') {
newS.type = 'boolean'
} else if (t === 'email') {
newS.type = 'string'
newS.format = 'email'
} else if (t === 'sql') {
newS.type = 'string'
newS.format = 'sql'
} else if (t === 'yaml') {
newS.type = 'string'
newS.format = 'yaml'
} else if (t === 'bytes') {
newS.type = 'string'
newS.contentEncoding = 'base64'
newS.originalType = 'bytes'
} else if (t === 'datetime') {
newS.type = 'string'
newS.format = 'date-time'
} else if (typeof t !== 'string' && 'oneof' in t) {
newS.type = 'object'
if (t.oneof) {
newS.oneOf = t.oneof.map((obj) => {
const oldObjS = oldS.oneOf?.find((o) => o?.title === obj.label) ?? undefined
const properties: Record<string, any> = {}
for (const prop of obj.properties) {
if (oldObjS?.properties && prop.key in oldObjS?.properties) {
properties[prop.key] = oldObjS?.properties[prop.key]
} else {
properties[prop.key] = { description: '', type: '' }
}
argSigToJsonSchemaType(prop.typ, properties[prop.key])
}
return {
type: 'object',
title: obj.label,
properties,
order: oldObjS?.order ?? undefined
}
})
}
} else if (typeof t !== 'string' && `object` in t) {
newS.type = 'object'
if (t.object) {
const properties: Record<string, any> = {}
for (const prop of t.object) {
if (oldS.properties && prop.key in oldS.properties) {
properties[prop.key] = oldS.properties[prop.key]
} else {
properties[prop.key] = { description: '', type: '' }
}
argSigToJsonSchemaType(prop.typ, properties[prop.key])
}
newS.properties = properties
}
} else if (typeof t !== 'string' && `str` in t) {
newS.type = 'string'
if (t.str) {
newS.originalType = 'enum'
newS.enum = t.str
} else if (oldS.originalType == 'string' && oldS.enum) {
newS.originalType = 'string'
newS.enum = oldS.enum
} else {
newS.originalType = 'string'
newS.enum = undefined
}
} else if (typeof t !== 'string' && `resource` in t) {
newS.type = 'object'
newS.format = `resource-${t.resource}`
} else if (typeof t !== 'string' && `dynselect` in t) {
newS.type = 'object'
newS.format = `dynselect-${t.dynselect}`
} else if (typeof t !== 'string' && `list` in t) {
newS.type = 'array'
if (t.list === 'int' || t.list === 'float') {
newS.items = { type: 'number' }
} else if (t.list === 'bytes') {
newS.items = { type: 'string', contentEncoding: 'base64' }
} else if (t.list == 'string') {
newS.items = { type: 'string' }
} else if (t.list && typeof t.list == 'object' && 'str' in t.list) {
newS.items = { type: 'string', enum: t.list.str }
} else if (t.list && typeof t.list == 'object' && 'resource' in t.list && t.list.resource) {
newS.items = {
type: 'resource',
resourceType: t.list.resource as string
}
} else if (
t.list &&
typeof t.list == 'object' &&
'object' in t.list &&
t.list.object &&
t.list.object.length > 0
) {
const properties: Record<string, any> = {}
for (const prop of t.list.object) {
properties[prop.key] = { description: '', type: '' }
argSigToJsonSchemaType(prop.typ, properties[prop.key])
}
newS.items = { type: 'object', properties: properties }
} else {
newS.items = { type: 'object' }
}
} else {
newS.type = 'object'
}
const preservedFields = [
'description',
'pattern',
'min',
'max',
'currency',
'currencyLocale',
'multiselect',
'customErrorMessage',
'required',
'showExpr',
'password',
'order',
'dateFormat',
'title',
'placeholder'
]
preservedFields.forEach((field) => {
// @ts-ignore
if (oldS[field] !== undefined) {
// @ts-ignore
newS[field] = oldS[field]
}
})
if (oldS.type != newS.type) {
for (const prop of Object.getOwnPropertyNames(newS)) {
if (prop != 'description') {
// @ts-ignore
delete oldS[prop]
}
}
} else if ((oldS.format == 'date' || oldS.format === 'date-time') && newS.format == 'string') {
newS.format = oldS.format
} else if (newS.format == 'date-time' && oldS.format == 'date') {
newS.format = 'date'
} else if (oldS.items?.type != newS.items?.type) {
delete oldS.items
}
Object.assign(oldS, newS)
// if (sameItems && savedItems != undefined && savedItems.enum != undefined) {
// sendUserToast(JSON.stringify(savedItems))
// oldS.items = savedItems
// }
if (oldS.format?.startsWith('resource-') && newS.type != 'object') {
oldS.format = undefined
}
}