From 71fa41aaf0bbae72cf810ca3f61c4783ec760158 Mon Sep 17 00:00:00 2001 From: Ian Montgomery <94383506+Ian-Montgomery-Klaviyo@users.noreply.github.com> Date: Wed, 22 May 2024 16:35:52 -0400 Subject: [PATCH] 10.0.1 (#68) * 10.0.1 release - fix serialization bug * fix deserializer for falsy values --- README.md | 4 +-- api/apis.ts | 2 +- model/models.ts | 35 +++++++++++++++------ package-lock.json | 62 +++++++++++++++++++------------------ package.json | 2 +- test/api.test.ts | 78 +++++++++++++++++++++++++++++++++++++++++++++-- 6 files changed, 139 insertions(+), 44 deletions(-) diff --git a/README.md b/README.md index 5d683b9c..9fcf8d62 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Klaviyo Typescript SDK -- SDK version: 10.0.0 +- SDK version: 10.0.1 - Revision: 2024-05-15 @@ -48,7 +48,7 @@ This SDK is organized into the following resources: You can install this library using `npm`. -`npm install klaviyo-api@10.0.0` +`npm install klaviyo-api@10.0.1` ## source code diff --git a/api/apis.ts b/api/apis.ts index 9d563825..46c75636 100644 --- a/api/apis.ts +++ b/api/apis.ts @@ -36,7 +36,7 @@ import {AxiosRequestConfig, AxiosResponse, AxiosHeaders, isAxiosError} from "axi export { RequestFile } from '../model/models'; const revision = "2024-05-15"; -const userAgent = "klaviyo-api-node/10.0.0"; +const userAgent = "klaviyo-api-node/10.0.1"; export class RetryOptions { diff --git a/model/models.ts b/model/models.ts index 682a5ea1..c2fdddb7 100644 --- a/model/models.ts +++ b/model/models.ts @@ -3487,7 +3487,7 @@ const oneOfMapNoDiscriminator: {[index: string]: Array} = { } export class ObjectSerializer { - public static findCorrectType(data: any, expectedType: string) { + public static findCorrectType(data: any, expectedType: string, serializer: boolean) { if (data == undefined) { return expectedType; } else if (primitives.indexOf(expectedType.toLowerCase()) !== -1) { @@ -3505,9 +3505,16 @@ export class ObjectSerializer { // the type does not have a discriminator. if (oneOfMapNoDiscriminator[expectedType]) { for (const index in oneOfMapNoDiscriminator[expectedType]) { - if (ObjectSerializer.validateType(data, typeMap[oneOfMapNoDiscriminator[expectedType][index]])) { - return oneOfMapNoDiscriminator[expectedType][index]; + if (serializer) { + if (ObjectSerializer.serializerValidateType(data, typeMap[oneOfMapNoDiscriminator[expectedType][index]])) { + return oneOfMapNoDiscriminator[expectedType][index]; + } + } else { + if (ObjectSerializer.deserializerValidateType(data, typeMap[oneOfMapNoDiscriminator[expectedType][index]])) { + return oneOfMapNoDiscriminator[expectedType][index]; + } } + } } return expectedType; // discriminator was not present (or an empty string) @@ -3527,10 +3534,10 @@ export class ObjectSerializer { } } - public static validateType(data: any, potentialType: any): boolean { + public static deserializerValidateType(data: any, potentialType: any): boolean { for (const index in potentialType.getAttributeTypeMap()) { const attribute = potentialType.getAttributeTypeMap()[index]; - if (!data[attribute.baseName]) { + if (!data.hasOwnProperty(attribute.baseName)) { return false; } if (enumsMap[attribute.type]) { @@ -3541,6 +3548,16 @@ export class ObjectSerializer { } return true; } + public static serializerValidateType(data: Object, potentialType: any): boolean { + const properties = Object.getOwnPropertyNames(data) + for (const index in properties) { + const property = properties[index] + if( !potentialType.getAttributeTypeMap().find((attribute) => attribute.name === property)) { + return false + } + } + return true + } public static serialize(data: any, type: string) { if (data == undefined) { @@ -3562,12 +3579,12 @@ export class ObjectSerializer { if (enumsMap[type]) { return data; } - if (!typeMap[type]) { // in case we dont know the type - return data; + if (!typeMap[type] && !oneOfMapNoDiscriminator[type]) { // in case we dont know the type + return data } // Get the actual type of this object - type = this.findCorrectType(data, type); + type = this.findCorrectType(data, type, true); // get the map for the correct type. let attributeTypes = typeMap[type].getAttributeTypeMap(); @@ -3582,7 +3599,7 @@ export class ObjectSerializer { public static deserialize(data: any, type: string) { // polymorphism may change the actual type. - type = ObjectSerializer.findCorrectType(data, type); + type = ObjectSerializer.findCorrectType(data, type, false); if (data == undefined) { return data; } else if (primitives.indexOf(type.toLowerCase()) !== -1) { diff --git a/package-lock.json b/package-lock.json index 7980aa1b..23c358bb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "klaviyo-api", - "version": "10.0.0", + "version": "10.0.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "klaviyo-api", - "version": "10.0.0", + "version": "10.0.1", "license": "MIT", "dependencies": { "axios": "^1.4.0", @@ -995,9 +995,9 @@ } }, "node_modules/@types/babel__traverse": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.5.tgz", - "integrity": "sha512-WXCyOcRtH37HAUkpXhUduaxdm82b4GSlyTqajXviN4EfiuPgNYR109xMCKvpl6zPIpua0DGlMEDCq+g8EdoheQ==", + "version": "7.20.6", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.6.tgz", + "integrity": "sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg==", "dev": true, "dependencies": { "@babel/types": "^7.20.7" @@ -1140,9 +1140,9 @@ "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" }, "node_modules/axios": { - "version": "1.6.8", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.8.tgz", - "integrity": "sha512-v/ZHtJDU39mDpyBoFVkETcd/uNdxrWRrg3bKpOKzXFA6Bvqopts6ALSMU3y6ijYxbw2B+wPrIv46egTzJXCLGQ==", + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.2.tgz", + "integrity": "sha512-2A8QhOMrbomlDuiLeK9XibIBzuHeRcqqNOHp0Cyp5EoJ1IFDh+XZH3A6BkXtv0K4gFGCI0Y4BM7B1wOEi0Rmgw==", "dependencies": { "follow-redirects": "^1.15.6", "form-data": "^4.0.0", @@ -1273,12 +1273,12 @@ } }, "node_modules/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "dev": true, "dependencies": { - "fill-range": "^7.0.1" + "fill-range": "^7.1.1" }, "engines": { "node": ">=8" @@ -1362,9 +1362,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001618", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001618.tgz", - "integrity": "sha512-p407+D1tIkDvsEAPS22lJxLQQaG8OTBEqo0KhzfABGk0TU4juBNDSfH0hyAp/HRyx+M8L17z/ltyhxh27FTfQg==", + "version": "1.0.30001621", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001621.tgz", + "integrity": "sha512-+NLXZiviFFKX0fk8Piwv3PfLPGtRqJeq2TiNoUff/qB5KJgwecJTvCXDpmlyP/eCI/GUEmp/h/y5j0yckiiZrA==", "dev": true, "funding": [ { @@ -1600,9 +1600,9 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.4.770", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.770.tgz", - "integrity": "sha512-ONwOsDiVvV07CMsyH4+dEaZ9L79HMH/ODHnDS3GkIhgNqdDHJN2C18kFb0fBj0RXpQywsPJl6k2Pqg1IY4r1ig==", + "version": "1.4.777", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.777.tgz", + "integrity": "sha512-n02NCwLJ3wexLfK/yQeqfywCblZqLcXphzmid5e8yVPdtEcida7li0A5WQKghHNG0FeOMCzeFOzEbtAh5riXFw==", "dev": true }, "node_modules/emittery": { @@ -1732,9 +1732,9 @@ } }, "node_modules/fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "dev": true, "dependencies": { "to-regex-range": "^5.0.1" @@ -2828,12 +2828,12 @@ "dev": true }, "node_modules/micromatch": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", - "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.7.tgz", + "integrity": "sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==", "dev": true, "dependencies": { - "braces": "^3.0.2", + "braces": "^3.0.3", "picomatch": "^2.3.1" }, "engines": { @@ -3435,9 +3435,9 @@ } }, "node_modules/ts-jest": { - "version": "29.1.2", - "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.1.2.tgz", - "integrity": "sha512-br6GJoH/WUX4pu7FbZXuWGKGNDuU7b8Uj77g/Sp7puZV6EXzuByl6JrECvm0MzVzSTkSHWTihsXt+5XYER5b+g==", + "version": "29.1.3", + "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.1.3.tgz", + "integrity": "sha512-6L9qz3ginTd1NKhOxmkP0qU3FyKjj5CPoY+anszfVn6Pmv/RIKzhiMCsH7Yb7UvJR9I2A64rm4zQl531s2F1iw==", "dev": true, "dependencies": { "bs-logger": "0.x", @@ -3453,10 +3453,11 @@ "ts-jest": "cli.js" }, "engines": { - "node": "^16.10.0 || ^18.0.0 || >=20.0.0" + "node": "^14.15.0 || ^16.10.0 || ^18.0.0 || >=20.0.0" }, "peerDependencies": { "@babel/core": ">=7.0.0-beta.0 <8", + "@jest/transform": "^29.0.0", "@jest/types": "^29.0.0", "babel-jest": "^29.0.0", "jest": "^29.0.0", @@ -3466,6 +3467,9 @@ "@babel/core": { "optional": true }, + "@jest/transform": { + "optional": true + }, "@jest/types": { "optional": true }, diff --git a/package.json b/package.json index 6cb85e97..e004950c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "klaviyo-api", - "version": "10.0.0", + "version": "10.0.1", "description": "A typescript client for the Klaviyo API", "repository": { "type": "git", diff --git a/test/api.test.ts b/test/api.test.ts index 2b7749c2..0d0ca782 100644 --- a/test/api.test.ts +++ b/test/api.test.ts @@ -1,5 +1,15 @@ import {describe, expect, jest, test} from '@jest/globals'; -import {AccountsApi, ApiKeySession, OAuthBasicSession, RetryOptions} from '../api'; +import { + AccountsApi, + ApiKeySession, + CampaignMessageCreateQueryResourceObjectAttributes, + CampaignResponseObjectResourceAttributes, + EmailSendOptionsSubObject, + EmailTrackingOptionsSubObject, + OAuthBasicSession, + ObjectSerializer, + RetryOptions, +} from '../api'; import axios from 'axios'; jest.mock('axios', () => jest.fn()) @@ -41,4 +51,68 @@ describe('retry', () => { expect(mockedAxios).toHaveBeenCalledTimes(3) } }); -}); \ No newline at end of file +}); +describe('Serialize', () => { + test('an oneOf item serializes correctly', async () => { + let campaign: CampaignMessageCreateQueryResourceObjectAttributes = { + channel: 'email', + content: { + subject: 'Hello', + fromEmail: 'foo.bar@example.com', + fromLabel: 'Foo Bar' + } + } + const serialized = ObjectSerializer.serialize(campaign, 'CampaignMessageCreateQueryResourceObjectAttributes') + expect(serialized).toEqual({ + channel: 'email', + content: { + subject: 'Hello', + from_email: 'foo.bar@example.com', + from_label: 'Foo Bar' + } + }) + }); +}); +describe('deserialize', () => { + test('an oneOf item deserializes correctly', async () => { + const serialized = { + "name": "Email", + "status": "Draft", + "archived": false, + "audiences": { + "included": [ + "TEST_ID" + ], + "excluded": [] + }, + "send_options": { + "use_smart_sending": true, + "ignore_unsubscribes": false + }, + "tracking_options": { + "is_add_utm": false, + "utm_params": [], + "is_tracking_clicks": true, + "is_tracking_opens": true + }, + "send_strategy": { + "method": "static", + "options_static": { + "datetime": "2024-05-22T19:14:32+00:00", + "is_local": false, + "send_past_recipients_immediately": null + }, + "options_throttled": null, + "options_sto": null + }, + "created_at": "2024-05-22T19:14:32.047339+00:00", + "scheduled_at": null, + "updated_at": "2024-05-22T19:14:32.140795+00:00", + "send_time": null + } + const deserialize: CampaignResponseObjectResourceAttributes = ObjectSerializer.deserialize(serialized, 'CampaignResponseObjectResourceAttributes') + expect(deserialize.trackingOptions).toBeInstanceOf(EmailTrackingOptionsSubObject) + expect(deserialize.sendOptions).toBeInstanceOf(EmailSendOptionsSubObject) + + }); +});