Skip to content
Open
Show file tree
Hide file tree
Changes from 3 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
5 changes: 5 additions & 0 deletions .changeset/jsonld-schema-support.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"swagger-typescript-api": minor
---

Add JSON-LD schema support for generating TypeScript types from JSON-LD context and entity schemas
83 changes: 83 additions & 0 deletions src/configuration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,9 @@ export class CodeGenConfig {
httpClient: "",
routeTypes: "",
routeName: "",
jsonldContextDataContract: "",
jsonldEntityDataContract: "",
jsonldUtils: "",
};
schemaParsers: Record<string, (...args: unknown[]) => MonoSchemaParser> = {};
toJS = false;
Expand Down Expand Up @@ -180,6 +183,20 @@ export class CodeGenConfig {

successResponseStatusRange = [200, 299];

/** JSON-LD specific configuration options */
jsonLdOptions = {
/** Generate context interfaces */
generateContext: true,
/** Enforce strict JSON-LD typing */
strictTyping: false,
/** Prefix for entity interfaces */
entityPrefix: "",
/** Suffix for context interfaces */
contextSuffix: "Context",
/** Generate utility types for JSON-LD */
generateUtils: true,
};

extractingOptions: Partial<ExtractingOptions> = {
requestBodySuffix: ["Payload", "Body", "Input"],
requestParamsSuffix: ["Params"],
Expand Down Expand Up @@ -390,6 +407,18 @@ export class CodeGenConfig {
"relative-json-pointer": () => this.Ts.Keyword.String,
regex: () => this.Ts.Keyword.String,
},
// JSON-LD specific types
"jsonld-iri": () => this.Ts.Keyword.String,
"jsonld-literal": (schema) => this.getJsonLdLiteralType(schema),
"jsonld-node": () => "JsonLdNode",
"jsonld-context": () =>
this.Ts.UnionType([
this.Ts.Keyword.String,
this.Ts.Keyword.Object,
this.Ts.ArrayType(
this.Ts.UnionType([this.Ts.Keyword.String, this.Ts.Keyword.Object]),
),
]),
};

templateInfos = [
Expand All @@ -403,6 +432,15 @@ export class CodeGenConfig {
{ name: "httpClient", fileName: "http-client" },
{ name: "routeTypes", fileName: "route-types" },
{ name: "routeName", fileName: "route-name" },
{
name: "jsonldContextDataContract",
fileName: "jsonld-context-data-contract",
},
{
name: "jsonldEntityDataContract",
fileName: "jsonld-entity-data-contract",
},
{ name: "jsonldUtils", fileName: "jsonld-utils" },
];

templateExtensions = [".eta", ".ejs"];
Expand Down Expand Up @@ -439,6 +477,51 @@ export class CodeGenConfig {
this.componentTypeNameResolver = new ComponentTypeNameResolver(this, []);
}

/** Helper method to determine JSON-LD literal type */
getJsonLdLiteralType = (schema: any): string => {
if (schema && typeof schema === "object") {
// Check for @type in schema to determine literal type
if (schema["@type"]) {
const type = schema["@type"];
switch (type) {
case "xsd:string":
case "http://www.w3.org/2001/XMLSchema#string":
return this.Ts.Keyword.String;
case "xsd:integer":
case "xsd:int":
case "http://www.w3.org/2001/XMLSchema#integer":
case "http://www.w3.org/2001/XMLSchema#int":
return this.Ts.Keyword.Number;
case "xsd:boolean":
case "http://www.w3.org/2001/XMLSchema#boolean":
return this.Ts.Keyword.Boolean;
case "xsd:dateTime":
case "http://www.w3.org/2001/XMLSchema#dateTime":
return this.Ts.Keyword.String; // or Date if preferred
default:
return this.Ts.Keyword.String;
}
}

// Fallback to primitive type detection
if (schema.type) {
switch (schema.type) {
case "string":
return this.Ts.Keyword.String;
case "number":
case "integer":
return this.Ts.Keyword.Number;
case "boolean":
return this.Ts.Keyword.Boolean;
default:
return this.Ts.Keyword.String;
}
}
}

return this.Ts.Keyword.String;
};

update = (update: Partial<GenerateApiConfiguration["config"]>) => {
objectAssign(this, update);
};
Expand Down
3 changes: 3 additions & 0 deletions src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,4 +51,7 @@ export const SCHEMA_TYPES = {
COMPLEX_ALL_OF: "allOf",
COMPLEX_NOT: "not",
COMPLEX_UNKNOWN: "__unknown",
JSONLD_CONTEXT: "jsonld-context",
JSONLD_ENTITY: "jsonld-entity",
JSONLD_TYPE: "jsonld-type",
} as const;
Loading