Skip to content

Commit

Permalink
feat(snippet): making the library synchronous again (#855)
Browse files Browse the repository at this point in the history
  • Loading branch information
erunion authored Apr 9, 2024
1 parent 550e2cc commit c54d5da
Show file tree
Hide file tree
Showing 5 changed files with 54 additions and 75 deletions.
17 changes: 4 additions & 13 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions packages/oas-to-snippet/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ const language = 'node';
// This will return an object containing `code` and `highlightMode`. `code` is
// the generated code snippet, while `highlightMode` is the language mode you
// can use to render it for syntax highlighting (with `codemirror` for example).
const { code, highlightMode } = await oasToSnippet(apiDefinition, operation, formData, auth, language);
const { code, highlightMode } = oasToSnippet(apiDefinition, operation, formData, auth, language);
```

### Plugins
Expand All @@ -60,7 +60,7 @@ This library also supports the plugin system that we've built into [HTTPSnippet]
import oasToSnippet from '@readme/oas-to-snippet';
import httpsnippetClientAPIPlugin from 'httpsnippet-client-api';

const snippet = await oasToSnippet(
const snippet = oasToSnippet(
petstore,
petstore.operation('/user/login', 'get'),
formData,
Expand Down
2 changes: 1 addition & 1 deletion packages/oas-to-snippet/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@
"test": "vitest run --coverage"
},
"dependencies": {
"@readme/httpsnippet": "^8.1.4",
"@readme/httpsnippet": "^9.0.0",
"@readme/oas-to-har": "file:../oas-to-har"
},
"devDependencies": {
Expand Down
6 changes: 3 additions & 3 deletions packages/oas-to-snippet/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import generateHar from '@readme/oas-to-har';

import { getSupportedLanguages, getLanguageConfig } from './languages.js';

export default async function oasToSnippet(
export default function oasToSnippet(
oas: Oas,
operation: Operation,
values: DataForHAR,
Expand Down Expand Up @@ -102,7 +102,7 @@ export default async function oasToSnippet(

try {
return {
code: await snippet.convert(language, target, targetOpts),
code: snippet.convert(language, target, targetOpts),
highlightMode,
};
} catch (err) {
Expand All @@ -118,7 +118,7 @@ export default async function oasToSnippet(
targetOpts = config.httpsnippet.targets.fetch.opts || {};

return {
code: await snippet.convert(language, 'fetch', targetOpts),
code: snippet.convert(language, 'fetch', targetOpts),
highlightMode,
};
}
Expand Down
100 changes: 44 additions & 56 deletions packages/oas-to-snippet/test/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@ const formData = {

describe('oas-to-snippet', () => {
describe('HAR overrides', () => {
it('should be able to accept a har override', async () => {
const { code } = await oasToSnippet(null, null, null, null, 'node', { harOverride: harExamples.full });
it('should be able to accept a har override', () => {
const { code } = oasToSnippet(null, null, null, null, 'node', { harOverride: harExamples.full });
expect(code).toBe(`const { URLSearchParams } = require('url');
const fetch = require('node-fetch');
const encodedParams = new URLSearchParams();
Expand All @@ -57,8 +57,8 @@ fetch(url, options)
.catch(err => console.error('error:' + err));`);
});

it('should treat overrides as if they are not yet encoded', async () => {
const { code } = await oasToSnippet(null, null, null, null, 'node', {
it('should treat overrides as if they are not yet encoded', () => {
const { code } = oasToSnippet(null, null, null, null, 'node', {
harOverride: queryEncodedHAR as unknown as HarRequest,
});

Expand All @@ -74,36 +74,30 @@ fetch(url, options)
});
});

it('should return falsy values for an unknown language', async () => {
it('should return falsy values for an unknown language', () => {
// @ts-expect-error Testing an improper typing case here.
const codeSnippet = await oasToSnippet(petstore, petstore.operation('/pet/{petId}', 'get'), {}, {}, 'css');
const codeSnippet = oasToSnippet(petstore, petstore.operation('/pet/{petId}', 'get'), {}, {}, 'css');

expect(codeSnippet).toStrictEqual({
code: '',
highlightMode: false,
});
});

it('should pass through values to code snippet', async () => {
const { code } = await oasToSnippet(petstore, petstore.operation('/pet/{petId}', 'get'), formData, {}, 'node');
it('should pass through values to code snippet', () => {
const { code } = oasToSnippet(petstore, petstore.operation('/pet/{petId}', 'get'), formData, {}, 'node');

expect(code).toContain('http://petstore.swagger.io/v2/pet/123');
});

it('should pass through json values to code snippet', async () => {
const { code } = await oasToSnippet(
petstore,
petstore.operation('/pet', 'post'),
{ body: { id: '123' } },
{},
'node',
);
it('should pass through json values to code snippet', () => {
const { code } = oasToSnippet(petstore, petstore.operation('/pet', 'post'), { body: { id: '123' } }, {}, 'node');

expect(code).toContain("body: JSON.stringify({id: '123'}");
});

it('should pass through form encoded values to code snippet', async () => {
const { code } = await oasToSnippet(
it('should pass through form encoded values to code snippet', () => {
const { code } = oasToSnippet(
petstore,
petstore.operation('/pet/{petId}', 'post'),
{
Expand All @@ -122,7 +116,7 @@ fetch(url, options)
expect(code).toContain('body: encodedParams');
});

it('should have special indents for curl snippets', async () => {
it('should have special indents for curl snippets', () => {
const oas = Oas.init({
paths: {
'/body': {
Expand All @@ -147,7 +141,7 @@ fetch(url, options)
},
});

const { code } = await oasToSnippet(
const { code } = oasToSnippet(
oas,
oas.operation('/body', 'get'),
{ formData: { a: 'test', b: [1, 2, 3] } },
Expand All @@ -162,7 +156,7 @@ fetch(url, options)
--data 'b=1,2,3'`);
});

