Skip to content

Commit

Permalink
Changing how we generate our AJV instance
Browse files Browse the repository at this point in the history
Looping over the annotation enum properly
Checking for pointers properly
  • Loading branch information
travjenkins committed Nov 26, 2024
1 parent 9973289 commit 77c8293
Show file tree
Hide file tree
Showing 5 changed files with 56 additions and 25 deletions.
4 changes: 2 additions & 2 deletions src/components/shared/Entity/EndpointConfig/Form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { jsonFormsPadding } from 'context/Theme';
import { isEmpty } from 'lodash';
import { useMemo } from 'react';
import { FormattedMessage } from 'react-intl';
import { setDefaultsValidator } from 'services/ajv';
import { customAjv } from 'services/ajv';
import { custom_generateDefaultUISchema } from 'services/jsonforms';
import defaultRenderers from 'services/jsonforms/defaultRenderers';
import { defaultOptions } from 'services/jsonforms/shared';
Expand Down Expand Up @@ -73,7 +73,7 @@ function EndpointConfigForm({ readOnly }: Props) {
readonly={readOnly || isActive}
validationMode="ValidateAndShow"
onChange={setEndpointConfig}
ajv={setDefaultsValidator}
ajv={customAjv}
/>
{endpointCanBeEmpty ? (
<AlertBox short severity="info">
Expand Down
6 changes: 3 additions & 3 deletions src/pages/dev/TestJsonForms.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import { GlobalSearchParams } from 'hooks/searchParams/useGlobalSearchParams';
import { useMemo, useState } from 'react';
import { useIntl } from 'react-intl';
import { useUnmount } from 'react-use';
import { setDefaultsValidator } from 'services/ajv';
import { customAjv } from 'services/ajv';
import { custom_generateDefaultUISchema } from 'services/jsonforms';
import defaultRenderers from 'services/jsonforms/defaultRenderers';
import { defaultOptions } from 'services/jsonforms/shared';
Expand Down Expand Up @@ -178,7 +178,7 @@ const TestJsonForms = () => {
searchParams.toString();
}
}}
ajv={setDefaultsValidator}
ajv={customAjv}
/>

<Editor
Expand Down Expand Up @@ -216,7 +216,7 @@ const TestJsonForms = () => {
state
);
}}
ajv={setDefaultsValidator}
ajv={customAjv}
/>
) : (
<>
Expand Down
52 changes: 40 additions & 12 deletions src/services/ajv.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { createAjv, JsonSchema } from '@jsonforms/core';
import { createAjv } from '@jsonforms/core';
import { isEmpty } from 'lodash';
import { Annotations } from 'types/jsonforms';
import { stripPathing } from 'utils/misc-utils';
Expand Down Expand Up @@ -33,7 +33,7 @@ export const addKeywords = (ajv: Ajv) => {

// How to write a config schema
// https://github.com/estuary/connectors/blob/main/config_schema_guidelines.md
for (const annotation in Annotations) {
for (const annotation of Object.values(Annotations)) {
if (typeof annotation === 'string') {
ajv.addKeyword(annotation);
}
Expand All @@ -42,14 +42,10 @@ export const addKeywords = (ajv: Ajv) => {
return ajv;
};

// eslint-disable-next-line func-names
export const setDefaultsValidator = (function () {
const ajv = createAjv(defaultAjvSettings);
return addKeywords(ajv);
})();
export const customAjv = addKeywords(createAjv(defaultAjvSettings));

function setJSONFormDefaults(jsonSchema: any, formData: any) {
const hydrateAndValidate = setDefaultsValidator.compile(jsonSchema);
const hydrateAndValidate = customAjv.compile(jsonSchema);

hydrateAndValidate(formData);

Expand Down Expand Up @@ -118,8 +114,40 @@ export function createJSONFormDefaults(
return { data, errors };
}

export const schemaSupportsDeltaUpdates = (schema: JsonSchema): boolean =>
Object.hasOwn(schema, Annotations.deltaUpdates);
export interface ResourceConfigPointers {
[Annotations.defaultResourceConfigName]?: boolean;
[Annotations.targetSchema]?: boolean;
[Annotations.deltaUpdates]?: boolean;
}

export const findKeysInObject = (
obj: Record<string, any>,
keysToFind: string[],
results: ResourceConfigPointers = {}
): ResourceConfigPointers => {
// Iterate over each key in the object
for (const key in obj) {
if (obj.hasOwnProperty(key)) {
const value = obj[key];

// Check if the key is one of the keys we're searching for
if (keysToFind.includes(key)) {
results[key] = value;
}

// If the value is an object, recurse into it
if (value && typeof value === 'object') {
findKeysInObject(value, keysToFind, results);
}
}
}

return results;
};

export const schemaSupportsTargetSchema = (schema: JsonSchema): boolean =>
Object.hasOwn(schema, Annotations.targetSchema);
export const getResourceConfigPointers = (schema: any) =>
findKeysInObject(schema, [
Annotations.defaultResourceConfigName,
Annotations.targetSchema,
Annotations.deltaUpdates,
]);
4 changes: 2 additions & 2 deletions src/services/jsonforms/defaults.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { materialCells } from '@jsonforms/material-renderers';
import { setDefaultsValidator } from 'services/ajv';
import { customAjv } from 'services/ajv';
import defaultRenderers from './defaultRenderers';
import { defaultOptions } from './shared';

export const jsonFormsDefaults = {
renderers: defaultRenderers,
cells: materialCells,
config: defaultOptions,
ajv: setDefaultsValidator,
ajv: customAjv,
};
15 changes: 9 additions & 6 deletions src/stores/Binding/Store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,7 @@ import {
} from 'lodash';
import {
createJSONFormDefaults,
schemaSupportsDeltaUpdates,
schemaSupportsTargetSchema,
getResourceConfigPointers,
} from 'services/ajv';
import { logRocketEvent } from 'services/shared';
import { BASE_ERROR } from 'services/supabase';
Expand Down Expand Up @@ -920,10 +919,14 @@ const getInitialState = (
// normally set stuff in a store. However, it does return array of
// properties.
// Might not be horrible to run through the objects twice
state.sourceCaptureDeltaUpdatesSupported =
schemaSupportsDeltaUpdates(resolved);
state.sourceCaptureDeltaUpdatesSupported =
schemaSupportsTargetSchema(resolved);
const pointers = getResourceConfigPointers(resolved);

state.sourceCaptureDeltaUpdatesSupported = Boolean(
pointers['x-delta-updates']
);
state.sourceCaptureTargetSchemaSupported = Boolean(
pointers['x-schema-name']
);
}),
false,
'Resource Schema Set'
Expand Down

0 comments on commit 77c8293

Please sign in to comment.