From 2c8aaf7422add19172c8b052e9311d5fb504d3da Mon Sep 17 00:00:00 2001 From: Benjamin Eckel Date: Tue, 15 Oct 2024 14:25:05 -0500 Subject: [PATCH] Refactor casting (#30) Refactors casting a bit. Fixes a bug where arrays were not being cast correctly. I think this won't really scale to more complex types and we should consider a dependency to handle this or code up a more runtime dependent solution. But for now i'm aiming to get it working well for the simple cases. Still have some tests to do. --- template/src/pdk.ts.ejs | 52 ++++++++++++++++++++++++++++++---------- tests/schemas/fruit.yaml | 5 ++++ 2 files changed, 45 insertions(+), 12 deletions(-) diff --git a/template/src/pdk.ts.ejs b/template/src/pdk.ts.ejs index 5ca6792..f1f2a17 100644 --- a/template/src/pdk.ts.ejs +++ b/template/src/pdk.ts.ejs @@ -2,6 +2,30 @@ const hostFunctions = Host.getFunctions() <% } %> +function isNull(v: any): boolean { + return v === undefined || v === null +} + +function cast(caster: (v: any) => any, v: any): any { + if (isNull(v)) return v + if (Array.isArray(v)) return v.map(caster) + return caster(v) +} + +function dateToJson(v: Date): string { + return v.toISOString() +} +function dateFromJson(v: string): Date { + return new Date(v) +} + +function bufferToJson(v: ArrayBuffer): string { + return Host.arrayBufferToBase64(v) +} +function bufferFromJson(v: string): ArrayBuffer { + return Host.base64ToArrayBuffer(v) +} + <% Object.values(schema.schemas).forEach(schema => { %> <% if (schema.properties.length > 0) { %> @@ -24,12 +48,14 @@ export class <%- schema.name %> { return { ...obj, <% schema.properties.forEach(p => { -%> - <% if (isDateTime(p)) { -%> - <%- p.name -%>: obj.<%- p.name -%> === undefined || obj.<%- p.name -%> === null ? obj.<%- p.name %> : new Date(obj.<%- p.name -%>), - <% } else if (isBuffer(p)) {-%> - <%- p.name -%>: obj.<%- p.name -%> === undefined || obj.<%- p.name -%> === null ? obj.<%- p.name %> : Host.base64ToArrayBuffer(obj.<%- p.name -%>), - <% } else if (!isPrimitive(p)) {-%> - <%- p.name -%>: obj.<%- p.name -%> === undefined || obj.<%- p.name -%> === null ? obj.<%- p.name %> : <%- p.$ref.name %>.fromJson(obj.<%- p.name -%>), + <% let baseP = p.items ? p.items : p -%> + <% let baseRef = p.$ref ? p.$ref.name : (p.items && p.items.$ref ? p.items.$ref.name : null) -%> + <% if (isDateTime(baseP)) { -%> + <%- p.name -%>: cast(dateFromJson, obj.<%- p.name -%>), + <% } else if (isBuffer(baseP)) {-%> + <%- p.name -%>: cast(bufferFromJson, obj.<%- p.name -%>), + <% } else if (!isPrimitive(baseP)) {-%> + <%- p.name -%>: cast(<%- baseRef -%>.fromJson, obj.<%- p.name -%>), <% } -%> <% }) -%> } @@ -39,12 +65,14 @@ export class <%- schema.name %> { return { ...obj, <% schema.properties.forEach(p => { -%> - <% if (p.type === "string" && p.format === "date-time") { -%> - <%- p.name -%>: obj.<%- p.name -%> === undefined || obj.<%- p.name -%> === null ? obj.<%- p.name %> : obj.<%- p.name %>.toISOString(), - <% } else if (isBuffer(p)) {-%> - <%- p.name -%>: obj.<%- p.name -%> === undefined || obj.<%- p.name -%> === null ? obj.<%- p.name %> : Host.arrayBufferToBase64(obj.<%- p.name -%>), - <% } else if (p.$ref && !p.$ref.enum) {-%> - <%- p.name -%>: obj.<%- p.name -%> === undefined || obj.<%- p.name -%> === null ? obj.<%- p.name %>: <%- p.$ref.name %>.toJson(obj.<%- p.name -%>) , + <% let baseP = p.items ? p.items : p -%> + <% let baseRef = p.$ref ? p.$ref.name : (p.items && p.items.$ref ? p.items.$ref.name : null) -%> + <% if (isDateTime(baseP)) { -%> + <%- p.name -%>: cast(dateToJson, obj.<%- p.name -%>), + <% } else if (isBuffer(baseP)) {-%> + <%- p.name -%>: cast(bufferToJson, obj.<%- p.name -%>), + <% } else if (!isPrimitive(baseP)) {-%> + <%- p.name -%>: cast(<%- baseRef -%>.toJson, obj.<%- p.name -%>), <% } -%> <% }) -%> } diff --git a/tests/schemas/fruit.yaml b/tests/schemas/fruit.yaml index d38c41a..27c17d6 100644 --- a/tests/schemas/fruit.yaml +++ b/tests/schemas/fruit.yaml @@ -110,6 +110,11 @@ components: description: A set of all the enemies of pac-man ComplexObject: properties: + arrayOfDate: + type: array + items: + type: string + format: date-time ghost: "$ref": "#/components/schemas/GhostGang" description: I can override the description for the property here