Skip to content
This repository was archived by the owner on Sep 22, 2024. It is now read-only.

Commit 7d02c7b

Browse files
committed
feat(service): implements service.requests[SERVICE_REQUEST_NAME] to return { invoke, item } API
1 parent 0153eaf commit 7d02c7b

File tree

3 files changed

+45
-47
lines changed

3 files changed

+45
-47
lines changed

Diff for: src/service/mod.test.ts

+25-14
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ Deno.test("service", () => {
1515
assertExists(service.client)
1616
assertExists(service.requests)
1717
assertExists(service.item)
18+
assertEquals(service.item._id, SERVICE_ID_JSONPLACEHOLDER)
1819
})
1920

2021
Deno.test("service.client.todos.get()", async () => {
@@ -27,22 +28,32 @@ Deno.test("service.client.todos[1].get()", async () => {
2728
assertEquals(todo?.id, 1)
2829
})
2930

30-
Deno.test("service.client.todos.post()", async () => {
31-
const todo = await service.client.todos.post({ userId: 1, title: "lorem ipsum", completed: true })
32-
assertExists(todo)
33-
})
31+
// Deno.test("service.client.todos.post()", async () => {
32+
// const todo = await service.client.todos.post({ userId: 1, title: "lorem ipsum", completed: true })
33+
// assertExists(todo)
34+
// })
3435

35-
Deno.test("service.client.todos[1].put()", async () => {
36-
const todo = await service.client.todos[1].put({ userId: 1, id: 1, title: "lorem ipsum", completed: true })
37-
assertExists(todo)
38-
})
36+
// Deno.test("service.client.todos[1].put()", async () => {
37+
// const todo = await service.client.todos[1].put({ userId: 1, id: 1, title: "lorem ipsum", completed: true })
38+
// assertExists(todo)
39+
// })
40+
41+
// Deno.test("service.client.todos[1].patch()", async () => {
42+
// const todo = await service.client.todos[1].patch({ completed: true })
43+
// assertExists(todo)
44+
// })
3945

40-
Deno.test("service.client.todos[1].patch()", async () => {
41-
const todo = await service.client.todos[1].patch({ completed: true })
42-
assertExists(todo)
46+
// Deno.test("service.client.todos[1].delete()", async () => {
47+
// const todo = await service.client.todos[1].delete()
48+
// assertExists(todo)
49+
// })
50+
51+
Deno.test("service.requests.getAllTodos.invoke()", async () => {
52+
const todos = await service.requests.getAllTodos.invoke()
53+
assertEquals(todos?.length, 200)
4354
})
4455

45-
Deno.test("service.client.todos[1].delete()", async () => {
46-
const todo = await service.client.todos[1].delete()
47-
assertExists(todo)
56+
Deno.test("service.requests.getFirstTodo.invoke()", async () => {
57+
const todo = await service.requests.getFirstTodo.invoke()
58+
assertEquals(todo?.id, 1)
4859
})

Diff for: src/service/mod.ts

+18-31
Original file line numberDiff line numberDiff line change
@@ -20,45 +20,32 @@ const getClient = (item: ItemService): Client => {
2020
}
2121
}
2222

23-
const createServiceRequests = ({ api, _id, item }: any) => {
24-
return (requestItem: ItemServiceRequest, index: number) => {
25-
// TODO: reuse existing client (of service) if possible
26-
// or at least $fetch/useFetch/unfetch client which supports
27-
// entire service request options (for example hooks, etc.)
28-
const createInvoke = (item: ItemServiceRequest) => {
29-
const { url, method, headers, body } = item
30-
return async () => {
31-
const response = await fetch(url, {
32-
method,
33-
headers,
34-
// IMPORTANT: Request with GET/HEAD method cannot have body
35-
...(!['GET', 'HEAD'].includes(method) && { body }),
36-
})
37-
return response.json()
38-
}
39-
}
40-
const proxy = new Proxy((() => { }), {
41-
/** Select existing by name: "service.requests('getAllTodos')" */
42-
get: (_target, _id): ServiceRequest => {
43-
return { invoke: createInvoke(item), item }
44-
},
45-
/** Creating a new service by passing in options */
46-
apply: (_target, _thisArg, args): ServiceRequest => {
47-
return { invoke: createInvoke(item), item }
48-
}
23+
const createServiceRequest = (item: ItemServiceRequest): ServiceRequest => {
24+
// TODO: reuse existing client (of service) if possible
25+
// or at least $fetch/useFetch/unfetch client which supports
26+
// entire service request options (for example hooks, etc.)
27+
const invoke = async (overrides?: Partial<ItemServiceRequest>) => {
28+
const { url, method, headers, body } = { ...item, ...overrides }
29+
const response = await fetch(url, {
30+
method,
31+
headers,
32+
// IMPORTANT: Request with GET/HEAD method cannot have body
33+
...(!['GET', 'HEAD'].includes(method) && { body }),
4934
})
50-
return [item.name, proxy]
35+
return response.json()
5136
}
37+
return { invoke, item }
5238
}
5339

5440
export const createService = (api: ClientBuilder) => {
5541
return async (_id: string) => {
56-
const item = await api.services[_id].get()
42+
const item = await api.services[_id].get<ItemService>()
5743
const client = getClient(item)
5844

59-
const requests = Object.fromEntries(
60-
item.requests.map(createServiceRequests({ api, _id, item }))
61-
)
45+
const requests = item.requests.reduce((previousValue, currentValue) => ({
46+
...previousValue,
47+
[currentValue.name]: createServiceRequest(currentValue)
48+
}), {} as Record<string, ServiceRequest>)
6249

6350
return { client, requests, item } // see NOTE bellow
6451
}

Diff for: src/service/types.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ export interface Service {
77
}
88

99
export interface ServiceRequest {
10-
invoke: () => Promise<any>;
10+
invoke: ((item: ItemServiceRequest) => () => Promise<any>) | any
1111
item: ItemServiceRequest;
1212
}
1313

@@ -23,7 +23,7 @@ export interface ItemService {
2323
display: { imageUrl: string };
2424
type: 'http' | 'sse' | 'websocket';
2525
client: Record<string, unknown>;
26-
requests: ItemServiceRequest;
26+
requests: ItemServiceRequest[];
2727
options: Record<string, unknown>;
2828
createdAt: string;
2929
updatedAt: string;

0 commit comments

Comments
 (0)