Skip to content

Commit 4e30f54

Browse files
authored
Merge pull request #56 from dev-five-git/add-method-layer
Add method layer
2 parents 4bb123f + 1f08e88 commit 4e30f54

File tree

11 files changed

+140
-122
lines changed

11 files changed

+140
-122
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"changes":{"packages/fetch/package.json":"Patch","packages/generator/package.json":"Patch","packages/vite-plugin/package.json":"Patch","packages/core/package.json":"Patch","packages/next-plugin/package.json":"Patch","packages/webpack-plugin/package.json":"Patch","packages/rsbuild-plugin/package.json":"Patch"},"note":"Add method layer","date":"2026-03-06T12:51:48.129089Z"}

packages/core/src/url-map.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
1+
export type HttpMethod = 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH'
2+
13
export interface UrlMapValue {
2-
method: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH'
4+
method: HttpMethod
35
url: string
46
bodyType?: 'json' | 'form' | 'multipart'
57
}
8+
9+
export type UrlMapStoredValue = Omit<UrlMapValue, 'method'>
10+
11+
export type UrlMapEntry = Partial<Record<HttpMethod, UrlMapStoredValue>>

packages/fetch/src/__tests__/api-body-type.test.ts

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,23 +3,28 @@ import { afterEach, beforeEach, describe, expect, mock, test } from 'bun:test'
33
import type { UrlMapValue } from '@devup-api/core'
44

