Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: creation of a new interface for combined target + client installation #206

Merged
merged 1 commit into from
Oct 25, 2023
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
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