it('should have special indents in curl snippets for JSON payloads', async () => {
it('should have special indents in curl snippets for JSON payloads', () => {
const oas = Oas.init({
paths: {
'/body': {
Expand All @@ -187,7 +181,7 @@ fetch(url, options)
},
});

const { code } = await oasToSnippet(
const { code } = oasToSnippet(
oas,
oas.operation('/body', 'get'),
{ body: { a: 'test', b: [1, 2, 3] } },
Expand All @@ -210,26 +204,26 @@ fetch(url, options)
'`);
});

it('should not contain proxy url', async () => {
it('should not contain proxy url', () => {
const oas = new Oas({
...JSON.parse(JSON.stringify(petstoreOas)),
[PROXY_ENABLED]: true,
});

const { code } = await oasToSnippet(oas, oas.operation('/pet/{petId}', 'post'), formData, {}, 'node');
const { code } = oasToSnippet(oas, oas.operation('/pet/{petId}', 'post'), formData, {}, 'node');

expect(code).toContain('http://petstore.swagger.io/v2/pet/123');
expect(code).not.toContain('try.readme.io');
});

it('should not contain `withCredentials` in javascript snippets', async () => {
const { code } = await oasToSnippet(petstore, petstore.operation('/pet/{petId}', 'post'), {}, {}, 'javascript');
it('should not contain `withCredentials` in javascript snippets', () => {
const { code } = oasToSnippet(petstore, petstore.operation('/pet/{petId}', 'post'), {}, {}, 'javascript');

expect(code).not.toMatch(/withCredentials/);
});

it('should return with unhighlighted code', async () => {
const { code } = await oasToSnippet(petstore, petstore.operation('/pet/{petId}', 'post'), {}, {}, 'javascript');
it('should return with unhighlighted code', () => {
const { code } = oasToSnippet(petstore, petstore.operation('/pet/{petId}', 'post'), {}, {}, 'javascript');

expect(code).not.toMatch(/cm-s-tomorrow-night/);
});
Expand Down Expand Up @@ -295,8 +289,8 @@ fetch(url, options)
});
});

it('should convert a `multipart/form-data` operation into a proper snippet that uses the original file', async () => {
const { code } = await oasToSnippet(
it('should convert a `multipart/form-data` operation into a proper snippet that uses the original file', () => {
const { code } = oasToSnippet(
formDataOas,
formDataOas.operation('/multipart', 'post'),
{
Expand All @@ -311,14 +305,14 @@ fetch(url, options)
--header 'content-type: multipart/form-data' \\
--form orderId=10 \\
--form userId=3232 \\
--form [email protected]`);
--form documentFile='@owlbert.png'`);
});

it('should handle a `multipart/form-data` schema that has a `oneOf`', async () => {
const oas = Oas.init(multipartFormDataOneOfRequestBody);
await oas.dereference();

const { code } = await oasToSnippet(
const { code } = oasToSnippet(
oas,
oas.operation('/anything', 'post'),
{
Expand All @@ -345,7 +339,7 @@ fetch(url, options)
});
});

it('should not double-encode query strings', async () => {
it('should not double-encode query strings', () => {
const startTime = '2019-06-13T19:08:25.455Z';
const endTime = '2015-09-15T14:00:12-04:00';

Expand Down Expand Up @@ -378,24 +372,18 @@ fetch(url, options)
},
});

const snippet = await oasToSnippet(
oas,
oas.operation('/', 'get'),
{ query: { startTime, endTime } },
{},
'javascript',
);
const snippet = oasToSnippet(oas, oas.operation('/', 'get'), { query: { startTime, endTime } }, {}, 'javascript');

expect(snippet.code).toContain(encodeURIComponent(startTime));
expect(snippet.code).toContain(encodeURIComponent(endTime));
expect(snippet.code).not.toContain(encodeURIComponent(encodeURIComponent(startTime)));
expect(snippet.code).not.toContain(encodeURIComponent(encodeURIComponent(endTime)));
});

it('should handle `multipart/form-data` payloads of multiple files', async () => {
it('should handle `multipart/form-data` payloads of multiple files', () => {
const oas = Oas.init(fileUploads);

const snippet = await oasToSnippet(
const snippet = oasToSnippet(
oas,
oas.operation('/anything/multipart-formdata', 'put'),
{ body: { filename: [owlbert, owlbertShrub] } },
Expand All @@ -407,10 +395,10 @@ fetch(url, options)
expect(snippet.code).toContain("formData.append('filename', fs.createReadStream('owlbert-shrub.png'));");
});

it('should handle a `multipart/form-data` payload where a file has an underscore in its name', async () => {
it('should handle a `multipart/form-data` payload where a file has an underscore in its name', () => {
const oas = Oas.init(fileUploads);

const snippet = await oasToSnippet(
const snippet = oasToSnippet(
oas,
oas.operation('/anything/multipart-formdata', 'post'),
{
Expand Down Expand Up @@ -443,8 +431,8 @@ fetch(url, options)
expect(targets).toContain(supportedLanguages[lang].httpsnippet.default);
});

it('should generate code for the default target', async () => {
const snippet = await oasToSnippet(petstore, petstore.operation('/pet', 'post'), formData, {}, lang);
it('should generate code for the default target', () => {
const snippet = oasToSnippet(petstore, petstore.operation('/pet', 'post'), formData, {}, lang);

expect(snippet.code).toMatchSnapshot();
expect(snippet.highlightMode).toBe(supportedLanguages[lang].highlight);
Expand All @@ -466,8 +454,8 @@ fetch(url, options)
}
});

it('should support snippet generation', async () => {
const snippet = await oasToSnippet(
it('should support snippet generation', () => {
const snippet = oasToSnippet(
petstore,
petstore.operation('/user/login', 'get'),
{
Expand All @@ -489,8 +477,8 @@ fetch(url, options)
});

if (lang === 'node' && target === 'api') {
it('should support custom variable names', async () => {
const snippet = await oasToSnippet(
it('should support custom variable names', () => {
const snippet = oasToSnippet(
petstore,
petstore.operation('/user/login', 'get'),
{
Expand All @@ -515,10 +503,10 @@ fetch(url, options)
});
});

it('should gracefully fallback to `fetch` snippets if our `api` target fails', async () => {
it('should gracefully fallback to `fetch` snippets if our `api` target fails', () => {
// Reason that this'll trigger a failure in the `api` snippet target is because we aren't
// passing in an API definition for it to look or an operation in.
const snippet = await oasToSnippet(null, null, null, null, ['node', 'api'], {
const snippet = oasToSnippet(null, null, null, null, ['node', 'api'], {
harOverride: harExamples.full,
openapi: {
registryIdentifier: OAS_REGISTRY_IDENTIFIER,
Expand All @@ -530,15 +518,15 @@ fetch(url, options)
expect(snippet.highlightMode).toBe('javascript');
});

it('should gracefully fallback to `fetch` snippets if our `api` plugin isnt loaded', async () => {
await expect(
it('should gracefully fallback to `fetch` snippets if our `api` plugin isnt loaded', () => {
expect(() => {
oasToSnippet(null, null, null, null, ['node', 'api'], {
harOverride: harExamples.full,
openapi: {
registryIdentifier: OAS_REGISTRY_IDENTIFIER,
},
}),
).rejects.toThrow(/is not supported/);
});
}).toThrow(/is not supported/);
});
});
});

0 comments on commit c54d5da

Please sign in to comment.