Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: support $ref when converting json schema to ATD #112

Merged
merged 5 commits into from
Nov 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 13 additions & 4 deletions tooling/json-schema-to-jtd/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,13 @@
"name": "json-schema-to-jtd",
"version": "0.65.2",
"license": "MIT",
"author": { "name": "joshmossas", "url": "https://github.com/joshmossas" },
"bugs": { "url": "https://github.com/modiimedia/arri/issues" },
"author": {
"name": "joshmossas",
"url": "https://github.com/joshmossas"
},
"bugs": {
"url": "https://github.com/modiimedia/arri/issues"
},
"repository": {
"type": "git",
"url": "https://github.com/modiimedia/arri.git",
Expand All @@ -13,6 +18,10 @@
"main": "./dist/index.cjs",
"module": "./dist/index.mjs",
"types": "./dist/index.d.ts",
"files": ["dist"],
"dependencies": { "jtd-utils": "workspace:*" }
"files": [
"dist"
],
"dependencies": {
"jtd-utils": "workspace:*"
}
}
75 changes: 64 additions & 11 deletions tooling/json-schema-to-jtd/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,31 +12,44 @@ import {
isJsonSchemaEnum,
isJsonSchemaObject,
isJsonSchemaRecord,
isJsonSchemaRef,
isJsonSchemaScalarType,
type JsonSchemaArray,
type JsonSchemaEnum,
type JsonSchemaObject,
type JsonSchemaRecord,
JsonSchemaRef,
type JsonSchemaScalarType,
type JsonSchemaType,
} from "./models";
export * from "./models";

export function jsonSchemaToJtdSchema(input: JsonSchemaType): Schema {
export interface JsonSchemaContext {
parentRefs: string[];
rootSchema?: any;
}

export function jsonSchemaToJtdSchema(
input: JsonSchemaType,
context: JsonSchemaContext = { parentRefs: [] },
): Schema {
if (isJsonSchemaScalarType(input)) {
return jsonSchemaScalarToJtdScalar(input);
return jsonSchemaScalarToJtdScalar(input, context);
}
if (isJsonSchemaEnum(input)) {
return jsonSchemaEnumToJtdEnum(input);
return jsonSchemaEnumToJtdEnum(input, context);
}
if (isJsonSchemaObject(input)) {
return jsonSchemaObjectToJtdObject(input);
return jsonSchemaObjectToJtdObject(input, context);
}
if (isJsonSchemaArray(input)) {
return jsonSchemaArrayToJtdArray(input);
return jsonSchemaArrayToJtdArray(input, context);
}
if (isJsonSchemaRecord(input)) {
return jsonSchemaRecordToJtdRecord(input);
return jsonSchemaRecordToJtdRecord(input, context);
}
if (isJsonSchemaRef(input)) {
return jsonSchemaRefToJtdRef(input, context);
}

console.warn(
Expand All @@ -53,7 +66,10 @@ export function jsonSchemaToJtdSchema(input: JsonSchemaType): Schema {
} satisfies SchemaFormEmpty;
}

export function jsonSchemaEnumToJtdEnum(input: JsonSchemaEnum): Schema {
export function jsonSchemaEnumToJtdEnum(
input: JsonSchemaEnum,
_: JsonSchemaContext,
): Schema {
const enumTypes = input.anyOf.map((val) => val.type);
const isNotStringEnum =
enumTypes.includes("integer") || enumTypes.includes("number");
Expand All @@ -76,6 +92,7 @@ export function jsonSchemaEnumToJtdEnum(input: JsonSchemaEnum): Schema {

export function jsonSchemaScalarToJtdScalar(
input: JsonSchemaScalarType,
_: JsonSchemaContext,
): Schema {
const meta = {
id: input.$id ?? input.title,
Expand Down Expand Up @@ -113,7 +130,10 @@ export function jsonSchemaScalarToJtdScalar(
}
}

export function jsonSchemaObjectToJtdObject(input: JsonSchemaObject): Schema {
export function jsonSchemaObjectToJtdObject(
input: JsonSchemaObject,
_: JsonSchemaContext,
): Schema {
const result: SchemaFormProperties = {
properties: {},
strict:
Expand Down Expand Up @@ -145,7 +165,10 @@ export function jsonSchemaObjectToJtdObject(input: JsonSchemaObject): Schema {
return result;
}

export function jsonSchemaArrayToJtdArray(input: JsonSchemaArray) {
export function jsonSchemaArrayToJtdArray(
input: JsonSchemaArray,
_: JsonSchemaContext,
) {
const result: SchemaFormElements = {
elements: jsonSchemaToJtdSchema(input.items),
metadata: {
Expand All @@ -156,7 +179,10 @@ export function jsonSchemaArrayToJtdArray(input: JsonSchemaArray) {
return result;
}

export function jsonSchemaRecordToJtdRecord(input: JsonSchemaRecord): Schema {
export function jsonSchemaRecordToJtdRecord(
input: JsonSchemaRecord,
_: JsonSchemaContext,
): Schema {
const types: Schema[] = [];
Object.keys(input.patternProperties).forEach((key) => {
const pattern = input.patternProperties[key];
Expand All @@ -172,7 +198,6 @@ export function jsonSchemaRecordToJtdRecord(input: JsonSchemaRecord): Schema {
return {};
}
const result: SchemaFormValues = {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
values: types[0]!,
metadata: {
id: input.$id ?? input.title,
Expand All @@ -181,3 +206,31 @@ export function jsonSchemaRecordToJtdRecord(input: JsonSchemaRecord): Schema {
};
return result;
}

export function jsonSchemaRefToJtdRef(
input: JsonSchemaRef,
context: JsonSchemaContext,
): Schema {
if (context.parentRefs.includes(input.$ref)) {
const parts = input.$ref.split("/");
const refId = parts[parts.length - 1];
if (!refId) return {};
return {
ref: refId,
};
}
const parts = input.$ref.split("/");
let subSchema = context.rootSchema ?? {};
for (const part of parts) {
if (part === "#") continue;
if (!subSchema[part]) return {};
subSchema = subSchema[part];
}
const r = context.parentRefs;
r.push(input.$ref);
const result = jsonSchemaToJtdSchema(subSchema, {
...context,
parentRefs: r,
});
return result;
}
13 changes: 11 additions & 2 deletions tooling/json-schema-to-jtd/src/models.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ export function isJsonSchemaScalarType(
if (!("type" in input)) {
return false;
}
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument

return JsonSchemaScalarTypeValues.includes(input.type as any);
}

Expand All @@ -56,7 +56,7 @@ export function isJsonSchemaNullType(input: any): input is JsonSchemaNullType {
if (!("type" in input)) {
return false;
}
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument

return JsonSchemaNullTypeValues.includes(input.type);
}

Expand Down Expand Up @@ -145,3 +145,12 @@ export function isJsonSchemaEnum(input: any): input is JsonSchemaEnum {
}
return true;
}
export interface JsonSchemaRef extends JsonSchemaTypeBase {
$ref: string;
}
export function isJsonSchemaRef(input: unknown): input is JsonSchemaRef {
if (typeof input !== "object" || !input) {
return false;
}
return "$ref" in input && typeof input.$ref === "string";
}
Loading