@antelopejs/interface-data-api 0.4.0 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +26 -22
- package/dist/antelope.test.js +1 -5
- package/dist/antelope.test.js.map +1 -1
- package/dist/components.d.ts +67 -39
- package/dist/components.js +106 -685
- package/dist/components.js.map +1 -1
- package/dist/index.d.ts +57 -68
- package/dist/index.js +114 -100
- package/dist/index.js.map +1 -1
- package/dist/internal/computed.d.ts +6 -0
- package/dist/internal/computed.js +51 -0
- package/dist/internal/computed.js.map +1 -0
- package/dist/internal/controller-types.d.ts +34 -0
- package/dist/internal/controller-types.js +4 -0
- package/dist/internal/controller-types.js.map +1 -0
- package/dist/internal/default-filter.d.ts +4 -0
- package/dist/internal/default-filter.js +29 -0
- package/dist/internal/default-filter.js.map +1 -0
- package/dist/internal/deferred-joined-stream.d.ts +11 -0
- package/dist/internal/deferred-joined-stream.js +125 -0
- package/dist/internal/deferred-joined-stream.js.map +1 -0
- package/dist/internal/extractors.d.ts +25 -0
- package/dist/internal/extractors.js +31 -0
- package/dist/internal/extractors.js.map +1 -0
- package/dist/internal/field-types.d.ts +199 -0
- package/dist/internal/field-types.js +4 -0
- package/dist/internal/field-types.js.map +1 -0
- package/dist/internal/filters.d.ts +6 -0
- package/dist/internal/filters.js +22 -0
- package/dist/internal/filters.js.map +1 -0
- package/dist/internal/foreign.d.ts +6 -0
- package/dist/internal/foreign.js +116 -0
- package/dist/internal/foreign.js.map +1 -0
- package/dist/internal/guards.d.ts +39 -0
- package/dist/internal/guards.js +116 -0
- package/dist/internal/guards.js.map +1 -0
- package/dist/internal/joined.d.ts +28 -0
- package/dist/internal/joined.js +127 -0
- package/dist/internal/joined.js.map +1 -0
- package/dist/internal/list.d.ts +16 -0
- package/dist/internal/list.js +182 -0
- package/dist/internal/list.js.map +1 -0
- package/dist/internal/meta-records.d.ts +19 -0
- package/dist/internal/meta-records.js +78 -0
- package/dist/internal/meta-records.js.map +1 -0
- package/dist/internal/properties.d.ts +4 -0
- package/dist/internal/properties.js +45 -0
- package/dist/internal/properties.js.map +1 -0
- package/dist/internal/prototypes.d.ts +14 -0
- package/dist/internal/prototypes.js +38 -0
- package/dist/internal/prototypes.js.map +1 -0
- package/dist/internal/read-properties.d.ts +3 -0
- package/dist/internal/read-properties.js +29 -0
- package/dist/internal/read-properties.js.map +1 -0
- package/dist/internal/table-reference.d.ts +11 -0
- package/dist/internal/table-reference.js +46 -0
- package/dist/internal/table-reference.js.map +1 -0
- package/dist/internal/tables.d.ts +28 -0
- package/dist/internal/tables.js +48 -0
- package/dist/internal/tables.js.map +1 -0
- package/dist/internal/validation.d.ts +12 -0
- package/dist/internal/validation.js +100 -0
- package/dist/internal/validation.js.map +1 -0
- package/dist/metadata.d.ts +27 -228
- package/dist/metadata.js +84 -213
- package/dist/metadata.js.map +1 -1
- package/dist/tests/components/access_control.test.js +28 -20
- package/dist/tests/components/access_control.test.js.map +1 -1
- package/dist/tests/components/computed.test.js +36 -27
- package/dist/tests/components/computed.test.js.map +1 -1
- package/dist/tests/components/cross_instance.test.js +8 -6
- package/dist/tests/components/cross_instance.test.js.map +1 -1
- package/dist/tests/components/deferred_joined.test.js +57 -54
- package/dist/tests/components/deferred_joined.test.js.map +1 -1
- package/dist/tests/components/extract_generic.test.d.ts +1 -0
- package/dist/tests/components/extract_generic.test.js +64 -0
- package/dist/tests/components/extract_generic.test.js.map +1 -0
- package/dist/tests/components/filter_comparisons.test.d.ts +1 -0
- package/dist/tests/components/filter_comparisons.test.js +34 -0
- package/dist/tests/components/filter_comparisons.test.js.map +1 -0
- package/dist/tests/components/filter_list_route.test.d.ts +1 -0
- package/dist/tests/components/filter_list_route.test.js +182 -0
- package/dist/tests/components/filter_list_route.test.js.map +1 -0
- package/dist/tests/components/filter_options.test.js +11 -10
- package/dist/tests/components/filter_options.test.js.map +1 -1
- package/dist/tests/components/foreign_computed.test.js +23 -14
- package/dist/tests/components/foreign_computed.test.js.map +1 -1
- package/dist/tests/components/foreign_joined.test.js +31 -27
- package/dist/tests/components/foreign_joined.test.js.map +1 -1
- package/dist/tests/components/joined.test.js +59 -45
- package/dist/tests/components/joined.test.js.map +1 -1
- package/dist/tests/components/listable.test.js +78 -58
- package/dist/tests/components/listable.test.js.map +1 -1
- package/dist/tests/components/localized_sort.test.js +14 -11
- package/dist/tests/components/localized_sort.test.js.map +1 -1
- package/dist/tests/components/mandatory.test.js +25 -25
- package/dist/tests/components/mandatory.test.js.map +1 -1
- package/dist/tests/components/modifier_key.test.js +27 -18
- package/dist/tests/components/modifier_key.test.js.map +1 -1
- package/dist/tests/components/parse_body.test.d.ts +1 -0
- package/dist/tests/components/parse_body.test.js +76 -0
- package/dist/tests/components/parse_body.test.js.map +1 -0
- package/dist/tests/components/parsed_value.test.js +23 -21
- package/dist/tests/components/parsed_value.test.js.map +1 -1
- package/dist/tests/components/partial_edit.test.js +38 -32
- package/dist/tests/components/partial_edit.test.js.map +1 -1
- package/dist/tests/components/per_action_access.test.js +20 -12
- package/dist/tests/components/per_action_access.test.js.map +1 -1
- package/dist/tests/components/prototype_named_filter.test.d.ts +1 -0
- package/dist/tests/components/prototype_named_filter.test.js +87 -0
- package/dist/tests/components/prototype_named_filter.test.js.map +1 -0
- package/dist/tests/components/validator.test.js +45 -37
- package/dist/tests/components/validator.test.js.map +1 -1
- package/dist/tests/components/written_row.test.d.ts +1 -0
- package/dist/tests/components/written_row.test.js +99 -0
- package/dist/tests/components/written_row.test.js.map +1 -0
- package/dist/tests/helpers/other-instance.d.ts +11 -1
- package/dist/tests/helpers/other-instance.js +35 -9
- package/dist/tests/helpers/other-instance.js.map +1 -1
- package/dist/tests/index/field_decorator_target.test.d.ts +1 -0
- package/dist/tests/index/field_decorator_target.test.js +20 -0
- package/dist/tests/index/field_decorator_target.test.js.map +1 -0
- package/dist/tests/index/get_guard.test.js +6 -6
- package/dist/tests/index/get_guard.test.js.map +1 -1
- package/dist/tests/index/inheritance.test.js +14 -9
- package/dist/tests/index/inheritance.test.js.map +1 -1
- package/dist/tests/index/metadata_names.test.d.ts +1 -0
- package/dist/tests/index/metadata_names.test.js +91 -0
- package/dist/tests/index/metadata_names.test.js.map +1 -0
- package/dist/tests/index/routes.test.js +49 -44
- package/dist/tests/index/routes.test.js.map +1 -1
- package/dist/tests/integration.test.d.ts +1 -1
- package/dist/tests/integration.test.js +66 -729
- package/dist/tests/integration.test.js.map +1 -1
- package/dist/tests/internal/controller-fields.test.d.ts +1 -0
- package/dist/tests/internal/controller-fields.test.js +25 -0
- package/dist/tests/internal/controller-fields.test.js.map +1 -0
- package/dist/tests/internal/http.d.ts +35 -0
- package/dist/tests/internal/http.js +56 -0
- package/dist/tests/internal/http.js.map +1 -0
- package/dist/tests/internal/shop-api.d.ts +1 -0
- package/dist/tests/internal/shop-api.js +331 -0
- package/dist/tests/internal/shop-api.js.map +1 -0
- package/dist/tests/internal/shop-schema.d.ts +162 -0
- package/dist/tests/internal/shop-schema.js +387 -0
- package/dist/tests/internal/shop-schema.js.map +1 -0
- package/dist/tests/utils.d.ts +8 -10
- package/dist/tests/utils.js +1 -3
- package/dist/tests/utils.js.map +1 -1
- package/dist/tests/utils.test.js +10 -11
- package/dist/tests/utils.test.js.map +1 -1
- package/docs/1.introduction.md +38 -35
- package/docs/10.joined.md +51 -40
- package/docs/11.computed.md +91 -47
- package/docs/2.data-controllers.md +50 -42
- package/docs/3.routes.md +156 -134
- package/docs/4.access-rights.md +48 -44
- package/docs/5.validators.md +65 -47
- package/docs/6.listable.md +53 -49
- package/docs/7.foreign-keys.md +55 -48
- package/docs/8.filters.md +65 -54
- package/docs/9.modifiers.md +29 -25
- package/package.json +34 -13
- package/skills/data-api-interface/SKILL.md +13 -3
- package/skills/data-api-interface/cases.json +99 -0
|
@@ -118,9 +118,11 @@ This exposes `GET /tasks/get?id=`, `GET /tasks/list`, `POST /tasks/new`, `PUT /t
|
|
|
118
118
|
- `list` responds `{ results, total, offset, limit }`. `limit` defaults to 10 and is capped at 100
|
|
119
119
|
(`maxPage`). Sorting uses `sortKey`/`sortDirection` query params and requires `@Sortable` on the
|
|
120
120
|
field (400 otherwise). List responses only include `@Listable` fields unless `noPluck` is set.
|
|
121
|
-
- Filters come from `filter_<name>=<mode>:<value>` query params (plain value means `eq`)
|
|
122
|
-
`eq|ne|gt|ge|lt|le`
|
|
123
|
-
function to cast for numeric ranges)
|
|
121
|
+
- Filters come from `filter_<name>=<mode>:<value>` query params (plain value means `eq`). `mode` is
|
|
122
|
+
text: the default filter accepts `eq|ne|gt|ge|lt|le` and answers 400 for anything else (it compares
|
|
123
|
+
the raw query-string value — pass a custom filter function to cast for numeric ranges), and a custom
|
|
124
|
+
filter receives it unchecked and defines its own modes. Only fields declared with `@Filter()` are
|
|
125
|
+
filterable.
|
|
124
126
|
Repeating a field's filter (`filter_age=ge:18&filter_age=lt:65`) keeps the rows passing them all;
|
|
125
127
|
the route then receives a list of tuples for it (`FieldFilter`, read with `FilterValuesOf`).
|
|
126
128
|
- `@Joined` and `@Computed` fields are materialized in-database, so `@Sortable` and `@Filter()` work
|
|
@@ -134,12 +136,20 @@ This exposes `GET /tasks/get?id=`, `GET /tasks/list`, `POST /tasks/new`, `PUT /t
|
|
|
134
136
|
- A custom list route reads its page with `Query.ListPage(db, meta, query, options)` (`offset`,
|
|
135
137
|
`limit`, `filters`, `sortKey`, `pluck`, `noForeign`, `deferredJoined`): joined, then computed, then
|
|
136
138
|
foreign, then pluck.
|
|
139
|
+
- A route is `DataControllerCallback<O, R, A>`: `A` is the tuple `func` receives, one element per
|
|
140
|
+
`args` entry. The default routes declare theirs (`Get` takes `[RequestContext, GetParameters]`), so a
|
|
141
|
+
wrapper generic over `[RequestContext, P, ...Rest]` calls `route.func.call(this, ctx, params, ...rest)`
|
|
142
|
+
typed; without `A` its parameters are not checked.
|
|
137
143
|
- `new` answers the created row as `get` reads it, with its `_id`; `edit` answers the stored row after
|
|
138
144
|
the update. Both accept a body already parsed (`Validation.WrittenBody`), so a wrapping route can
|
|
139
145
|
amend it before the write.
|
|
140
146
|
- `edit` is a partial update: a field absent from the body is left unchanged, `null` clears it, and
|
|
141
147
|
setters only run for the fields present. `@Mandatory("edit")` rejects a field cleared by the body
|
|
142
148
|
(`null`, `""`, `[]`), not an absent one. `new` still writes every writable field and runs every setter.
|
|
149
|
+
- A parsed request body is `FieldValues` (fields by name; a `FieldValue` is JSON or a `Date`). A
|
|
150
|
+
`@Validator` receives `FieldValue | undefined`, and `Validation.ParseBody` answers 400 for a body that
|
|
151
|
+
holds anything else, even one a wrapping route already parsed. The default routes run with the
|
|
152
|
+
controller as `this` (`DataControllerInstance`); a wrapper calls `route.func.call(this, ...)`.
|
|
143
153
|
- A `@Validator` may return a parse result `{ success, data }` (e.g. zod's `safeParseAsync(value)`)
|
|
144
154
|
instead of a boolean: `data` is then written in place of the raw value.
|
|
145
155
|
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 1,
|
|
3
|
+
"cases": [
|
|
4
|
+
{
|
|
5
|
+
"id": "data-api-interface-crud-endpoints",
|
|
6
|
+
"area": "framework",
|
|
7
|
+
"style": "clean",
|
|
8
|
+
"prompt": "Expose my orders table as REST endpoints for get, list, create, update and delete. Only the status column should be sortable and customer filterable.",
|
|
9
|
+
"expect": {
|
|
10
|
+
"skills": ["data-api-interface"],
|
|
11
|
+
"acceptable": [
|
|
12
|
+
"api-interface",
|
|
13
|
+
"database-decorators-interface",
|
|
14
|
+
"database-interface",
|
|
15
|
+
"ajs-consume-interface",
|
|
16
|
+
"antelopejs"
|
|
17
|
+
],
|
|
18
|
+
"mustMention": [
|
|
19
|
+
"DataController",
|
|
20
|
+
"RegisterDataController",
|
|
21
|
+
"Sortable",
|
|
22
|
+
"Filter"
|
|
23
|
+
]
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
"id": "data-api-interface-crud-casual",
|
|
28
|
+
"area": "framework",
|
|
29
|
+
"style": "casual",
|
|
30
|
+
"prompt": "can i get a crud api straight from my table without writing every route",
|
|
31
|
+
"expect": {
|
|
32
|
+
"skills": ["data-api-interface"],
|
|
33
|
+
"acceptable": [
|
|
34
|
+
"api-interface",
|
|
35
|
+
"database-decorators-interface",
|
|
36
|
+
"database-interface",
|
|
37
|
+
"antelopejs"
|
|
38
|
+
],
|
|
39
|
+
"mustMention": ["DataController", "DefaultRoutes"]
|
|
40
|
+
}
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
"id": "data-api-interface-field-hidden",
|
|
44
|
+
"area": "framework",
|
|
45
|
+
"style": "clean",
|
|
46
|
+
"prompt": "The list endpoint I generated from my table never returns the email field and I cannot write to it either. Why?",
|
|
47
|
+
"expect": {
|
|
48
|
+
"skills": ["data-api-interface"],
|
|
49
|
+
"acceptable": [
|
|
50
|
+
"api-interface",
|
|
51
|
+
"database-decorators-interface",
|
|
52
|
+
"ajs-consume-interface"
|
|
53
|
+
],
|
|
54
|
+
"mustMention": ["Access"]
|
|
55
|
+
}
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
"id": "data-api-interface-sort-400-casual",
|
|
59
|
+
"area": "framework",
|
|
60
|
+
"style": "casual",
|
|
61
|
+
"prompt": "sorting the list by createdAt gives me a 400",
|
|
62
|
+
"expect": {
|
|
63
|
+
"skills": ["data-api-interface"],
|
|
64
|
+
"acceptable": ["api-interface", "database-decorators-interface"],
|
|
65
|
+
"mustMention": ["Sortable"]
|
|
66
|
+
}
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
"id": "data-api-interface-table-neighbour",
|
|
70
|
+
"area": "framework",
|
|
71
|
+
"style": "clean",
|
|
72
|
+
"prompt": "Add a hashed passphrase and an encrypted supplier code to my chef table class, plus created and updated timestamps.",
|
|
73
|
+
"expect": {
|
|
74
|
+
"skills": ["database-decorators-interface"],
|
|
75
|
+
"acceptable": [
|
|
76
|
+
"database-interface",
|
|
77
|
+
"antelopejs",
|
|
78
|
+
"ajs-consume-interface"
|
|
79
|
+
],
|
|
80
|
+
"avoid": ["data-api-interface"]
|
|
81
|
+
}
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
"id": "data-api-interface-wrap-new-stamp",
|
|
85
|
+
"area": "framework",
|
|
86
|
+
"style": "clean",
|
|
87
|
+
"prompt": "I want the generated create route to stamp a source field on every body before it is validated and written. How do I wrap it, and what type does the parsed body have?",
|
|
88
|
+
"expect": {
|
|
89
|
+
"skills": ["data-api-interface"],
|
|
90
|
+
"acceptable": [
|
|
91
|
+
"api-interface",
|
|
92
|
+
"database-decorators-interface",
|
|
93
|
+
"ajs-consume-interface"
|
|
94
|
+
],
|
|
95
|
+
"mustMention": ["ParseBody", "WrittenBody", "FieldValues"]
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
]
|
|
99
|
+
}
|