Skip to content

Commit faaab90

Browse files
Merge pull request #3 from NHSDigital/add-json-parser
Added new schema reference package
2 parents 7c3e316 + 3f21770 commit faaab90

File tree

5 files changed

+31
-105
lines changed

5 files changed

+31
-105
lines changed

.github/workflows/release.yml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,17 @@ jobs:
2727
- name: Install deps
2828
run: pnpm i
2929

30+
- name: Create .npmrc for GitHub Packages
31+
run: |
32+
cat <<EOF > ~/.npmrc
33+
@nhsdigital:registry=https://npm.pkg.github.com
34+
//npm.pkg.github.com/:_authToken=${GITHUB_TOKEN}
35+
always-auth=true
36+
registry=https://registry.npmjs.org/
37+
EOF
38+
env:
39+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
40+
3041
- name: Create Release Pull Request or Publish to npm
3142
uses: changesets/action@master
3243
with:

.npmrc

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1 @@
11
strict-peer-dependencies=false
2-
3-
@nhsdigital:registry=https://npm.pkg.github.com
4-
//npm.pkg.github.com/:_authToken=${GITHUB_TOKEN}
5-
always-auth=true

eventcatalog/src/components/SchemaExplorer/JSONSchemaViewer.tsx

Lines changed: 4 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { useState, useEffect, useRef, useMemo } from 'react';
2+
import $RefParser from '@apidevtools/json-schema-ref-parser';
23

34
interface JSONSchemaViewerProps {
45
schema: any;
@@ -100,107 +101,10 @@ function mergeAllOfSchemas(schemaWithProcessor: any): any {
100101
return mergedSchema;
101102
}
102103

103-
function processSchema(schema: any, rootSchema?: any): any {
104+
async function processSchema(schema: any, rootSchema?: any): Promise<any> {
104105
if (!schema) return schema;
105-
106-
const root = rootSchema || schema;
107-
108-
// Handle $ref
109-
if (schema.$ref) {
110-
const refPath = schema.$ref;
111-
let resolvedSchema = null;
112-
let defName = '';
113-
114-
// Try draft-7 style first: #/definitions/
115-
if (refPath.startsWith('#/definitions/')) {
116-
defName = refPath.replace('#/definitions/', '');
117-
if (root.definitions && root.definitions[defName]) {
118-
resolvedSchema = root.definitions[defName];
119-
}
120-
}
121-
// Try 2020-12 style: #/$defs/
122-
else if (refPath.startsWith('#/$defs/')) {
123-
defName = refPath.replace('#/$defs/', '');
124-
if (root.$defs && root.$defs[defName]) {
125-
resolvedSchema = root.$defs[defName];
126-
}
127-
}
128-
// Try other common patterns
129-
else if (refPath.startsWith('#/components/schemas/')) {
130-
defName = refPath.replace('#/components/schemas/', '');
131-
if (root.components && root.components.schemas && root.components.schemas[defName]) {
132-
resolvedSchema = root.components.schemas[defName];
133-
}
134-
}
135-
136-
if (resolvedSchema) {
137-
const processedSchema = processSchema(resolvedSchema, root);
138-
return {
139-
...processedSchema,
140-
_refPath: refPath,
141-
_refName: defName,
142-
_originalRef: schema.$ref,
143-
};
144-
}
145-
146-
return {
147-
type: 'string',
148-
description: `Reference to ${refPath} (definition not found in root schema)`,
149-
title: defName || refPath.split('/').pop(),
150-
_refPath: refPath,
151-
_refName: defName,
152-
_refNotFound: true,
153-
};
154-
}
155-
156-
if (schema.allOf) {
157-
return mergeAllOfSchemas({ ...schema, processSchema: (s: any) => processSchema(s, root) });
158-
}
159-
160-
if (schema.oneOf) {
161-
const processedVariants = schema.oneOf.map((variant: any) => {
162-
const processedVariant = processSchema(variant, root);
163-
return {
164-
title: processedVariant.title || variant.title || 'Unnamed Variant',
165-
required: processedVariant.required || variant.required || [],
166-
properties: processedVariant.properties || {},
167-
...processedVariant,
168-
};
169-
});
170-
171-
const allProperties: Record<string, any> = {};
172-
processedVariants.forEach((variant: any) => {
173-
if (variant.properties) {
174-
Object.assign(allProperties, variant.properties);
175-
}
176-
});
177-
178-
return {
179-
...schema,
180-
type: schema.type || 'object',
181-
properties: {
182-
...(schema.properties || {}),
183-
...allProperties,
184-
},
185-
variants: processedVariants,
186-
};
187-
}
188-
189-
// Process nested schemas in properties
190-
if (schema.properties) {
191-
const processedProperties: Record<string, any> = {};
192-
Object.entries(schema.properties).forEach(([key, prop]: [string, any]) => {
193-
processedProperties[key] = processSchema(prop, root);
194-
});
195-
schema = { ...schema, properties: processedProperties };
196-
}
197-
198-
// Process array items
199-
if (schema.type === 'array' && schema.items) {
200-
schema = { ...schema, items: processSchema(schema.items, root) };
201-
}
202-
203-
return schema;
106+
let dereferencedSchema = await $RefParser.dereference(schema);
107+
return dereferencedSchema;
204108
}
205109

206110
// SchemaProperty component

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
"@ai-sdk/google": "^2.0.17",
5151
"@ai-sdk/openai": "^2.0.42",
5252
"@ai-sdk/react": "^2.0.60",
53+
"@apidevtools/json-schema-ref-parser": "^15.1.3",
5354
"@astrojs/markdown-remark": "^6.3.9",
5455
"@astrojs/mdx": "^4.3.12",
5556
"@astrojs/node": "^9.5.1",

pnpm-lock.yaml

Lines changed: 15 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)