55
// Mock the url-map module to return custom bodyType values
6-
const mockUrlMap: Record<string, Record<string, UrlMapValue>> = {
6+
const mockUrlMap: Record<
7+
string,
8+
Record<string, Partial<Record<string, Omit<UrlMapValue, 'method'>>>>
9+
> = {
710
'openapi.json': {
8-
submitForm: { method: 'POST', url: '/submit', bodyType: 'form' },
9-
uploadFile: { method: 'POST', url: '/upload', bodyType: 'multipart' },
10-
jsonEndpoint: { method: 'POST', url: '/json', bodyType: 'json' },
11+
submitForm: { POST: { url: '/submit', bodyType: 'form' } },
12+
uploadFile: {
13+
POST: { url: '/upload', bodyType: 'multipart' },
14+
},
15+
jsonEndpoint: { POST: { url: '/json', bodyType: 'json' } },
1116
},
1217
}
1318

1419
mock.module('../url-map', () => ({
1520
DEVUP_API_URL_MAP: mockUrlMap,
16-
getApiEndpointInfo: (key: string, serverName: string): UrlMapValue => {
17-
const result = mockUrlMap[serverName]?.[key] ?? {
18-
method: 'GET' as const,
19-
url: key,
20-
}
21-
result.url ||= key
22-
return result
21+
getApiEndpointInfo: (
22+
key: string,
23+
serverName: string,
24+
method: string,
25+
): UrlMapValue => {
26+
const stored = mockUrlMap[serverName]?.[key]?.[method]
27+
return { method: method as 'GET', url: key, ...stored }
2328
},
2429
}))
2530

packages/fetch/src/__tests__/url-map.test.ts

Lines changed: 32 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@ import { beforeEach, expect, test } from 'bun:test'
22

33
const urlMap = {
44
foo: {
5-
getUsers: { method: 'GET' as const, url: '/users' },
6-
createUser: { method: 'POST' as const, url: '/users' },
7-
updateUser: { method: 'PUT' as const, url: '/users/{id}' },
8-
deleteUser: { method: 'DELETE' as const, url: '/users/{id}' },
5+
getUsers: { GET: { url: '/users' } },
6+
createUser: { POST: { url: '/users' } },
7+
updateUser: { PUT: { url: '/users/{id}' } },
8+
deleteUser: { DELETE: { url: '/users/{id}' } },
99
},
1010
}
1111

@@ -15,41 +15,52 @@ beforeEach(() => {
1515
const random = Math.random()
1616

1717
test.each([
18-
['getUsers', '/users', JSON.stringify(urlMap)],
19-
['createUser', '/users', JSON.stringify(urlMap)],
20-
['updateUser', '/users/{id}', JSON.stringify(urlMap)],
21-
['deleteUser', '/users/{id}', JSON.stringify(urlMap)],
22-
] as const)('getApiEndpointInfo returns url for existing key: %s -> %s', async (key, expected, envValue) => {
18+
['getUsers', '/users', 'GET', JSON.stringify(urlMap)],
19+
['createUser', '/users', 'POST', JSON.stringify(urlMap)],
20+
['updateUser', '/users/{id}', 'PUT', JSON.stringify(urlMap)],
21+
['deleteUser', '/users/{id}', 'DELETE', JSON.stringify(urlMap)],
22+
] as const)('getApiEndpointInfo returns url for existing key: %s -> %s', async (key, expected, method, envValue) => {
2323
process.env.DEVUP_API_URL_MAP = envValue
2424
// Add query parameter to bypass module cache and reload
2525
const { getApiEndpointInfo } = await import(`../url-map?t=${random}`)
26-
expect(getApiEndpointInfo(key, 'foo')?.url).toBe(expected)
26+
expect(getApiEndpointInfo(key, 'foo', method)?.url).toBe(expected)
2727
})
2828

2929
test.each([
30-
['nonExistentKey', 'nonExistentKey', JSON.stringify(urlMap)],
31-
['unknown', 'unknown', JSON.stringify(urlMap)],
32-
['', '', JSON.stringify(urlMap)],
33-
['/users', '/users', JSON.stringify(urlMap)],
34-
] as const)('getApiEndpointInfo returns key itself when key does not exist: %s -> %s', async (key, expected, envValue) => {
30+
['nonExistentKey', 'nonExistentKey', 'GET', JSON.stringify(urlMap)],
31+
['unknown', 'unknown', 'GET', JSON.stringify(urlMap)],
32+
['', '', 'GET', JSON.stringify(urlMap)],
33+
['/users', '/users', 'GET', JSON.stringify(urlMap)],
34+
] as const)('getApiEndpointInfo returns key itself when key does not exist: %s -> %s', async (key, expected, method, envValue) => {
3535
process.env.DEVUP_API_URL_MAP = envValue
3636
const { getApiEndpointInfo } = await import(`../url-map?t=${random}`)
37-
expect(getApiEndpointInfo(key, 'foo').url).toBe(expected)
37+
expect(getApiEndpointInfo(key, 'foo', method).url).toBe(expected)
3838
})
3939

4040
test.each([
41-
['getUsers', { method: 'GET', url: '/users' }, JSON.stringify(urlMap)],
42-
['createUser', { method: 'POST', url: '/users' }, JSON.stringify(urlMap)],
43-
['updateUser', { method: 'PUT', url: '/users/{id}' }, JSON.stringify(urlMap)],
41+
['getUsers', { method: 'GET', url: '/users' }, 'GET', JSON.stringify(urlMap)],
42+
[
43+
'createUser',
44+
{ method: 'POST', url: '/users' },
45+
'POST',
46+
JSON.stringify(urlMap),
47+
],
48+
[
49+
'updateUser',
50+
{ method: 'PUT', url: '/users/{id}' },
51+
'PUT',
52+
JSON.stringify(urlMap),
53+
],
4454
[
4555
'deleteUser',
4656
{ method: 'DELETE', url: '/users/{id}' },
57+
'DELETE',
4758
JSON.stringify(urlMap),
4859
],
49-
] as const)('getApiEndpointInfo returns UrlMapValue for existing key: %s -> %s', async (key, expected, envValue) => {
60+
] as const)('getApiEndpointInfo returns UrlMapValue for existing key: %s -> %s', async (key, expected, method, envValue) => {
5061
process.env.DEVUP_API_URL_MAP = envValue
5162
const { getApiEndpointInfo } = await import(`../url-map?t=${random}`)
52-
expect(getApiEndpointInfo(key, 'foo')).toEqual(expected)
63+
expect(getApiEndpointInfo(key, 'foo', method)).toEqual(expected)
5364
})
5465

5566
test.each([

packages/fetch/src/url-map.ts

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,15 @@
1-
import type { UrlMapValue } from '@devup-api/core'
1+
import type { HttpMethod, UrlMapEntry, UrlMapValue } from '@devup-api/core'
22

33
export const DEVUP_API_URL_MAP: Record<
44
string,
5-
Record<string, UrlMapValue>
5+
Record<string, UrlMapEntry>
66
> = JSON.parse(process.env.DEVUP_API_URL_MAP || '{}')
77

88
export function getApiEndpointInfo(
99
key: string,
1010
serverName: string,
11-
method: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH',
11+
method: HttpMethod,
1212
): UrlMapValue {
13-
const result = DEVUP_API_URL_MAP[serverName]?.[key] ?? {
14-
method,
15-
url: key,
16-
}
17-
result.url ||= key
18-
return result
13+
const stored = DEVUP_API_URL_MAP[serverName]?.[key]?.[method]
14+
return { method, url: key, ...stored }
1915
}

0 commit comments

Comments
 (0)