mirror of
https://github.com/invoke-ai/InvokeAI
synced 2024-08-30 20:32:17 +00:00
fix(ui): fix enum parsing for optional enums
Closes #5121 - Parse `anyOf` for enums (present when they are optional) - Consolidate `FieldTypeParseError` and `UnsupportedFieldTypeError` into `FieldParseError` (there was no difference in handling and it simplifies things a bit)
This commit is contained in:
parent
3e01c396e1
commit
a6d4e4ed57
@ -978,6 +978,7 @@
|
||||
"unsupportedAnyOfLength": "too many union members ({{count}})",
|
||||
"unsupportedMismatchedUnion": "mismatched CollectionOrScalar type with base types {{firstType}} and {{secondType}}",
|
||||
"unableToParseFieldType": "unable to parse field type",
|
||||
"unableToExtractEnumOptions": "unable to extract enum options",
|
||||
"uNetField": "UNet",
|
||||
"uNetFieldDescription": "UNet submodel.",
|
||||
"unhandledInputProperty": "Unhandled input property",
|
||||
|
@ -43,10 +43,10 @@ export class NodeUpdateError extends Error {
|
||||
}
|
||||
|
||||
/**
|
||||
* FieldTypeParseError
|
||||
* FieldParseError
|
||||
* Raised when a field cannot be parsed from a field schema.
|
||||
*/
|
||||
export class FieldTypeParseError extends Error {
|
||||
export class FieldParseError extends Error {
|
||||
/**
|
||||
* Create FieldTypeParseError
|
||||
* @param {String} message
|
||||
@ -56,18 +56,3 @@ export class FieldTypeParseError extends Error {
|
||||
this.name = this.constructor.name;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* UnsupportedFieldTypeError
|
||||
* Raised when an unsupported field type is parsed.
|
||||
*/
|
||||
export class UnsupportedFieldTypeError extends Error {
|
||||
/**
|
||||
* Create UnsupportedFieldTypeError
|
||||
* @param {String} message
|
||||
*/
|
||||
constructor(message: string) {
|
||||
super(message);
|
||||
this.name = this.constructor.name;
|
||||
}
|
||||
}
|
||||
|
@ -23,7 +23,12 @@ import {
|
||||
VAEModelFieldInputTemplate,
|
||||
isStatefulFieldType,
|
||||
} from 'features/nodes/types/field';
|
||||
import { InvocationFieldSchema } from 'features/nodes/types/openapi';
|
||||
import {
|
||||
InvocationFieldSchema,
|
||||
isSchemaObject,
|
||||
} from 'features/nodes/types/openapi';
|
||||
import { t } from 'i18next';
|
||||
import { FieldParseError } from 'features/nodes/types/error';
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
type FieldInputTemplateBuilder<T extends FieldInputTemplate = any> = // valid `any`!
|
||||
@ -321,7 +326,28 @@ const buildImageFieldInputTemplate: FieldInputTemplateBuilder<
|
||||
const buildEnumFieldInputTemplate: FieldInputTemplateBuilder<
|
||||
EnumFieldInputTemplate
|
||||
> = ({ schemaObject, baseField, isCollection, isCollectionOrScalar }) => {
|
||||
const options = schemaObject.enum ?? [];
|
||||
let options: EnumFieldInputTemplate['options'] = [];
|
||||
if (schemaObject.anyOf) {
|
||||
const filteredAnyOf = schemaObject.anyOf.filter((i) => {
|
||||
if (isSchemaObject(i)) {
|
||||
if (i.type === 'null') {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
});
|
||||
const firstAnyOf = filteredAnyOf[0];
|
||||
if (filteredAnyOf.length !== 1 || !isSchemaObject(firstAnyOf)) {
|
||||
options = [];
|
||||
} else {
|
||||
options = firstAnyOf.enum ?? [];
|
||||
}
|
||||
} else {
|
||||
options = schemaObject.enum ?? [];
|
||||
}
|
||||
if (options.length === 0) {
|
||||
throw new FieldParseError(t('nodes.unableToExtractEnumOptions'));
|
||||
}
|
||||
const template: EnumFieldInputTemplate = {
|
||||
...baseField,
|
||||
type: {
|
||||
|
@ -1,10 +1,4 @@
|
||||
import { t } from 'i18next';
|
||||
import { isArray } from 'lodash-es';
|
||||
import { OpenAPIV3_1 } from 'openapi-types';
|
||||
import {
|
||||
FieldTypeParseError,
|
||||
UnsupportedFieldTypeError,
|
||||
} from 'features/nodes/types/error';
|
||||
import { FieldParseError } from 'features/nodes/types/error';
|
||||
import { FieldType } from 'features/nodes/types/field';
|
||||
import {
|
||||
OpenAPIV3_1SchemaOrRef,
|
||||
@ -14,6 +8,9 @@ import {
|
||||
isRefObject,
|
||||
isSchemaObject,
|
||||
} from 'features/nodes/types/openapi';
|
||||
import { t } from 'i18next';
|
||||
import { isArray } from 'lodash-es';
|
||||
import { OpenAPIV3_1 } from 'openapi-types';
|
||||
|
||||
/**
|
||||
* Transforms an invocation output ref object to field type.
|
||||
@ -70,7 +67,7 @@ export const parseFieldType = (
|
||||
// This is a single ref type
|
||||
const name = refObjectToSchemaName(allOf[0]);
|
||||
if (!name) {
|
||||
throw new FieldTypeParseError(
|
||||
throw new FieldParseError(
|
||||
t('nodes.unableToExtractSchemaNameFromRef')
|
||||
);
|
||||
}
|
||||
@ -95,7 +92,7 @@ export const parseFieldType = (
|
||||
if (isRefObject(filteredAnyOf[0])) {
|
||||
const name = refObjectToSchemaName(filteredAnyOf[0]);
|
||||
if (!name) {
|
||||
throw new FieldTypeParseError(
|
||||
throw new FieldParseError(
|
||||
t('nodes.unableToExtractSchemaNameFromRef')
|
||||
);
|
||||
}
|
||||
@ -120,7 +117,7 @@ export const parseFieldType = (
|
||||
|
||||
if (filteredAnyOf.length !== 2) {
|
||||
// This is a union of more than 2 types, which we don't support
|
||||
throw new UnsupportedFieldTypeError(
|
||||
throw new FieldParseError(
|
||||
t('nodes.unsupportedAnyOfLength', {
|
||||
count: filteredAnyOf.length,
|
||||
})
|
||||
@ -167,7 +164,7 @@ export const parseFieldType = (
|
||||
};
|
||||
}
|
||||
|
||||
throw new UnsupportedFieldTypeError(
|
||||
throw new FieldParseError(
|
||||
t('nodes.unsupportedMismatchedUnion', {
|
||||
firstType,
|
||||
secondType,
|
||||
@ -186,7 +183,7 @@ export const parseFieldType = (
|
||||
if (isSchemaObject(schemaObject.items)) {
|
||||
const itemType = schemaObject.items.type;
|
||||
if (!itemType || isArray(itemType)) {
|
||||
throw new UnsupportedFieldTypeError(
|
||||
throw new FieldParseError(
|
||||
t('nodes.unsupportedArrayItemType', {
|
||||
type: itemType,
|
||||
})
|
||||
@ -196,7 +193,7 @@ export const parseFieldType = (
|
||||
const name = OPENAPI_TO_FIELD_TYPE_MAP[itemType];
|
||||
if (!name) {
|
||||
// it's 'null', 'object', or 'array' - skip
|
||||
throw new UnsupportedFieldTypeError(
|
||||
throw new FieldParseError(
|
||||
t('nodes.unsupportedArrayItemType', {
|
||||
type: itemType,
|
||||
})
|
||||
@ -212,7 +209,7 @@ export const parseFieldType = (
|
||||
// This is a ref object, extract the type name
|
||||
const name = refObjectToSchemaName(schemaObject.items);
|
||||
if (!name) {
|
||||
throw new FieldTypeParseError(
|
||||
throw new FieldParseError(
|
||||
t('nodes.unableToExtractSchemaNameFromRef')
|
||||
);
|
||||
}
|
||||
@ -226,7 +223,7 @@ export const parseFieldType = (
|
||||
const name = OPENAPI_TO_FIELD_TYPE_MAP[schemaObject.type];
|
||||
if (!name) {
|
||||
// it's 'null', 'object', or 'array' - skip
|
||||
throw new UnsupportedFieldTypeError(
|
||||
throw new FieldParseError(
|
||||
t('nodes.unsupportedArrayItemType', {
|
||||
type: schemaObject.type,
|
||||
})
|
||||
@ -242,9 +239,7 @@ export const parseFieldType = (
|
||||
} else if (isRefObject(schemaObject)) {
|
||||
const name = refObjectToSchemaName(schemaObject);
|
||||
if (!name) {
|
||||
throw new FieldTypeParseError(
|
||||
t('nodes.unableToExtractSchemaNameFromRef')
|
||||
);
|
||||
throw new FieldParseError(t('nodes.unableToExtractSchemaNameFromRef'));
|
||||
}
|
||||
return {
|
||||
name,
|
||||
@ -252,5 +247,5 @@ export const parseFieldType = (
|
||||
isCollectionOrScalar: false,
|
||||
};
|
||||
}
|
||||
throw new FieldTypeParseError(t('nodes.unableToParseFieldType'));
|
||||
throw new FieldParseError(t('nodes.unableToParseFieldType'));
|
||||
};
|
||||
|
@ -1,12 +1,6 @@
|
||||
import { logger } from 'app/logging/logger';
|
||||
import { parseify } from 'common/util/serialize';
|
||||
import { t } from 'i18next';
|
||||
import { reduce } from 'lodash-es';
|
||||
import { OpenAPIV3_1 } from 'openapi-types';
|
||||
import {
|
||||
FieldTypeParseError,
|
||||
UnsupportedFieldTypeError,
|
||||
} from 'features/nodes/types/error';
|
||||
import { FieldParseError } from 'features/nodes/types/error';
|
||||
import {
|
||||
FieldInputTemplate,
|
||||
FieldOutputTemplate,
|
||||
@ -18,6 +12,9 @@ import {
|
||||
isInvocationOutputSchemaObject,
|
||||
isInvocationSchemaObject,
|
||||
} from 'features/nodes/types/openapi';
|
||||
import { t } from 'i18next';
|
||||
import { reduce } from 'lodash-es';
|
||||
import { OpenAPIV3_1 } from 'openapi-types';
|
||||
import { buildFieldInputTemplate } from './buildFieldInputTemplate';
|
||||
import { buildFieldOutputTemplate } from './buildFieldOutputTemplate';
|
||||
import { parseFieldType } from './parseFieldType';
|
||||
@ -133,10 +130,7 @@ export const parseSchema = (
|
||||
|
||||
inputsAccumulator[propertyName] = fieldInputTemplate;
|
||||
} catch (e) {
|
||||
if (
|
||||
e instanceof FieldTypeParseError ||
|
||||
e instanceof UnsupportedFieldTypeError
|
||||
) {
|
||||
if (e instanceof FieldParseError) {
|
||||
logger('nodes').warn(
|
||||
{
|
||||
node: type,
|
||||
@ -225,10 +219,7 @@ export const parseSchema = (
|
||||
|
||||
outputsAccumulator[propertyName] = fieldOutputTemplate;
|
||||
} catch (e) {
|
||||
if (
|
||||
e instanceof FieldTypeParseError ||
|
||||
e instanceof UnsupportedFieldTypeError
|
||||
) {
|
||||
if (e instanceof FieldParseError) {
|
||||
logger('nodes').warn(
|
||||
{
|
||||
node: type,
|
||||
|
Loading…
Reference in New Issue
Block a user