@samchon/openapi
Version:
OpenAPI definitions and converters for 'typia' and 'nestia'.
102 lines (94 loc) • 4.26 kB
JavaScript
import { LlmTypeCheckerV3 } from "../../utils/LlmTypeCheckerV3.mjs";
import { OpenApiTypeChecker } from "../../utils/OpenApiTypeChecker.mjs";
import { LlmParametersFinder } from "./LlmParametersComposer.mjs";
import { LlmSchemaV3Composer } from "./LlmSchemaV3Composer.mjs";
var GeminiSchemaComposer;
(function(GeminiSchemaComposer) {
GeminiSchemaComposer.IS_DEFS = false;
GeminiSchemaComposer.DEFAULT_CONFIG = {
recursive: 3
};
GeminiSchemaComposer.parameters = props => {
const entity = LlmParametersFinder.parameters({
...props,
method: "GeminiSchemaComposer.parameters"
});
if (entity.success === false) return entity;
return GeminiSchemaComposer.schema(props);
};
GeminiSchemaComposer.schema = props => {
const result = LlmSchemaV3Composer.schema({
...props,
config: {
recursive: props.config.recursive,
constraint: false
},
validate: (next, accessor) => {
if (OpenApiTypeChecker.isObject(next)) {
if (!!next.additionalProperties) return [ {
schema: next,
accessor: `${accessor}.additionalProperties`,
message: "Gemini does not allow additionalProperties."
} ];
} else if (OpenApiTypeChecker.isOneOf(next) && isOneOf(props.components)(next)) return [ {
schema: next,
accessor,
message: "Gemini does not allow union type."
} ];
return [];
}
});
if (result.success === false) return result;
LlmTypeCheckerV3.visit({
schema: result.value,
closure: v => {
if (v.title !== undefined) {
v.description = !!v.description?.length ? `${v.description}\n\n@title ${v.title}` : `@title ${v.title}`;
delete v.title;
}
if (LlmTypeCheckerV3.isObject(v) && v.additionalProperties !== undefined) {
delete v.additionalProperties;
}
}
});
return result;
};
GeminiSchemaComposer.separateParameters = props => {
const separated = LlmSchemaV3Composer.separateParameters(props);
return separated;
};
GeminiSchemaComposer.invert = props => LlmSchemaV3Composer.invert(props);
})(GeminiSchemaComposer || (GeminiSchemaComposer = {}));
const isOneOf = components => schema => {
const union = [];
const already = new Set;
const visit = schema => {
if (OpenApiTypeChecker.isBoolean(schema) || OpenApiTypeChecker.isInteger(schema) || OpenApiTypeChecker.isNumber(schema) || OpenApiTypeChecker.isString(schema)) union.push({
...schema
}); else if (OpenApiTypeChecker.isArray(schema) || OpenApiTypeChecker.isTuple(schema) || OpenApiTypeChecker.isObject(schema)) union.push(schema); else if (OpenApiTypeChecker.isOneOf(schema)) schema.oneOf.forEach(visit); else if (OpenApiTypeChecker.isReference(schema)) {
if (already.has(schema.$ref)) union.push(schema); else {
already.add(schema.$ref);
const target = components.schemas?.[schema.$ref.split("/").pop()];
if (target === undefined) union.push(schema); else visit(target);
}
}
};
const visitConstant = schema => {
const insert = value => {
const matched = union.find((u => u.type === typeof value));
if (matched !== undefined) {
matched.enum ?? (matched.enum = []);
matched.enum.push(value);
} else union.push({
type: typeof value,
enum: [ value ]
});
};
if (OpenApiTypeChecker.isConstant(schema)) insert(schema.const); else if (OpenApiTypeChecker.isOneOf(schema)) for (const u of schema.oneOf) if (OpenApiTypeChecker.isConstant(u)) insert(u.const);
};
visit(schema);
visitConstant(schema);
return union.length > 1;
};
export { GeminiSchemaComposer };
//# sourceMappingURL=GeminiSchemaComposer.mjs.map