Fix antigravity
This commit is contained in:
parent
f2ca6f0dc5
commit
8c37b39eed
2 changed files with 27 additions and 77 deletions
|
|
@ -99,70 +99,30 @@ export function generateProjectId() {
|
||||||
return `${adj}-${noun}-${crypto.randomUUID().slice(0, 5)}`;
|
return `${adj}-${noun}-${crypto.randomUUID().slice(0, 5)}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Helper: Walk recursively through object/array and collect all paths for a given key
|
// Helper: Remove unsupported keywords recursively from object/array
|
||||||
function walkAndCollectPaths(obj, currentPath, targetKey, paths) {
|
function removeUnsupportedKeywords(obj, keywords) {
|
||||||
if (!obj || typeof obj !== "object") return;
|
if (!obj || typeof obj !== "object") return;
|
||||||
|
|
||||||
if (Array.isArray(obj)) {
|
if (Array.isArray(obj)) {
|
||||||
obj.forEach((item, index) => {
|
for (const item of obj) {
|
||||||
const newPath = currentPath ? `${currentPath}[${index}]` : `[${index}]`;
|
removeUnsupportedKeywords(item, keywords);
|
||||||
walkAndCollectPaths(item, newPath, targetKey, paths);
|
}
|
||||||
});
|
|
||||||
} else {
|
} else {
|
||||||
for (const [key, value] of Object.entries(obj)) {
|
// Delete unsupported keys at current level
|
||||||
const newPath = currentPath ? `${currentPath}.${key}` : key;
|
for (const keyword of keywords) {
|
||||||
|
if (keyword in obj) {
|
||||||
if (key === targetKey) {
|
delete obj[keyword];
|
||||||
paths.push(newPath);
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
// Recurse into remaining values
|
||||||
|
for (const value of Object.values(obj)) {
|
||||||
if (value && typeof value === "object") {
|
if (value && typeof value === "object") {
|
||||||
walkAndCollectPaths(value, newPath, targetKey, paths);
|
removeUnsupportedKeywords(value, keywords);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Helper: Get value at path
|
|
||||||
function getAtPath(obj, path) {
|
|
||||||
const parts = path.split(".");
|
|
||||||
let current = obj;
|
|
||||||
for (const part of parts) {
|
|
||||||
if (!current || typeof current !== "object") return undefined;
|
|
||||||
current = current[part];
|
|
||||||
}
|
|
||||||
return current;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Helper: Set value at path
|
|
||||||
function setAtPath(obj, path, value) {
|
|
||||||
const parts = path.split(".");
|
|
||||||
let current = obj;
|
|
||||||
|
|
||||||
for (let i = 0; i < parts.length - 1; i++) {
|
|
||||||
const part = parts[i];
|
|
||||||
if (!current[part]) current[part] = {};
|
|
||||||
current = current[part];
|
|
||||||
}
|
|
||||||
|
|
||||||
current[parts[parts.length - 1]] = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Helper: Delete a key at a specific path in nested object
|
|
||||||
function deleteAtPath(obj, path) {
|
|
||||||
const parts = path.split(".");
|
|
||||||
let current = obj;
|
|
||||||
|
|
||||||
for (let i = 0; i < parts.length - 1; i++) {
|
|
||||||
const part = parts[i];
|
|
||||||
if (!current[part]) return;
|
|
||||||
current = current[part];
|
|
||||||
}
|
|
||||||
|
|
||||||
const lastKey = parts[parts.length - 1];
|
|
||||||
delete current[lastKey];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Convert const to enum
|
// Convert const to enum
|
||||||
function convertConstToEnum(obj) {
|
function convertConstToEnum(obj) {
|
||||||
if (!obj || typeof obj !== "object") return;
|
if (!obj || typeof obj !== "object") return;
|
||||||
|
|
@ -307,8 +267,8 @@ function flattenTypeArrays(obj) {
|
||||||
export function cleanJSONSchemaForAntigravity(schema) {
|
export function cleanJSONSchemaForAntigravity(schema) {
|
||||||
if (!schema || typeof schema !== "object") return schema;
|
if (!schema || typeof schema !== "object") return schema;
|
||||||
|
|
||||||
// Deep clone to avoid mutating original
|
// Mutate directly (schema is only used once per request)
|
||||||
let cleaned = JSON.parse(JSON.stringify(schema));
|
let cleaned = schema;
|
||||||
|
|
||||||
// Phase 1: Convert and prepare
|
// Phase 1: Convert and prepare
|
||||||
convertConstToEnum(cleaned);
|
convertConstToEnum(cleaned);
|
||||||
|
|
@ -319,18 +279,8 @@ export function cleanJSONSchemaForAntigravity(schema) {
|
||||||
flattenAnyOfOneOf(cleaned);
|
flattenAnyOfOneOf(cleaned);
|
||||||
flattenTypeArrays(cleaned);
|
flattenTypeArrays(cleaned);
|
||||||
|
|
||||||
// Phase 3: Remove all unsupported keywords at ALL levels
|
// Phase 3: Remove all unsupported keywords at ALL levels (including inside arrays)
|
||||||
for (const keyword of UNSUPPORTED_SCHEMA_CONSTRAINTS) {
|
removeUnsupportedKeywords(cleaned, UNSUPPORTED_SCHEMA_CONSTRAINTS);
|
||||||
const paths = [];
|
|
||||||
walkAndCollectPaths(cleaned, "", keyword, paths);
|
|
||||||
|
|
||||||
// Sort by depth (deepest first) to avoid path invalidation
|
|
||||||
paths.sort((a, b) => b.split(".").length - a.split(".").length);
|
|
||||||
|
|
||||||
for (const path of paths) {
|
|
||||||
deleteAtPath(cleaned, path);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Phase 4: Cleanup required fields recursively
|
// Phase 4: Cleanup required fields recursively
|
||||||
function cleanupRequired(obj) {
|
function cleanupRequired(obj) {
|
||||||
|
|
|
||||||
|
|
@ -135,16 +135,16 @@ function ProviderCard({ providerId, provider, stats }) {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Link href={`/dashboard/providers/${providerId}`}>
|
<Link href={`/dashboard/providers/${providerId}`}>
|
||||||
<Card className="h-full hover:border-primary/50 transition-colors cursor-pointer">
|
<Card padding="sm" className="h-full hover:border-primary/50 transition-colors cursor-pointer">
|
||||||
<div className="flex items-center justify-between">
|
<div className="flex items-center justify-between">
|
||||||
<div className="flex items-center gap-3">
|
<div className="flex items-center gap-3">
|
||||||
<div
|
<div
|
||||||
className="size-10 rounded-lg flex items-center justify-center"
|
className="size-8 rounded-lg flex items-center justify-center"
|
||||||
style={{ backgroundColor: `${provider.color}15` }}
|
style={{ backgroundColor: `${provider.color}15` }}
|
||||||
>
|
>
|
||||||
{imgError ? (
|
{imgError ? (
|
||||||
<span
|
<span
|
||||||
className="text-sm font-bold"
|
className="text-xs font-bold"
|
||||||
style={{ color: provider.color }}
|
style={{ color: provider.color }}
|
||||||
>
|
>
|
||||||
{provider.textIcon || provider.id.slice(0, 2).toUpperCase()}
|
{provider.textIcon || provider.id.slice(0, 2).toUpperCase()}
|
||||||
|
|
@ -153,10 +153,10 @@ function ProviderCard({ providerId, provider, stats }) {
|
||||||
<Image
|
<Image
|
||||||
src={`/providers/${provider.id}.png`}
|
src={`/providers/${provider.id}.png`}
|
||||||
alt={provider.name}
|
alt={provider.name}
|
||||||
width={40}
|
width={32}
|
||||||
height={40}
|
height={32}
|
||||||
className="object-contain rounded-lg max-w-[40px] max-h-[40px]"
|
className="object-contain rounded-lg max-w-[32px] max-h-[32px]"
|
||||||
sizes="40px"
|
sizes="32px"
|
||||||
onError={() => setImgError(true)}
|
onError={() => setImgError(true)}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|
@ -200,15 +200,15 @@ function ApiKeyProviderCard({ providerId, provider, stats }) {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Link href={`/dashboard/providers/${providerId}`}>
|
<Link href={`/dashboard/providers/${providerId}`}>
|
||||||
<Card className="h-full hover:border-primary/50 transition-colors cursor-pointer">
|
<Card padding="sm" className="h-full hover:border-primary/50 transition-colors cursor-pointer">
|
||||||
<div className="flex items-center justify-between">
|
<div className="flex items-center justify-between">
|
||||||
<div className="flex items-center gap-3">
|
<div className="flex items-center gap-3">
|
||||||
<div
|
<div
|
||||||
className="size-10 rounded-lg flex items-center justify-center"
|
className="size-8 rounded-lg flex items-center justify-center"
|
||||||
style={{ backgroundColor: `${provider.color}15` }}
|
style={{ backgroundColor: `${provider.color}15` }}
|
||||||
>
|
>
|
||||||
<span
|
<span
|
||||||
className="text-sm font-bold"
|
className="text-xs font-bold"
|
||||||
style={{ color: provider.color }}
|
style={{ color: provider.color }}
|
||||||
>
|
>
|
||||||
{provider.textIcon || provider.id.slice(0, 2).toUpperCase()}
|
{provider.textIcon || provider.id.slice(0, 2).toUpperCase()}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue