Skip to content

Commit

Permalink
changed upsert to differentiate between null and undefined
Browse files Browse the repository at this point in the history
  • Loading branch information
stefanfaistenauer committed Mar 6, 2025
1 parent f1ea480 commit 14ad177
Showing 1 changed file with 51 additions and 44 deletions.
95 changes: 51 additions & 44 deletions packages/core/graphql/resolvers/upsert.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
import { ApiConfig, Context, ExtractConfig, TransformConfig } from "@superglue/shared";
import { GraphQLResolveInfo } from "graphql";

function resolveField<T>(newValue: T | null | undefined, oldValue: T | undefined, defaultValue?: T): T | undefined {
if (newValue === null) return undefined;
if (newValue !== undefined) return newValue;
if (oldValue !== undefined) return oldValue;
return defaultValue;
}

export const upsertApiResolver = async (
_: any,
{ id, input }: { id: string; input: ApiConfig },
Expand All @@ -10,7 +17,6 @@ export const upsertApiResolver = async (
if(!id) {
throw new Error("id is required");
}
// override id with the id from the input
const oldConfig = await context.datastore.getApiConfig(id, context.orgId);

if(!input.urlHost && !oldConfig?.urlHost) {
Expand All @@ -19,38 +25,39 @@ export const upsertApiResolver = async (
if(!input.instruction && !oldConfig?.instruction) {
throw new Error("instruction is required");
}
// reset the response mapping if there are major updates
let newResponseMapping = input.responseMapping;
const hasNoUpdates = (!input?.urlHost || oldConfig?.urlHost === input?.urlHost) &&
(!input?.urlPath || oldConfig?.urlPath === input?.urlPath) &&
(!input?.dataPath || oldConfig?.dataPath === input?.dataPath) &&
(!input?.body || oldConfig?.body === input?.body) &&
(!input?.queryParams || oldConfig?.queryParams === input?.queryParams) &&
(!input?.headers || oldConfig?.headers === input?.headers) &&
(!input?.responseSchema || oldConfig?.responseSchema === input?.responseSchema) &&
(!input?.instruction || oldConfig?.instruction === input?.instruction);

// Handle response mapping with existing logic
let newResponseMapping = resolveField(input.responseMapping, oldConfig?.responseMapping);
const hasNoUpdates = (input.urlHost === undefined || oldConfig?.urlHost === input.urlHost) &&
(input.urlPath === undefined || oldConfig?.urlPath === input.urlPath) &&
(input.dataPath === undefined || oldConfig?.dataPath === input.dataPath) &&
(input.body === undefined || oldConfig?.body === input.body) &&
(input.queryParams === undefined || oldConfig?.queryParams === input.queryParams) &&
(input.headers === undefined || oldConfig?.headers === input.headers) &&
(input.responseSchema === undefined || oldConfig?.responseSchema === input.responseSchema) &&
(input.instruction === undefined || oldConfig?.instruction === input.instruction);
if (!newResponseMapping && hasNoUpdates) {
newResponseMapping = oldConfig?.responseMapping;
}

const config = {
urlHost: input.urlHost || oldConfig?.urlHost || '',
urlPath: input.urlPath || oldConfig?.urlPath || '',
instruction: input.instruction || oldConfig?.instruction || '',
createdAt: input.createdAt || oldConfig?.createdAt || new Date(),
urlHost: resolveField(input.urlHost, oldConfig?.urlHost, ''),
urlPath: resolveField(input.urlPath, oldConfig?.urlPath, ''),
instruction: resolveField(input.instruction, oldConfig?.instruction, ''),
createdAt: resolveField(input.createdAt, oldConfig?.createdAt, new Date()),
updatedAt: new Date(),
id: id,
method: input.method || oldConfig?.method,
queryParams: input.queryParams || oldConfig?.queryParams,
headers: input.headers || oldConfig?.headers,
body: input.body || oldConfig?.body,
documentationUrl: input.documentationUrl || oldConfig?.documentationUrl,
responseSchema: input.responseSchema || oldConfig?.responseSchema,
method: resolveField(input.method, oldConfig?.method),
queryParams: resolveField(input.queryParams, oldConfig?.queryParams),
headers: resolveField(input.headers, oldConfig?.headers),
body: resolveField(input.body, oldConfig?.body),
documentationUrl: resolveField(input.documentationUrl, oldConfig?.documentationUrl),
responseSchema: resolveField(input.responseSchema, oldConfig?.responseSchema),
responseMapping: newResponseMapping,
authentication: input.authentication || oldConfig?.authentication,
pagination: input.pagination || oldConfig?.pagination,
dataPath: input.dataPath || oldConfig?.dataPath,
version: input.version || oldConfig?.version
authentication: resolveField(input.authentication, oldConfig?.authentication),
pagination: resolveField(input.pagination, oldConfig?.pagination),
dataPath: resolveField(input.dataPath, oldConfig?.dataPath),
version: resolveField(input.version, oldConfig?.version)
};
await context.datastore.upsertApiConfig(id, config, context.orgId);
return config;
Expand All @@ -68,19 +75,19 @@ export const upsertTransformResolver = async (
const oldConfig = await context.datastore.getTransformConfig(id, context.orgId);

// reset the response mapping if there are major updates
let newResponseMapping = input.responseMapping;
let newResponseMapping = resolveField(input.responseMapping, oldConfig?.responseMapping);
if (!newResponseMapping && !input.responseSchema && !input.instruction) {
newResponseMapping = oldConfig?.responseMapping;
}

const config = {
id: id,
updatedAt: new Date(),
createdAt: oldConfig?.createdAt || new Date(),
instruction: input.instruction || oldConfig?.instruction || '',
responseSchema: input.responseSchema || oldConfig?.responseSchema || {},
createdAt: resolveField(input.createdAt, oldConfig?.createdAt, new Date()),
instruction: resolveField(input.instruction, oldConfig?.instruction, ''),
responseSchema: resolveField(input.responseSchema, oldConfig?.responseSchema, {}),
responseMapping: newResponseMapping,
version: input.version || oldConfig?.version
version: resolveField(input.version, oldConfig?.version)
};
await context.datastore.upsertTransformConfig(id, config, context.orgId);
return config;
Expand All @@ -98,21 +105,21 @@ export const upsertExtractResolver = async (
const oldConfig = await context.datastore.getExtractConfig(id, context.orgId);
const config = {
id: id,
urlHost: input.urlHost || oldConfig?.urlHost || '',
urlPath: input.urlPath || oldConfig?.urlPath || '',
instruction: input.instruction || oldConfig?.instruction || '',
createdAt: oldConfig?.createdAt || new Date(),
urlHost: resolveField(input.urlHost, oldConfig?.urlHost, ''),
urlPath: resolveField(input.urlPath, oldConfig?.urlPath, ''),
instruction: resolveField(input.instruction, oldConfig?.instruction, ''),
createdAt: resolveField(input.createdAt, oldConfig?.createdAt, new Date()),
updatedAt: new Date(),
method: input.method || oldConfig?.method,
queryParams: input.queryParams || oldConfig?.queryParams,
headers: input.headers || oldConfig?.headers,
body: input.body || oldConfig?.body,
documentationUrl: input.documentationUrl || oldConfig?.documentationUrl,
decompressionMethod: input.decompressionMethod || oldConfig?.decompressionMethod,
authentication: input.authentication || oldConfig?.authentication,
fileType: input.fileType || oldConfig?.fileType,
dataPath: input.dataPath || oldConfig?.dataPath,
version: input.version || oldConfig?.version
method: resolveField(input.method, oldConfig?.method),
queryParams: resolveField(input.queryParams, oldConfig?.queryParams),
headers: resolveField(input.headers, oldConfig?.headers),
body: resolveField(input.body, oldConfig?.body),
documentationUrl: resolveField(input.documentationUrl, oldConfig?.documentationUrl),
decompressionMethod: resolveField(input.decompressionMethod, oldConfig?.decompressionMethod),
authentication: resolveField(input.authentication, oldConfig?.authentication),
fileType: resolveField(input.fileType, oldConfig?.fileType),
dataPath: resolveField(input.dataPath, oldConfig?.dataPath),
version: resolveField(input.version, oldConfig?.version)
};
await context.datastore.upsertExtractConfig(id, config, context.orgId);
return config;
Expand Down

0 comments on commit 14ad177

Please sign in to comment.