Skip to content

Commit

Permalink
Use JSON Schema $Ref Parser instead of JsonRefs
Browse files Browse the repository at this point in the history
JsonRefs isn't customizable enough to support all use cases concerning
references resolving. This commits removes JsonRefs and adds
JSON Schema $Ref Parser  to the core library.

JSON Schema $Ref Parser configuration is exposed via the 'init' action
similar to Ajv.

 * Remove JsonRefs from all packages
 * Copy 'findRefs' method of JsonRefs as JSON Schema $Ref Parser does
not provide a similar method
 * Adapt all testcases
 * Remove resources and resource-set from material-tree-renderer as they
were unused
  • Loading branch information
sdirix committed Mar 18, 2019
1 parent cb71f96 commit 7a0e03d
Show file tree
Hide file tree
Showing 21 changed files with 917 additions and 366 deletions.
105 changes: 27 additions & 78 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion packages/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,9 @@
},
"dependencies": {
"ajv": "^6.4.0",
"json-refs": "^3.0.10",
"json-schema-ref-parser": "^6.1.0",
"lodash": "^4.17.4",
"uri-js": "^4.2.2",
"uuid": "^3.2.1"
},
"peerDependencies": {
Expand Down
10 changes: 8 additions & 2 deletions packages/core/src/actions/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
THE SOFTWARE.
*/
import AJV from 'ajv';
import RefParser from 'json-schema-ref-parser';
import { RankedTester } from '../testers';
import { JsonSchema, UISchemaElement } from '../';
import { generateDefaultUISchema, generateJsonSchema } from '../generators';
Expand Down Expand Up @@ -64,20 +65,25 @@ export interface InitAction {
data: any;
schema: JsonSchema;
uischema: UISchemaElement;
options?: InitActionOptions | AJV.Ajv;
}

export interface InitActionOptions {
ajv?: AJV.Ajv;
refParserOptions?: RefParser.Options;
}

export const init = (
data: any,
schema: JsonSchema = generateJsonSchema(data),
uischema: UISchemaElement = generateDefaultUISchema(schema),
ajv?: AJV.Ajv
options?: InitActionOptions | AJV.Ajv
) => ({
type: INIT,
data,
schema,
uischema,
ajv
options
});

export interface RegisterDefaultDataAction {
Expand Down
52 changes: 48 additions & 4 deletions packages/core/src/reducers/core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,13 @@ import set from 'lodash/set';
import get from 'lodash/get';
import filter from 'lodash/filter';
import isEqual from 'lodash/isEqual';
import isFunction from 'lodash/isFunction';
import { Ajv, ErrorObject, ValidateFunction } from 'ajv';
import RefParser from 'json-schema-ref-parser';
import {
INIT,
InitAction,
InitActionOptions,
SET_AJV,
SET_SCHEMA,
SET_UISCHEMA,
Expand Down Expand Up @@ -68,6 +71,7 @@ export interface JsonFormsCore {
errors?: ErrorObject[];
validator?: ValidateFunction;
ajv?: Ajv;
refParserOptions?: RefParser.Options;
}

const initState: JsonFormsCore = {
Expand All @@ -76,7 +80,8 @@ const initState: JsonFormsCore = {
uischema: undefined,
errors: [],
validator: alwaysValid,
ajv: undefined
ajv: undefined,
refParserOptions: undefined
};

type ValidCoreActions =
Expand All @@ -87,15 +92,50 @@ type ValidCoreActions =
| SetUISchemaAction;

const getOrCreateAjv = (state: JsonFormsCore, action?: InitAction): Ajv => {
if (action && action.ajv) {
return action.ajv;
if (action) {
if (hasAjvOption(action.options)) {
// options object with ajv
return action.options.ajv;
} else if (
action.options !== undefined &&
!hasRefParserOption(action.options)
) {
// it is not an option object => should be ajv itself => check for compile function
if (isFunction(action.options.compile)) {
return action.options;
}
}
}
if (state.ajv) {
return state.ajv;
}
return createAjv();
};

const getRefParserOptions = (
state: JsonFormsCore,
action?: InitAction
): RefParser.Options => {
if (action && hasRefParserOption(action.options)) {
return action.options.refParserOptions;
}
return state.refParserOptions;
};

function hasRefParserOption(option: any): option is InitActionOptions {
if (option) {
return option.refParserOptions !== undefined;
}
return false;
}

function hasAjvOption(option: any): option is InitActionOptions {
if (option) {
return option.ajv !== undefined;
}
return false;
}

export const coreReducer = (
state: JsonFormsCore = initState,
action: ValidCoreActions
Expand All @@ -105,6 +145,7 @@ export const coreReducer = (
const thisAjv = getOrCreateAjv(state, action);
const v = thisAjv.compile(action.schema);
const e = sanitizeErrors(v, action.data);
const o = getRefParserOptions(state, action);

return {
...state,
Expand All @@ -113,7 +154,8 @@ export const coreReducer = (
uischema: action.uischema,
errors: e,
validator: v,
ajv: thisAjv
ajv: thisAjv,
refParserOptions: o
};
}
case SET_AJV: {
Expand Down Expand Up @@ -218,3 +260,5 @@ export const subErrorsAt = (instancePath: string, schema: JsonSchema) => (
error.dataPath.startsWith(path) && isEqual(error.parentSchema, schema)
);
};
export const extractRefParserOptions = (state: JsonFormsCore) =>
get(state, 'refParserOptions');
6 changes: 5 additions & 1 deletion packages/core/src/reducers/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
THE SOFTWARE.
*/
import get from 'lodash/get';
import RefParser from 'json-schema-ref-parser';
import {
defaultDataReducer,
extractDefaultData,
Expand All @@ -38,7 +39,8 @@ import {
extractData,
extractSchema,
extractUiSchema,
subErrorsAt
subErrorsAt,
extractRefParserOptions
} from './core';
import { JsonFormsState, JsonFormsSubStates } from '../store';
import {
Expand Down Expand Up @@ -79,6 +81,8 @@ export const getSchema = (state: JsonFormsState): JsonSchema =>
extractSchema(get(state, 'jsonforms.core'));
export const getUiSchema = (state: JsonFormsState): UISchemaElement =>
extractUiSchema(get(state, 'jsonforms.core'));
export const getRefParserOptions = (state: JsonFormsState): RefParser.Options =>
extractRefParserOptions(get(state, 'jsonforms.core'));
export const getDefaultData = (
state: JsonFormsState
): JsonFormsDefaultDataRegistryEntry[] =>
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/util/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ const Resolve: {
schema: resolveSchema,
data: resolveData
};
export { resolveData, resolveSchema } from './resolvers';
export { resolveData, resolveSchema, findRefs } from './resolvers';
export { Resolve };

// Paths --
Expand Down
Loading

0 comments on commit 7a0e03d

Please sign in to comment.