This repository was archived by the owner on Jan 5, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathSearch.ts
90 lines (78 loc) · 2.52 KB
/
Search.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
/* eslint-disable @typescript-eslint/no-explicit-any */
import {
Adapted,
adaptRes,
annotate,
array,
bool,
literal,
makeOptional,
metaC,
metaIdentifier,
Model,
named,
positiveInt,
Post,
prop,
props,
useClassNameForSchema,
} from "@effect-ts-app/core/Schema"
import * as MO from "@effect-ts-app/core/Schema"
import { typedKeysOf } from "@effect-ts-app/core/utils"
import { TaskView } from "./views"
const selectableKeys = typedKeysOf(TaskView.Model.Api.props)
// TODO: but only make selectableKeys optional ;-)
const TaskViewAdapted = props(makeOptional(TaskView.Model.Api.props))
["|>"](named("DynamicTaskView"))
["|>"](
annotate(metaIdentifier, {
description:
"The available properties depend on $select. if $select is omitted, all properties will be available",
})
)
// https://docs.microsoft.com/en-us/graph/query-parameters#odata-system-query-options
function odataProps<Keys extends string[]>(fieldNames: Keys) {
const selectableFields = literal(...fieldNames)
return {
// todo: SET / nonEmptySet / nonEmptyArray
$select: prop(array(selectableFields)).opt(),
$count: prop(bool).opt(),
// $filter
// $orderBy
// $search
$skip: prop(positiveInt).opt(),
$top: prop(positiveInt).opt(),
}
}
@useClassNameForSchema
export class SearchTasksRequest extends Post("/tasks/search")<SearchTasksRequest>()({
...odataProps(selectableKeys),
}) {}
@metaC({ description: "A list of Tasks" })
export class Response extends Model<Response>()({
// TODO: Have to expose to openapi that the fields can be selected
// but, if not adapted, the Optionals must be removed again.
// aka: if has adapter:
// - openapi Response: all optional
// - Response encoder: all required, but only the selected keys available.
items: prop(array(TaskView.Model)),
// TODO: make the count appear as non optional when $count: true on Request.
count: prop(positiveInt).opt(),
}) {}
export class ResponseOpenApi extends Model<ResponseOpenApi>()({
items: prop(array(TaskViewAdapted)),
count: prop(positiveInt).opt(),
}) {}
export function makeAdapter<Props extends MO.PropertyRecord>(props: Props) {
function a<Key extends keyof Props>(
req: SearchTasksRequest & {
fields: readonly Key[]
}
): Adapted<Props, Key>
function a(req: SearchTasksRequest): typeof Response // todo
function a(req: SearchTasksRequest): any {
return req.$select ? adaptRes(props)(req.$select) : Response.Model
}
return a
}
export const adapt = makeAdapter(TaskView.Model.Api.props)