Skip to content
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
67 changes: 45 additions & 22 deletions src/resources/providers/providers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -112,15 +112,26 @@ export class Providers extends APIResource {
}

/**
* Updates part of a provider's configuration and keeps every field you omit.
* Settings merge into the stored settings key by key, and a setting sent as null
* is removed.
* Applies JSON Patch (RFC 6902) operations to a provider configuration and keeps
* every field the operations don't touch. Paths address the provider as it is
* returned: /title, /alias and /settings/<key>. The operations apply in order, and
* if one fails, nothing is saved.
*
* @example
* ```ts
* const provider = await client.providers.patch('id', {
* settings: { api_key: 'SG.xxxxxxxx' },
* title: 'Production SendGrid',
* patch: [
* {
* op: 'replace',
* path: '/title',
* value: 'Production SendGrid',
* },
* {
* op: 'replace',
* path: '/settings/api_key',
* value: 'SG.xxxxxxxx',
* },
* ],
* });
* ```
*/
Expand Down Expand Up @@ -333,29 +344,41 @@ export interface ProviderListParams {

export interface ProviderPatchParams {
/**
* Updated alias. Set to null to clear it.
* Operations to apply, in order. Paths address the provider as it is returned:
* `/title`, `/alias`, `/provider`, and `/settings/<key>` with the snake_case
* setting keys, including nested paths such as `/settings/rate_limit/rate`. If any
* operation fails, for example a `test`, nothing is saved and the request returns
* a 400. The result can't change `provider`, remove `title`, or add other
* top-level fields. Removing `/alias` clears it.
*/
alias?: string | null;
patch: Array<ProviderPatchParams.Patch>;
}

export namespace ProviderPatchParams {
/**
* The provider key identifying the type. Optional. When sent, it must match the
* stored provider, otherwise the request returns a 400.
* One JSON Patch (RFC 6902) operation.
*/
provider?: string;
export interface Patch {
/**
* The operation to perform.
*/
op: 'add' | 'remove' | 'replace' | 'move' | 'copy' | 'test';

/**
* Provider-specific settings (snake_case keys) to merge into the stored settings,
* using JSON Merge Patch (RFC 7396). Each key you send replaces the stored value,
* a key set to null is removed, nested objects merge recursively, and arrays
* replace the stored value. Keys you omit keep their stored values. Set
* `rate_limit` to null to remove this configuration's send rate limit.
*/
settings?: { [key: string]: unknown };
/**
* JSON Pointer to the field to operate on, such as `/settings/api_key`.
*/
path: string;

/**
* Updated display title.
*/
title?: string;
/**
* JSON Pointer to the source field for `move` and `copy`.
*/
from?: string;

/**
* The value for `add`, `replace` and `test`. Any JSON value.
*/
value?: unknown;
}
}

Providers.Catalog = Catalog;
Expand Down
29 changes: 27 additions & 2 deletions tests/api-resources/providers/providers.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,8 +99,13 @@ describe('resource providers', () => {
});

// Mock server tests are disabled
test.skip('patch', async () => {
const responsePromise = client.providers.patch('id', {});
test.skip('patch: only required params', async () => {
const responsePromise = client.providers.patch('id', {
patch: [
{ op: 'replace', path: '/title' },
{ op: 'replace', path: '/settings/api_key' },
],
});
const rawResponse = await responsePromise.asResponse();
expect(rawResponse).toBeInstanceOf(Response);
const response = await responsePromise;
Expand All @@ -109,4 +114,24 @@ describe('resource providers', () => {
expect(dataAndResponse.data).toBe(response);
expect(dataAndResponse.response).toBe(rawResponse);
});

// Mock server tests are disabled
test.skip('patch: required and optional params', async () => {
const response = await client.providers.patch('id', {
patch: [
{
op: 'replace',
path: '/title',
from: 'from',
value: 'Production SendGrid',
},
{
op: 'replace',
path: '/settings/api_key',
from: 'from',
value: 'SG.xxxxxxxx',
},
],
});
});
});
Loading