Skip to content

Commit 5476f55

Browse files
authored
Merge pull request #1884 from hey-api/feat/client-custom
refactor: move snapshot tests into separate package
2 parents 93dad69 + e8aab64 commit 5476f55

File tree

1,090 files changed

+8126
-177
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

1,090 files changed

+8126
-177
lines changed

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
"lint:fix": "prettier --check --write . && eslint . --fix",
2929
"lint": "prettier --check . && eslint .",
3030
"openapi-ts": "turbo run $1 --filter=\"@hey-api/openapi-ts\"",
31+
"openapi-ts-tests": "turbo run $1 --filter=\"@test/openapi-ts\"",
3132
"prepare": "husky",
3233
"test:coverage": "turbo run test:coverage",
3334
"test:e2e": "turbo run test:e2e",

packages/client-custom/LICENSE.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) Hey API
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

packages/client-custom/package.json

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
{
2+
"name": "@hey-api/client-custom",
3+
"version": "0.0.0",
4+
"description": "Custom client for `@hey-api/openapi-ts` codegen. Used for testing.",
5+
"private": true,
6+
"homepage": "https://heyapi.dev/",
7+
"repository": {
8+
"type": "git",
9+
"url": "git+https://github.com/hey-api/openapi-ts.git"
10+
},
11+
"bugs": {
12+
"url": "https://github.com/hey-api/openapi-ts/issues"
13+
},
14+
"license": "MIT",
15+
"author": {
16+
"email": "[email protected]",
17+
"name": "Hey API",
18+
"url": "https://heyapi.dev"
19+
},
20+
"funding": "https://github.com/sponsors/hey-api",
21+
"type": "module",
22+
"main": "./dist/index.cjs",
23+
"module": "./dist/index.js",
24+
"types": "./dist/index.d.ts",
25+
"exports": {
26+
".": {
27+
"import": {
28+
"types": "./dist/index.d.ts",
29+
"default": "./dist/index.js"
30+
},
31+
"require": {
32+
"types": "./dist/index.d.cts",
33+
"default": "./dist/index.cjs"
34+
}
35+
},
36+
"./plugin": {
37+
"import": {
38+
"types": "./dist/plugin.d.ts",
39+
"default": "./dist/plugin.js"
40+
},
41+
"require": {
42+
"types": "./dist/plugin.d.cts",
43+
"default": "./dist/plugin.cjs"
44+
}
45+
},
46+
"./package.json": "./package.json"
47+
},
48+
"sideEffects": false,
49+
"files": [
50+
"dist",
51+
"LICENSE.md",
52+
"src"
53+
],
54+
"scripts": {
55+
"build": "tsup && rollup -c && pnpm check-exports",
56+
"check-exports": "attw --profile node16 --pack .",
57+
"dev": "tsup --watch",
58+
"prepublishOnly": "pnpm build",
59+
"test:coverage": "vitest run --coverage",
60+
"test:update": "vitest watch --update",
61+
"test:watch": "vitest watch",
62+
"test": "vitest run",
63+
"typecheck": "vitest --typecheck --watch=false"
64+
},
65+
"peerDependencies": {
66+
"@hey-api/openapi-ts": "< 2"
67+
},
68+
"devDependencies": {
69+
"@hey-api/client-core": "workspace:*",
70+
"@hey-api/openapi-ts": "workspace:*"
71+
}
72+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import path from 'node:path';
2+
3+
import { defineConfig } from 'rollup';
4+
import dts from 'rollup-plugin-dts';
5+
6+
const files = ['index.d.ts', 'index.d.cts', 'plugin.d.ts', 'plugin.d.cts'];
7+
8+
export default files.map((file) =>
9+
defineConfig({
10+
external: (id) => {
11+
const normalizedId = id.split(path.sep).join('/');
12+
if (normalizedId === '@hey-api/client-core') {
13+
return false;
14+
}
15+
return (
16+
!normalizedId.startsWith('/') && !/^[a-zA-Z]:\//.test(normalizedId)
17+
);
18+
},
19+
input: `./dist/${file}`,
20+
output: {
21+
file: `./dist/${file}`,
22+
format: 'es',
23+
},
24+
plugins: [
25+
dts({
26+
respectExternal: true,
27+
}),
28+
],
29+
}),
30+
);
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import { describe, expect, it } from 'vitest';
2+
3+
import { createClient } from '../client';
4+
5+
describe('buildUrl', () => {
6+
const client = createClient();
7+
8+
const scenarios: {
9+
options: Parameters<typeof client.buildUrl>[0];
10+
url: string;
11+
}[] = [
12+
{
13+
options: {
14+
url: '',
15+
},
16+
url: '/',
17+
},
18+
{
19+
options: {
20+
url: '/foo',
21+
},
22+
url: '/foo',
23+
},
24+
{
25+
options: {
26+
path: {
27+
fooId: 1,
28+
},
29+
url: '/foo/{fooId}',
30+
},
31+
url: '/foo/1',
32+
},
33+
{
34+
options: {
35+
path: {
36+
fooId: 1,
37+
},
38+
query: {
39+
bar: 'baz',
40+
},
41+
url: '/foo/{fooId}',
42+
},
43+
url: '/foo/1?bar=baz',
44+
},
45+
];
46+
47+
it.each(scenarios)('returns $url', ({ options, url }) => {
48+
expect(client.buildUrl(options)).toBe(url);
49+
});
50+
});
Lines changed: 210 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,210 @@
1+
import type { Auth } from '@hey-api/client-core';
2+
import { describe, expect, it, vi } from 'vitest';
3+
4+
import { getParseAs, setAuthParams } from '../utils';
5+
6+
describe('getParseAs', () => {
7+
const scenarios: Array<{
8+
content: Parameters<typeof getParseAs>[0];
9+
parseAs: ReturnType<typeof getParseAs>;
10+
}> = [
11+
{
12+
content: null,
13+
parseAs: 'stream',
14+
},
15+
{
16+
content: 'application/json',
17+
parseAs: 'json',
18+
},
19+
{
20+
content: 'application/ld+json',
21+
parseAs: 'json',
22+
},
23+
{
24+
content: 'application/ld+json;charset=utf-8',
25+
parseAs: 'json',
26+
},
27+
{
28+
content: 'application/ld+json; charset=utf-8',
29+
parseAs: 'json',
30+
},
31+
{
32+
content: 'multipart/form-data',
33+
parseAs: 'formData',
34+
},
35+
{
36+
content: 'application/*',
37+
parseAs: 'blob',
38+
},
39+
{
40+
content: 'audio/*',
41+
parseAs: 'blob',
42+
},
43+
{
44+
content: 'image/*',
45+
parseAs: 'blob',
46+
},
47+
{
48+
content: 'video/*',
49+
parseAs: 'blob',
50+
},
51+
{
52+
content: 'text/*',
53+
parseAs: 'text',
54+
},
55+
{
56+
content: 'unsupported',
57+
parseAs: undefined,
58+
},
59+
];
60+
61+
it.each(scenarios)(
62+
'detects $content as $parseAs',
63+
async ({ content, parseAs }) => {
64+
expect(getParseAs(content)).toEqual(parseAs);
65+
},
66+
);
67+
});
68+
69+
describe('setAuthParams', () => {
70+
it('sets bearer token in headers', async () => {
71+
const auth = vi.fn().mockReturnValue('foo');
72+
const headers = new Headers();
73+
const query: Record<any, unknown> = {};
74+
await setAuthParams({
75+
auth,
76+
headers,
77+
query,
78+
security: [
79+
{
80+
name: 'baz',
81+
scheme: 'bearer',
82+
type: 'http',
83+
},
84+
],
85+
});
86+
expect(auth).toHaveBeenCalled();
87+
expect(headers.get('baz')).toBe('Bearer foo');
88+
expect(Object.keys(query).length).toBe(0);
89+
});
90+
91+
it('sets access token in query', async () => {
92+
const auth = vi.fn().mockReturnValue('foo');
93+
const headers = new Headers();
94+
const query: Record<any, unknown> = {};
95+
await setAuthParams({
96+
auth,
97+
headers,
98+
query,
99+
security: [
100+
{
101+
in: 'query',
102+
name: 'baz',
103+
scheme: 'bearer',
104+
type: 'http',
105+
},
106+
],
107+
});
108+
expect(auth).toHaveBeenCalled();
109+
expect(headers.get('baz')).toBeNull();
110+
expect(query.baz).toBe('Bearer foo');
111+
});
112+
113+
it('sets Authorization header when `in` and `name` are undefined', async () => {
114+
const auth = vi.fn().mockReturnValue('foo');
115+
const headers = new Headers();
116+
const query: Record<any, unknown> = {};
117+
await setAuthParams({
118+
auth,
119+
headers,
120+
query,
121+
security: [
122+
{
123+
type: 'http',
124+
},
125+
],
126+
});
127+
expect(auth).toHaveBeenCalled();
128+
expect(headers.get('Authorization')).toBe('foo');
129+
expect(query).toEqual({});
130+
});
131+
132+
it('sets first scheme only', async () => {
133+
const auth = vi.fn().mockReturnValue('foo');
134+
const headers = new Headers();
135+
const query: Record<any, unknown> = {};
136+
await setAuthParams({
137+
auth,
138+
headers,
139+
query,
140+
security: [
141+
{
142+
name: 'baz',
143+
scheme: 'bearer',
144+
type: 'http',
145+
},
146+
{
147+
in: 'query',
148+
name: 'baz',
149+
scheme: 'bearer',
150+
type: 'http',
151+
},
152+
],
153+
});
154+
expect(auth).toHaveBeenCalled();
155+
expect(headers.get('baz')).toBe('Bearer foo');
156+
expect(Object.keys(query).length).toBe(0);
157+
});
158+
159+
it('sets first scheme with token', async () => {
160+
const auth = vi.fn().mockImplementation((auth: Auth) => {
161+
if (auth.type === 'apiKey') {
162+
return;
163+
}
164+
return 'foo';
165+
});
166+
const headers = new Headers();
167+
const query: Record<any, unknown> = {};
168+
await setAuthParams({
169+
auth,
170+
headers,
171+
query,
172+
security: [
173+
{
174+
name: 'baz',
175+
type: 'apiKey',
176+
},
177+
{
178+
in: 'query',
179+
name: 'baz',
180+
scheme: 'bearer',
181+
type: 'http',
182+
},
183+
],
184+
});
185+
expect(auth).toHaveBeenCalled();
186+
expect(headers.get('baz')).toBeNull();
187+
expect(query.baz).toBe('Bearer foo');
188+
});
189+
190+
it('sets an API key in a cookie', async () => {
191+
const auth = vi.fn().mockReturnValue('foo');
192+
const headers = new Headers();
193+
const query: Record<any, unknown> = {};
194+
await setAuthParams({
195+
auth,
196+
headers,
197+
query,
198+
security: [
199+
{
200+
in: 'cookie',
201+
name: 'baz',
202+
type: 'apiKey',
203+
},
204+
],
205+
});
206+
expect(auth).toHaveBeenCalled();
207+
expect(headers.get('Cookie')).toBe('baz=foo');
208+
expect(query).toEqual({});
209+
});
210+
});

0 commit comments

Comments
 (0)