diff --git a/.gitignore b/.gitignore index 9a583fa..1daf821 100644 --- a/.gitignore +++ b/.gitignore @@ -36,4 +36,7 @@ logs .eslintcache # Optional REPL history -.node_repl_history \ No newline at end of file +.node_repl_history + +# Test scripts +scripts/ \ No newline at end of file diff --git a/README.md b/README.md index f1c3eb0..e31f9a7 100644 --- a/README.md +++ b/README.md @@ -478,7 +478,8 @@ MIT License - See LICENSE file for details. | PUT /v1/console/card-templates/{id} | `console.updateTemplate()` | Y | | GET /v1/console/card-templates/{id} | `console.readTemplate()` | Y | | GET .../logs | `console.eventLog()` | Y | -| GET /v1/console/pass-template-pairs | `console.listPassTemplatePairs()` | Y | +| GET /v1/console/card-template-pairs | `console.listPassTemplatePairs()` | Y | +| POST /v1/console/card-template-pairs | `console.createPassTemplatePair()` | Y | | GET /v1/console/ledger-items | `console.ledgerItems()` | Y | | POST .../ios_preflight | `console.iosPreflight()` | Y | | GET /v1/console/webhooks | `console.webhooks.list()` | Y | diff --git a/src/index.js b/src/index.js index 1be2ac5..21e4e79 100644 --- a/src/index.js +++ b/src/index.js @@ -169,6 +169,7 @@ class BaseApi { let resourceId = null; if ( method === "GET" || + method === "DELETE" || (method === "POST" && (!options.body || Object.keys(options.body).length === 0)) ) { @@ -193,7 +194,11 @@ class BaseApi { let payload; let sigPayload; - if ((method === "POST" && !options.body) || method === "GET") { + if ( + (method === "POST" && !options.body) || + method === "GET" || + method === "DELETE" + ) { // For these requests, use {"id": "card_id"} as the payload for signature generation if (resourceId) { sigPayload = JSON.stringify({ id: resourceId }); @@ -221,7 +226,11 @@ class BaseApi { // Handle query parameters for GET requests or POST with empty body let finalUrl = url; - if (method === "GET" || (method === "POST" && !options.body)) { + if ( + method === "GET" || + method === "DELETE" || + (method === "POST" && !options.body) + ) { if (resourceId) { // Add sig_payload to query params const separator = finalUrl.includes("?") ? "&" : "?"; @@ -236,7 +245,11 @@ class BaseApi { body: method !== "GET" ? payload : undefined, }); - const data = await response.json(); + // Handle empty responses (204 No Content) + let data = {}; + if (response.status !== 204) { + data = await response.json(); + } if (!response.ok) { if (response.status === 401) { @@ -487,6 +500,7 @@ class ConsoleApi extends BaseApi { supportEmail: "support_email", privacyPolicyUrl: "privacy_policy_url", termsAndConditionsUrl: "terms_and_conditions_url", + logo: "logo", metadata: "metadata", }; @@ -560,10 +574,15 @@ class ConsoleApi extends BaseApi { return { provisioningCredentialIdentifier: + response.provisioningCredentialIdentifier || response.provisioning_credential_identifier, - sharingInstanceIdentifier: response.sharing_instance_identifier, - cardTemplateIdentifier: response.card_template_identifier, - environmentIdentifier: response.environment_identifier, + sharingInstanceIdentifier: + response.sharingInstanceIdentifier || + response.sharing_instance_identifier, + cardTemplateIdentifier: + response.cardTemplateIdentifier || response.card_template_identifier, + environmentIdentifier: + response.environmentIdentifier || response.environment_identifier, }; } @@ -600,21 +619,35 @@ class ConsoleApi extends BaseApi { const queryString = queryParams.toString(); const path = queryString - ? `/v1/console/pass-template-pairs?${queryString}` - : "/v1/console/pass-template-pairs"; + ? `/v1/console/card-template-pairs?${queryString}` + : "/v1/console/card-template-pairs"; const response = await this.request(path); - if (response.pass_template_pairs) { - response.passTemplatePairs = response.pass_template_pairs.map( + if (response.card_template_pairs) { + response.passTemplatePairs = response.card_template_pairs.map( (pair) => new PassTemplatePair(pair), ); - delete response.pass_template_pairs; + delete response.card_template_pairs; } return response; } + async createPassTemplatePair(params) { + const body = { + name: params.name, + apple_card_template_id: params.appleCardTemplateId, + google_card_template_id: params.googleCardTemplateId, + }; + + const response = await this.request("/v1/console/card-template-pairs", { + method: "POST", + body, + }); + return new PassTemplatePair(response); + } + async listLandingPages() { const response = await this.request("/v1/console/landing-pages"); const pages = Array.isArray(response) ? response : []; diff --git a/test/index.test.js b/test/index.test.js index 702f5b1..85dd78b 100644 --- a/test/index.test.js +++ b/test/index.test.js @@ -550,7 +550,7 @@ describe('AccessGrid SDK', () => { describe('listPassTemplatePairs', () => { const mockPairsResponse = { - pass_template_pairs: [ + card_template_pairs: [ { id: 'pair-1', name: 'Employee Badge Pair', @@ -577,7 +577,7 @@ describe('AccessGrid SDK', () => { await client.console.listPassTemplatePairs(); expect(fetch).toHaveBeenCalledWith( - expect.stringContaining('/v1/console/pass-template-pairs'), + expect.stringContaining('/v1/console/card-template-pairs'), expect.objectContaining({ method: 'GET' }) @@ -611,7 +611,7 @@ describe('AccessGrid SDK', () => { await client.console.listPassTemplatePairs(); const calledUrl = fetch.mock.calls[0][0]; - expect(calledUrl).toMatch(/\/pass-template-pairs(\?sig_payload=|$)/); + expect(calledUrl).toMatch(/\/card-template-pairs(\?sig_payload=|$)/); }); test('should return PassTemplatePair instances', async () => { @@ -635,7 +635,7 @@ describe('AccessGrid SDK', () => { const result = await client.console.listPassTemplatePairs(); - expect(result.pass_template_pairs).toBeUndefined(); + expect(result.card_template_pairs).toBeUndefined(); }); test('should deserialize nested TemplateInfo models', async () => {