Skip to content

Commit

Permalink
feat: creation of a new interface for combined target + client instal…
Browse files Browse the repository at this point in the history
…lation
  • Loading branch information
erunion committed Oct 25, 2023
1 parent 64a5531 commit da9682f
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 7 deletions.
39 changes: 34 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,13 @@ npm install --save @readme/httpsnippet

## Usage

### HTTPSnippet(source [, options])
### HTTPSnippet(input [, options])

#### source
#### input

_Required_ Type: `object`

Name of [conversion target](https://github.com/Kong/httpsnippet/wiki/Targets)
The [HAR](http://www.softwareishard.com/blog/har-12-spec/#request) request object to generate a snippet for.

```ts
import { HTTPSnippet } from 'httpsnippet';
Expand Down Expand Up @@ -128,13 +128,13 @@ HTTPSnippet.addTarget(customLanguageTarget);

### addTargetClient(target, client)

### Target
#### Target

_Required_ Type: `string`

Name of [conversion target](https://github.com/Kong/httpsnippet/wiki/Targets)

### Client
#### Client

_Required_ Type: `object`

Expand All @@ -145,6 +145,34 @@ import { customClient } from 'httpsnippet-for-my-node-http-client';
HTTPSnippet.addTargetClient('node', customClient);
```

### addClientPlugin(plugin)

#### Plugin

_Required_ Type: `object`

The client plugin to install.

```ts
addClientPlugin({
target: 'node',
client: {
info: {
key: 'custom',
title: 'Custom HTTP library',
link: 'https://example.com',
description: 'A custom HTTP library',
extname: '.custom',
},
convert: () => {
return 'This was generated from a custom client.';
},
},
});
```

The above example will create a new `custom` client snippet generator for the `node` target.

## Documentation

At the heart of this module is the [HAR Format](http://www.softwareishard.com/blog/har-12-spec/#request) as the HTTP request description format, please review some of the sample JSON HAR Request objects in [test fixtures](/test/fixtures/requests), or read the [HAR Docs](http://www.softwareishard.com/blog/har-12-spec/#request) for more details.
Expand All @@ -161,6 +189,7 @@ There are some major differences between this library and the [httpsnippet](http
- The main `HTTPSnippet` export contains an `options` argument for an `harIsAlreadyEncoded` option for disabling [escaping](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent) of cookies and query strings in URLs.
- We added this because all HARs that we interact with already have this data escaped and this option prevents them from being double encoded, thus corrupting the data.
- Does not support the `insecureSkipVerify` option on `go:native`, `node:native`, `ruby:native`, and `shell:curl` as we don't want snippets generated for our users to bypass SSL certificate verification.
- Includes a full plugin system, `#addClientPlugin`, for quick installation of a target client.
- Node
- `fetch`
- Body payloads are treated as an object literal and wrapped within `JSON.stringify()`. We do this to keep those targets looking nicer with those kinds of payloads. This also applies to the JS `fetch` target as well.
Expand Down
36 changes: 34 additions & 2 deletions src/targets/index.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { Client, ClientId, Target, TargetId } from './index.js';
import type { Client, ClientId, ClientPlugin, Target, TargetId } from './index.js';
import type { HTTPSnippetOptions, Request } from '../index.js';

import { readdirSync, readFileSync, writeFileSync } from 'node:fs';
Expand All @@ -10,7 +10,7 @@ import short from '../fixtures/requests/short.cjs';
import { availableTargets, extname } from '../helpers/utils.js';
import { HTTPSnippet } from '../index.js';

import { isClient, isTarget, addTarget, addTargetClient, targets } from './index.js';
import { isClient, isTarget, addTarget, addTargetClient, targets, addClientPlugin } from './index.js';

const expectedBasePath = ['src', 'fixtures', 'requests'];

Expand Down Expand Up @@ -318,3 +318,35 @@ describe('addTargetClient', () => {
expect(result).toBe('This was generated from a custom client.');
});
});

describe('addClientPlugin', () => {
afterEach(() => {
delete targets.node.clientsById.custom;
});

it('should add a new custom target', async () => {
const customPlugin: ClientPlugin = {
target: 'node',
client: {
info: {
key: 'custom',
title: 'Custom HTTP library',
link: 'https://example.com',
description: 'A custom HTTP library',
extname: '.custom',
},
convert: () => {
return 'This was generated from a custom client.';
},
},
};

addClientPlugin(customPlugin);

const snippet = new HTTPSnippet(short.log.entries[0].request as Request, {});

const result = await snippet.convert('node', 'custom');

expect(result).toBe('This was generated from a custom client.');
});
});
9 changes: 9 additions & 0 deletions src/targets/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,11 @@ export interface Client<T extends Record<string, any> = Record<string, any>> {
info: ClientInfo;
}

export interface ClientPlugin {
client: Client;
target: TargetId;
}

export type Extension = `.${string}` | null;

export interface TargetInfo {
Expand Down Expand Up @@ -186,6 +191,10 @@ export const isClient = (client: Client): client is Client => {
return true;
};

export const addClientPlugin = (plugin: ClientPlugin) => {
addTargetClient(plugin.target, plugin.client);
};

export const addTargetClient = (targetId: TargetId, client: Client) => {
if (!isClient(client)) {
return;
Expand Down

0 comments on commit da9682f

Please sign in to comment.