@nixxie-cms/core 1.0.3 → 2.0.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/CHANGELOG.md +36 -0
- package/CHANGES-1.1.md +134 -0
- package/context/dist/nixxie-cms-core-context.cjs.js +4 -3
- package/context/dist/nixxie-cms-core-context.esm.js +3 -2
- package/dist/declarations/src/access.d.ts +2 -2
- package/dist/declarations/src/access.d.ts.map +1 -1
- package/dist/declarations/src/admin-ui/components/Navigation.d.ts +2 -2
- package/dist/declarations/src/admin-ui/components/Navigation.d.ts.map +1 -1
- package/dist/declarations/src/admin-ui/context.d.ts +6 -6
- package/dist/declarations/src/admin-ui/context.d.ts.map +1 -1
- package/dist/declarations/src/admin-ui/utils/Fields.d.ts +3 -3
- package/dist/declarations/src/admin-ui/utils/Fields.d.ts.map +1 -1
- package/dist/declarations/src/admin-ui/utils/filters.d.ts +5 -5
- package/dist/declarations/src/admin-ui/utils/filters.d.ts.map +1 -1
- package/dist/declarations/src/admin-ui/utils/useCreateItem.d.ts +3 -3
- package/dist/declarations/src/admin-ui/utils/useCreateItem.d.ts.map +1 -1
- package/dist/declarations/src/admin-ui/utils/utils.d.ts +2 -2
- package/dist/declarations/src/admin-ui/utils/utils.d.ts.map +1 -1
- package/dist/declarations/src/context.d.ts +1 -1
- package/dist/declarations/src/context.d.ts.map +1 -1
- package/dist/declarations/src/fields/types/bigInt/index.d.ts +3 -3
- package/dist/declarations/src/fields/types/bigInt/index.d.ts.map +1 -1
- package/dist/declarations/src/fields/types/bytes/index.d.ts +3 -3
- package/dist/declarations/src/fields/types/bytes/index.d.ts.map +1 -1
- package/dist/declarations/src/fields/types/calendarDay/index.d.ts +3 -3
- package/dist/declarations/src/fields/types/calendarDay/index.d.ts.map +1 -1
- package/dist/declarations/src/fields/types/checkbox/index.d.ts +3 -3
- package/dist/declarations/src/fields/types/checkbox/index.d.ts.map +1 -1
- package/dist/declarations/src/fields/types/decimal/index.d.ts +3 -3
- package/dist/declarations/src/fields/types/decimal/index.d.ts.map +1 -1
- package/dist/declarations/src/fields/types/file/index.d.ts +4 -4
- package/dist/declarations/src/fields/types/file/index.d.ts.map +1 -1
- package/dist/declarations/src/fields/types/float/index.d.ts +3 -3
- package/dist/declarations/src/fields/types/float/index.d.ts.map +1 -1
- package/dist/declarations/src/fields/types/image/index.d.ts +4 -4
- package/dist/declarations/src/fields/types/image/index.d.ts.map +1 -1
- package/dist/declarations/src/fields/types/integer/index.d.ts +3 -3
- package/dist/declarations/src/fields/types/integer/index.d.ts.map +1 -1
- package/dist/declarations/src/fields/types/json/index.d.ts +3 -3
- package/dist/declarations/src/fields/types/json/index.d.ts.map +1 -1
- package/dist/declarations/src/fields/types/multiselect/index.d.ts +3 -3
- package/dist/declarations/src/fields/types/multiselect/index.d.ts.map +1 -1
- package/dist/declarations/src/fields/types/multiselect/views/index.d.ts.map +1 -1
- package/dist/declarations/src/fields/types/password/index.d.ts +3 -3
- package/dist/declarations/src/fields/types/password/index.d.ts.map +1 -1
- package/dist/declarations/src/fields/types/relationship/index.d.ts +8 -8
- package/dist/declarations/src/fields/types/relationship/index.d.ts.map +1 -1
- package/dist/declarations/src/fields/types/relationship/views/ComboboxMany.d.ts +3 -3
- package/dist/declarations/src/fields/types/relationship/views/ComboboxMany.d.ts.map +1 -1
- package/dist/declarations/src/fields/types/relationship/views/ComboboxSingle.d.ts +3 -3
- package/dist/declarations/src/fields/types/relationship/views/ComboboxSingle.d.ts.map +1 -1
- package/dist/declarations/src/fields/types/relationship/views/index.d.ts +3 -3
- package/dist/declarations/src/fields/types/relationship/views/index.d.ts.map +1 -1
- package/dist/declarations/src/fields/types/relationship/views/types.d.ts +3 -3
- package/dist/declarations/src/fields/types/relationship/views/types.d.ts.map +1 -1
- package/dist/declarations/src/fields/types/select/index.d.ts +3 -3
- package/dist/declarations/src/fields/types/select/index.d.ts.map +1 -1
- package/dist/declarations/src/fields/types/text/index.d.ts +3 -3
- package/dist/declarations/src/fields/types/text/index.d.ts.map +1 -1
- package/dist/declarations/src/fields/types/timestamp/index.d.ts +3 -3
- package/dist/declarations/src/fields/types/timestamp/index.d.ts.map +1 -1
- package/dist/declarations/src/fields/types/virtual/index.d.ts +7 -7
- package/dist/declarations/src/fields/types/virtual/index.d.ts.map +1 -1
- package/dist/declarations/src/helpers.d.ts +249 -13
- package/dist/declarations/src/helpers.d.ts.map +1 -1
- package/dist/declarations/src/index.d.ts +9 -4
- package/dist/declarations/src/index.d.ts.map +1 -1
- package/dist/declarations/src/internal-unstable/admin-ui/pages/ListPage/index.d.ts.map +1 -1
- package/dist/declarations/src/lib/admin-meta.d.ts +11 -11
- package/dist/declarations/src/lib/admin-meta.d.ts.map +1 -1
- package/dist/declarations/src/lib/core/access-control.d.ts +18 -18
- package/dist/declarations/src/lib/core/access-control.d.ts.map +1 -1
- package/dist/declarations/src/lib/core/cascade.d.ts +47 -0
- package/dist/declarations/src/lib/core/cascade.d.ts.map +1 -0
- package/dist/declarations/src/lib/core/initialise-lists.d.ts +27 -24
- package/dist/declarations/src/lib/core/initialise-lists.d.ts.map +1 -1
- package/dist/declarations/src/lib/env.d.ts +9 -0
- package/dist/declarations/src/lib/env.d.ts.map +1 -0
- package/dist/declarations/src/lib/system.d.ts +1 -1
- package/dist/declarations/src/lib/system.d.ts.map +1 -1
- package/dist/declarations/src/list-features.d.ts +162 -0
- package/dist/declarations/src/list-features.d.ts.map +1 -0
- package/dist/declarations/src/schema.d.ts +24 -23
- package/dist/declarations/src/schema.d.ts.map +1 -1
- package/dist/declarations/src/session.d.ts +75 -0
- package/dist/declarations/src/session.d.ts.map +1 -1
- package/dist/declarations/src/types/admin-meta.d.ts +11 -11
- package/dist/declarations/src/types/admin-meta.d.ts.map +1 -1
- package/dist/declarations/src/types/config/access-control.d.ts +42 -42
- package/dist/declarations/src/types/config/access-control.d.ts.map +1 -1
- package/dist/declarations/src/types/config/fields.d.ts +19 -19
- package/dist/declarations/src/types/config/fields.d.ts.map +1 -1
- package/dist/declarations/src/types/config/hooks.d.ts +131 -131
- package/dist/declarations/src/types/config/hooks.d.ts.map +1 -1
- package/dist/declarations/src/types/config/index.d.ts +190 -8
- package/dist/declarations/src/types/config/index.d.ts.map +1 -1
- package/dist/declarations/src/types/config/lists.d.ts +146 -108
- package/dist/declarations/src/types/config/lists.d.ts.map +1 -1
- package/dist/declarations/src/types/context.d.ts +507 -47
- package/dist/declarations/src/types/context.d.ts.map +1 -1
- package/dist/declarations/src/types/next-fields.d.ts +28 -28
- package/dist/declarations/src/types/next-fields.d.ts.map +1 -1
- package/dist/declarations/src/types/type-info.d.ts +3 -3
- package/dist/declarations/src/types/type-info.d.ts.map +1 -1
- package/dist/{express-455ae20c.cjs.js → express-84d534c2.cjs.js} +6 -6
- package/dist/{express-7559ca2d.esm.js → express-d0a4ce99.esm.js} +6 -6
- package/dist/{index-15c8f81e.esm.js → index-5d8b0b4e.esm.js} +363 -183
- package/dist/index-6055753b.cjs.js +393 -0
- package/dist/{index-42045902.cjs.js → index-ac29f382.cjs.js} +363 -185
- package/dist/index-f1703b7b.esm.js +386 -0
- package/dist/nixxie-cms-core.cjs.js +1388 -30
- package/dist/nixxie-cms-core.esm.js +1362 -24
- package/dist/{non-null-graphql-add6bb3d.cjs.js → non-null-graphql-4a44c122.cjs.js} +1 -1
- package/dist/{non-null-graphql-a84ed64d.esm.js → non-null-graphql-8c5feaae.esm.js} +1 -1
- package/dist/{resolve-hooks-165a9ce2.cjs.js → resolve-hooks-10a5f84c.cjs.js} +240 -6
- package/dist/{resolve-hooks-6813a045.esm.js → resolve-hooks-9e676794.esm.js} +238 -7
- package/dist/{system-a321642d.cjs.js → system-6b37a5f8.cjs.js} +33 -7
- package/dist/{system-03e49e4f.esm.js → system-e591d821.esm.js} +33 -7
- package/fields/dist/nixxie-cms-core-fields.cjs.js +29 -576
- package/fields/dist/nixxie-cms-core-fields.esm.js +18 -565
- package/fields/types/bytes/dist/nixxie-cms-core-fields-types-bytes.cjs.js +4 -2
- package/fields/types/bytes/dist/nixxie-cms-core-fields-types-bytes.esm.js +4 -2
- package/fields/types/multiselect/views/dist/nixxie-cms-core-fields-types-multiselect-views.cjs.js +1 -6
- package/fields/types/multiselect/views/dist/nixxie-cms-core-fields-types-multiselect-views.esm.js +1 -6
- package/fields/types/password/dist/nixxie-cms-core-fields-types-password.cjs.js +4 -2
- package/fields/types/password/dist/nixxie-cms-core-fields-types-password.esm.js +4 -2
- package/internal-unstable/artifacts/dist/nixxie-cms-core-internal-unstable-artifacts.cjs.js +4 -3
- package/internal-unstable/artifacts/dist/nixxie-cms-core-internal-unstable-artifacts.esm.js +4 -3
- package/package.json +4 -4
- package/scripts/cli/dist/nixxie-cms-core-scripts-cli.cjs.js +4 -3
- package/scripts/cli/dist/nixxie-cms-core-scripts-cli.esm.js +4 -3
- package/scripts/dist/nixxie-cms-core-scripts.cjs.js +4 -3
- package/scripts/dist/nixxie-cms-core-scripts.esm.js +4 -3
- package/session/dist/nixxie-cms-core-session.cjs.js +286 -0
- package/session/dist/nixxie-cms-core-session.esm.js +279 -1
- package/src/access.ts +25 -25
- package/src/admin-ui/admin-meta-graphql.ts +5 -5
- package/src/admin-ui/components/CreateButtonLink.tsx +46 -46
- package/src/admin-ui/components/Navigation.tsx +3 -3
- package/src/admin-ui/context.tsx +6 -6
- package/src/admin-ui/utils/Fields.tsx +241 -241
- package/src/admin-ui/utils/actionData.ts +36 -36
- package/src/admin-ui/utils/filters.ts +148 -148
- package/src/admin-ui/utils/useCreateItem.ts +171 -171
- package/src/admin-ui/utils/utils.tsx +127 -127
- package/src/context.ts +1 -1
- package/src/fields/non-null-graphql.ts +115 -115
- package/src/fields/types/bigInt/index.ts +6 -6
- package/src/fields/types/bytes/index.ts +6 -6
- package/src/fields/types/calendarDay/index.ts +18 -19
- package/src/fields/types/checkbox/index.ts +6 -6
- package/src/fields/types/decimal/index.ts +6 -6
- package/src/fields/types/file/index.ts +8 -8
- package/src/fields/types/float/index.ts +6 -6
- package/src/fields/types/image/index.ts +8 -8
- package/src/fields/types/integer/index.ts +6 -6
- package/src/fields/types/json/index.ts +5 -5
- package/src/fields/types/multiselect/index.ts +7 -7
- package/src/fields/types/multiselect/views/index.tsx +149 -151
- package/src/fields/types/password/index.ts +6 -6
- package/src/fields/types/relationship/index.ts +13 -13
- package/src/fields/types/relationship/views/ComboboxMany.tsx +110 -110
- package/src/fields/types/relationship/views/ComboboxSingle.tsx +115 -115
- package/src/fields/types/relationship/views/ContextualActions.tsx +139 -139
- package/src/fields/types/relationship/views/index.tsx +492 -492
- package/src/fields/types/relationship/views/types.ts +46 -46
- package/src/fields/types/relationship/views/useApolloQuery.ts +185 -185
- package/src/fields/types/relationship/views/useFilter.tsx +109 -109
- package/src/fields/types/select/index.ts +6 -6
- package/src/fields/types/text/index.ts +6 -6
- package/src/fields/types/timestamp/index.ts +23 -21
- package/src/fields/types/virtual/index.ts +11 -11
- package/src/helpers.ts +773 -42
- package/src/index.ts +66 -24
- package/src/internal-unstable/admin-ui/pages/ItemPage/common.tsx +4 -4
- package/src/internal-unstable/admin-ui/pages/ItemPage/index.tsx +5 -5
- package/src/internal-unstable/admin-ui/pages/ListPage/index.tsx +8 -8
- package/src/lib/admin-meta.ts +369 -369
- package/src/lib/context/createContext.ts +6 -0
- package/src/lib/core/access-control.ts +434 -434
- package/src/lib/core/cascade.ts +236 -0
- package/src/lib/core/initialise-lists.ts +49 -33
- package/src/lib/core/mutations/index.ts +7 -0
- package/src/lib/core/mutations/nested-mutation-many-input-resolvers.ts +145 -145
- package/src/lib/core/mutations/nested-mutation-one-input-resolvers.ts +71 -71
- package/src/lib/core/queries/output-field.ts +178 -178
- package/src/lib/env.ts +50 -0
- package/src/lib/id-field.ts +2 -2
- package/src/lib/system.ts +221 -207
- package/src/lib/typescript-schema-printer.ts +227 -227
- package/src/list-features.ts +476 -0
- package/src/schema.ts +92 -22
- package/src/session.ts +225 -0
- package/src/types/admin-meta.ts +218 -218
- package/src/types/config/access-control.ts +186 -186
- package/src/types/config/fields.ts +96 -96
- package/src/types/config/hooks.ts +529 -529
- package/src/types/config/index.ts +206 -7
- package/src/types/config/lists.ts +606 -565
- package/src/types/context.ts +592 -55
- package/src/types/next-fields.ts +31 -31
- package/src/types/type-info.ts +38 -38
- package/src/types/type-tests.ts +21 -21
|
@@ -1,186 +1,186 @@
|
|
|
1
|
-
import type { NixxieContext } from '../context'
|
|
2
|
-
import type {
|
|
3
|
-
import type { MaybePromise } from '../utils'
|
|
4
|
-
|
|
5
|
-
export type BaseAccessArgs<
|
|
6
|
-
context: NixxieContext<
|
|
7
|
-
session?:
|
|
8
|
-
listKey:
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
export type AccessOperation = 'create' | 'query' | 'update' | 'delete'
|
|
12
|
-
export type FilterOperation = 'query' | 'update' | 'delete'
|
|
13
|
-
export type ItemOperation = 'create' | 'update' | 'delete'
|
|
14
|
-
|
|
15
|
-
export type
|
|
16
|
-
Operation extends AccessOperation,
|
|
17
|
-
|
|
18
|
-
> = (args: BaseAccessArgs<
|
|
19
|
-
|
|
20
|
-
export type
|
|
21
|
-
Operation extends FilterOperation,
|
|
22
|
-
|
|
23
|
-
> = (
|
|
24
|
-
args: BaseAccessArgs<
|
|
25
|
-
) => MaybePromise<boolean |
|
|
26
|
-
|
|
27
|
-
export type
|
|
28
|
-
Operation extends ItemOperation,
|
|
29
|
-
|
|
30
|
-
> = (
|
|
31
|
-
args: BaseAccessArgs<
|
|
32
|
-
{
|
|
33
|
-
create: {
|
|
34
|
-
operation: 'create'
|
|
35
|
-
|
|
36
|
-
/**
|
|
37
|
-
* The input passed in from the GraphQL API
|
|
38
|
-
*/
|
|
39
|
-
inputData:
|
|
40
|
-
}
|
|
41
|
-
update: {
|
|
42
|
-
operation: 'update'
|
|
43
|
-
|
|
44
|
-
/**
|
|
45
|
-
* The input passed in from the GraphQL API
|
|
46
|
-
*/
|
|
47
|
-
inputData:
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
* The item being updated
|
|
51
|
-
*/
|
|
52
|
-
item:
|
|
53
|
-
}
|
|
54
|
-
delete: {
|
|
55
|
-
operation: 'delete'
|
|
56
|
-
|
|
57
|
-
/**
|
|
58
|
-
* The item being deleted
|
|
59
|
-
*/
|
|
60
|
-
item:
|
|
61
|
-
}
|
|
62
|
-
}[Operation]
|
|
63
|
-
) => MaybePromise<boolean>
|
|
64
|
-
|
|
65
|
-
export type
|
|
66
|
-
|
|
67
|
-
export type
|
|
68
|
-
|
|
69
|
-
export type
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
type
|
|
73
|
-
args: BaseAccessArgs<
|
|
74
|
-
) => MaybePromise<boolean>
|
|
75
|
-
|
|
76
|
-
type
|
|
77
|
-
// these functions should return `true` if access is allowed or `false` if access is denied.
|
|
78
|
-
operation:
|
|
79
|
-
|
|
|
80
|
-
| {
|
|
81
|
-
query:
|
|
82
|
-
create:
|
|
83
|
-
update:
|
|
84
|
-
delete:
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
// The 'filter' rules can return either:
|
|
88
|
-
// - a filter. In this case, the operation can proceed, but the filter will be additionally applied when updating/reading/deleting
|
|
89
|
-
// which may make it appear that some of the items don't exist.
|
|
90
|
-
// - boolean true/false. If false, treated as a filter that never matches.
|
|
91
|
-
filter?: {
|
|
92
|
-
query?:
|
|
93
|
-
// create?: not supported
|
|
94
|
-
update?:
|
|
95
|
-
delete?:
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
// These rules are applied to each item being operated on individually. They return `true` or `false`,
|
|
99
|
-
// and if false, an access denied error will be returned for the individual operation.
|
|
100
|
-
item?: {
|
|
101
|
-
// read?: not supported // TODO: why not
|
|
102
|
-
create?:
|
|
103
|
-
update?:
|
|
104
|
-
delete?:
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
// List level access control lets you set permissions on the autogenerated CRUD API for each list.
|
|
109
|
-
//
|
|
110
|
-
// * `operation` access lets you check the information in the `context` and `session` objects to decide if the
|
|
111
|
-
// user is allow to access the list.
|
|
112
|
-
// * `filter` access lets you provide a GraphQL filter which defines the items the user is allowed to access.
|
|
113
|
-
// * `item` access lets you write a function which inspects the provided input data and the existing object (if it exists)
|
|
114
|
-
// and make a decision based on this extra data.
|
|
115
|
-
//
|
|
116
|
-
// If access is denied due to any of the access control methods then the following response will be returned from the GraphQL API:
|
|
117
|
-
// Mutations:
|
|
118
|
-
// - Single operations will return `null` and return an access denied error
|
|
119
|
-
// - Multi operations will return a data array with `null` values for the items which have access denied.
|
|
120
|
-
// Access denied errors will be return for each `null` items.
|
|
121
|
-
// Queries:
|
|
122
|
-
// - Single item queries will return `null` with no errors.
|
|
123
|
-
// - Many item queries will filter out those items which have access denied, with no errors.
|
|
124
|
-
// - Count queries will only count those items for which access is not denied, with no errors.
|
|
125
|
-
//
|
|
126
|
-
export type
|
|
127
|
-
|
|
|
128
|
-
|
|
|
129
|
-
|
|
130
|
-
// Field Access
|
|
131
|
-
export type FieldAccessControlFunction<Args> = (args: Args) => MaybePromise<boolean>
|
|
132
|
-
|
|
133
|
-
export type FieldCreateItemAccessArgs<
|
|
134
|
-
BaseAccessArgs<
|
|
135
|
-
operation: 'create'
|
|
136
|
-
fieldKey: string
|
|
137
|
-
/**
|
|
138
|
-
* The input passed in from the GraphQL API
|
|
139
|
-
*/
|
|
140
|
-
inputData:
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
export type FieldReadItemAccessArgs<
|
|
144
|
-
BaseAccessArgs<
|
|
145
|
-
operation: 'read'
|
|
146
|
-
fieldKey: string
|
|
147
|
-
/**
|
|
148
|
-
* The item being read
|
|
149
|
-
*/
|
|
150
|
-
item:
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
export type FieldUpdateItemAccessArgs<
|
|
154
|
-
BaseAccessArgs<
|
|
155
|
-
operation: 'update'
|
|
156
|
-
fieldKey: string
|
|
157
|
-
/**
|
|
158
|
-
* The item being updated
|
|
159
|
-
*/
|
|
160
|
-
item:
|
|
161
|
-
/**
|
|
162
|
-
* The input passed in from the GraphQL API
|
|
163
|
-
*/
|
|
164
|
-
inputData:
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
export type FieldAccessControl<
|
|
168
|
-
| FieldAccessControlFunction<
|
|
169
|
-
| FieldReadItemAccessArgs<
|
|
170
|
-
| FieldCreateItemAccessArgs<
|
|
171
|
-
| FieldUpdateItemAccessArgs<
|
|
172
|
-
// delete: not supported
|
|
173
|
-
>
|
|
174
|
-
| {
|
|
175
|
-
read?: FieldAccessControlFunction<FieldReadItemAccessArgs<
|
|
176
|
-
create?: FieldAccessControlFunction<FieldCreateItemAccessArgs<
|
|
177
|
-
update?: FieldAccessControlFunction<FieldUpdateItemAccessArgs<
|
|
178
|
-
// delete: not supported
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
// Action Access
|
|
182
|
-
export type ActionAccessControlFunction<
|
|
183
|
-
args: BaseAccessArgs<
|
|
184
|
-
actionKey: string
|
|
185
|
-
}
|
|
186
|
-
) => MaybePromise<boolean>
|
|
1
|
+
import type { NixxieContext } from '../context'
|
|
2
|
+
import type { BaseCollectionTypeInfo } from '../type-info'
|
|
3
|
+
import type { MaybePromise } from '../utils'
|
|
4
|
+
|
|
5
|
+
export type BaseAccessArgs<CollectionTypeInfo extends BaseCollectionTypeInfo> = {
|
|
6
|
+
context: NixxieContext<CollectionTypeInfo['all']>
|
|
7
|
+
session?: CollectionTypeInfo['all']['session'] // TODO: use context.session, remove in breaking change
|
|
8
|
+
listKey: CollectionTypeInfo['key']
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export type AccessOperation = 'create' | 'query' | 'update' | 'delete'
|
|
12
|
+
export type FilterOperation = 'query' | 'update' | 'delete'
|
|
13
|
+
export type ItemOperation = 'create' | 'update' | 'delete'
|
|
14
|
+
|
|
15
|
+
export type CollectionOperationAccessControl<
|
|
16
|
+
Operation extends AccessOperation,
|
|
17
|
+
CollectionTypeInfo extends BaseCollectionTypeInfo,
|
|
18
|
+
> = (args: BaseAccessArgs<CollectionTypeInfo> & { operation: Operation }) => MaybePromise<boolean>
|
|
19
|
+
|
|
20
|
+
export type CollectionFilterAccessControl<
|
|
21
|
+
Operation extends FilterOperation,
|
|
22
|
+
CollectionTypeInfo extends BaseCollectionTypeInfo,
|
|
23
|
+
> = (
|
|
24
|
+
args: BaseAccessArgs<CollectionTypeInfo> & { operation: Operation }
|
|
25
|
+
) => MaybePromise<boolean | CollectionTypeInfo['inputs']['where']>
|
|
26
|
+
|
|
27
|
+
export type CollectionItemAccessControl<
|
|
28
|
+
Operation extends ItemOperation,
|
|
29
|
+
CollectionTypeInfo extends BaseCollectionTypeInfo,
|
|
30
|
+
> = (
|
|
31
|
+
args: BaseAccessArgs<CollectionTypeInfo> &
|
|
32
|
+
{
|
|
33
|
+
create: {
|
|
34
|
+
operation: 'create'
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* The input passed in from the GraphQL API
|
|
38
|
+
*/
|
|
39
|
+
inputData: CollectionTypeInfo['inputs']['create']
|
|
40
|
+
}
|
|
41
|
+
update: {
|
|
42
|
+
operation: 'update'
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* The input passed in from the GraphQL API
|
|
46
|
+
*/
|
|
47
|
+
inputData: CollectionTypeInfo['inputs']['update']
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* The item being updated
|
|
51
|
+
*/
|
|
52
|
+
item: CollectionTypeInfo['item']
|
|
53
|
+
}
|
|
54
|
+
delete: {
|
|
55
|
+
operation: 'delete'
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* The item being deleted
|
|
59
|
+
*/
|
|
60
|
+
item: CollectionTypeInfo['item']
|
|
61
|
+
}
|
|
62
|
+
}[Operation]
|
|
63
|
+
) => MaybePromise<boolean>
|
|
64
|
+
|
|
65
|
+
export type CreateCollectionItemAccessControl<CollectionTypeInfo extends BaseCollectionTypeInfo> =
|
|
66
|
+
CollectionItemAccessControl<'create', CollectionTypeInfo>
|
|
67
|
+
export type UpdateCollectionItemAccessControl<CollectionTypeInfo extends BaseCollectionTypeInfo> =
|
|
68
|
+
CollectionItemAccessControl<'update', CollectionTypeInfo>
|
|
69
|
+
export type DeleteCollectionItemAccessControl<CollectionTypeInfo extends BaseCollectionTypeInfo> =
|
|
70
|
+
CollectionItemAccessControl<'delete', CollectionTypeInfo>
|
|
71
|
+
|
|
72
|
+
type CollectionAccessControlFunction<CollectionTypeInfo extends BaseCollectionTypeInfo> = (
|
|
73
|
+
args: BaseAccessArgs<CollectionTypeInfo> & { operation: AccessOperation }
|
|
74
|
+
) => MaybePromise<boolean>
|
|
75
|
+
|
|
76
|
+
type CollectionAccessControlObject<CollectionTypeInfo extends BaseCollectionTypeInfo> = {
|
|
77
|
+
// these functions should return `true` if access is allowed or `false` if access is denied.
|
|
78
|
+
operation:
|
|
79
|
+
| CollectionOperationAccessControl<AccessOperation, CollectionTypeInfo>
|
|
80
|
+
| {
|
|
81
|
+
query: CollectionOperationAccessControl<'query', CollectionTypeInfo>
|
|
82
|
+
create: CollectionOperationAccessControl<'create', CollectionTypeInfo>
|
|
83
|
+
update: CollectionOperationAccessControl<'update', CollectionTypeInfo>
|
|
84
|
+
delete: CollectionOperationAccessControl<'delete', CollectionTypeInfo>
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// The 'filter' rules can return either:
|
|
88
|
+
// - a filter. In this case, the operation can proceed, but the filter will be additionally applied when updating/reading/deleting
|
|
89
|
+
// which may make it appear that some of the items don't exist.
|
|
90
|
+
// - boolean true/false. If false, treated as a filter that never matches.
|
|
91
|
+
filter?: {
|
|
92
|
+
query?: CollectionFilterAccessControl<'query', CollectionTypeInfo>
|
|
93
|
+
// create?: not supported
|
|
94
|
+
update?: CollectionFilterAccessControl<'update', CollectionTypeInfo>
|
|
95
|
+
delete?: CollectionFilterAccessControl<'delete', CollectionTypeInfo>
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// These rules are applied to each item being operated on individually. They return `true` or `false`,
|
|
99
|
+
// and if false, an access denied error will be returned for the individual operation.
|
|
100
|
+
item?: {
|
|
101
|
+
// read?: not supported // TODO: why not
|
|
102
|
+
create?: CollectionItemAccessControl<'create', CollectionTypeInfo>
|
|
103
|
+
update?: CollectionItemAccessControl<'update', CollectionTypeInfo>
|
|
104
|
+
delete?: CollectionItemAccessControl<'delete', CollectionTypeInfo>
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// List level access control lets you set permissions on the autogenerated CRUD API for each list.
|
|
109
|
+
//
|
|
110
|
+
// * `operation` access lets you check the information in the `context` and `session` objects to decide if the
|
|
111
|
+
// user is allow to access the list.
|
|
112
|
+
// * `filter` access lets you provide a GraphQL filter which defines the items the user is allowed to access.
|
|
113
|
+
// * `item` access lets you write a function which inspects the provided input data and the existing object (if it exists)
|
|
114
|
+
// and make a decision based on this extra data.
|
|
115
|
+
//
|
|
116
|
+
// If access is denied due to any of the access control methods then the following response will be returned from the GraphQL API:
|
|
117
|
+
// Mutations:
|
|
118
|
+
// - Single operations will return `null` and return an access denied error
|
|
119
|
+
// - Multi operations will return a data array with `null` values for the items which have access denied.
|
|
120
|
+
// Access denied errors will be return for each `null` items.
|
|
121
|
+
// Queries:
|
|
122
|
+
// - Single item queries will return `null` with no errors.
|
|
123
|
+
// - Many item queries will filter out those items which have access denied, with no errors.
|
|
124
|
+
// - Count queries will only count those items for which access is not denied, with no errors.
|
|
125
|
+
//
|
|
126
|
+
export type CollectionAccessControl<CollectionTypeInfo extends BaseCollectionTypeInfo> =
|
|
127
|
+
| CollectionAccessControlFunction<CollectionTypeInfo>
|
|
128
|
+
| CollectionAccessControlObject<CollectionTypeInfo>
|
|
129
|
+
|
|
130
|
+
// Field Access
|
|
131
|
+
export type FieldAccessControlFunction<Args> = (args: Args) => MaybePromise<boolean>
|
|
132
|
+
|
|
133
|
+
export type FieldCreateItemAccessArgs<CollectionTypeInfo extends BaseCollectionTypeInfo> =
|
|
134
|
+
BaseAccessArgs<CollectionTypeInfo> & {
|
|
135
|
+
operation: 'create'
|
|
136
|
+
fieldKey: string
|
|
137
|
+
/**
|
|
138
|
+
* The input passed in from the GraphQL API
|
|
139
|
+
*/
|
|
140
|
+
inputData: CollectionTypeInfo['inputs']['create']
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
export type FieldReadItemAccessArgs<CollectionTypeInfo extends BaseCollectionTypeInfo> =
|
|
144
|
+
BaseAccessArgs<CollectionTypeInfo> & {
|
|
145
|
+
operation: 'read'
|
|
146
|
+
fieldKey: string
|
|
147
|
+
/**
|
|
148
|
+
* The item being read
|
|
149
|
+
*/
|
|
150
|
+
item: CollectionTypeInfo['item']
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
export type FieldUpdateItemAccessArgs<CollectionTypeInfo extends BaseCollectionTypeInfo> =
|
|
154
|
+
BaseAccessArgs<CollectionTypeInfo> & {
|
|
155
|
+
operation: 'update'
|
|
156
|
+
fieldKey: string
|
|
157
|
+
/**
|
|
158
|
+
* The item being updated
|
|
159
|
+
*/
|
|
160
|
+
item: CollectionTypeInfo['item']
|
|
161
|
+
/**
|
|
162
|
+
* The input passed in from the GraphQL API
|
|
163
|
+
*/
|
|
164
|
+
inputData: CollectionTypeInfo['inputs']['update']
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
export type FieldAccessControl<CollectionTypeInfo extends BaseCollectionTypeInfo> =
|
|
168
|
+
| FieldAccessControlFunction<
|
|
169
|
+
| FieldReadItemAccessArgs<CollectionTypeInfo>
|
|
170
|
+
| FieldCreateItemAccessArgs<CollectionTypeInfo>
|
|
171
|
+
| FieldUpdateItemAccessArgs<CollectionTypeInfo>
|
|
172
|
+
// delete: not supported
|
|
173
|
+
>
|
|
174
|
+
| {
|
|
175
|
+
read?: FieldAccessControlFunction<FieldReadItemAccessArgs<CollectionTypeInfo>>
|
|
176
|
+
create?: FieldAccessControlFunction<FieldCreateItemAccessArgs<CollectionTypeInfo>>
|
|
177
|
+
update?: FieldAccessControlFunction<FieldUpdateItemAccessArgs<CollectionTypeInfo>>
|
|
178
|
+
// delete: not supported
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
// Action Access
|
|
182
|
+
export type ActionAccessControlFunction<CollectionTypeInfo extends BaseCollectionTypeInfo> = (
|
|
183
|
+
args: BaseAccessArgs<CollectionTypeInfo> & {
|
|
184
|
+
actionKey: string
|
|
185
|
+
}
|
|
186
|
+
) => MaybePromise<boolean>
|
|
@@ -1,96 +1,96 @@
|
|
|
1
|
-
import type { CacheHint } from '@apollo/cache-control-types'
|
|
2
|
-
import type { NixxieContext } from '..'
|
|
3
|
-
import type { FieldTypeFunc } from '../next-fields'
|
|
4
|
-
import type {
|
|
5
|
-
import type { FieldAccessControl } from './access-control'
|
|
6
|
-
import type { FieldHooks } from './hooks'
|
|
7
|
-
import type {
|
|
8
|
-
MaybeBooleanSessionFunctionWithFilter,
|
|
9
|
-
MaybeFieldFunction,
|
|
10
|
-
MaybeItemFieldFunction,
|
|
11
|
-
MaybeItemFieldFunctionWithFilter,
|
|
12
|
-
MaybeSessionFunction,
|
|
13
|
-
MaybeSessionFunctionWithFilter,
|
|
14
|
-
} from './lists'
|
|
15
|
-
|
|
16
|
-
export type BaseFields<
|
|
17
|
-
[key: string]: FieldTypeFunc<
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
export type FilterOrderArgs<
|
|
21
|
-
context: NixxieContext<
|
|
22
|
-
session?:
|
|
23
|
-
listKey:
|
|
24
|
-
fieldKey:
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
export type BaseFieldTypeInfo = {
|
|
28
|
-
item: any
|
|
29
|
-
inputs: {
|
|
30
|
-
create: any
|
|
31
|
-
update: any
|
|
32
|
-
where: any
|
|
33
|
-
uniqueWhere: any
|
|
34
|
-
orderBy: any
|
|
35
|
-
}
|
|
36
|
-
prisma: {
|
|
37
|
-
create: any
|
|
38
|
-
update: any
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
export type CommonFieldConfig<
|
|
43
|
-
|
|
44
|
-
FieldTypeInfo extends BaseFieldTypeInfo,
|
|
45
|
-
> = {
|
|
46
|
-
access?: FieldAccessControl<
|
|
47
|
-
hooks?: FieldHooks<
|
|
48
|
-
ui?: {
|
|
49
|
-
label?: string
|
|
50
|
-
description?: string
|
|
51
|
-
views?: string
|
|
52
|
-
createView?: {
|
|
53
|
-
fieldMode?: MaybeSessionFunctionWithFilter<'edit' | 'hidden', 'hidden',
|
|
54
|
-
isRequired?: MaybeBooleanSessionFunctionWithFilter<
|
|
55
|
-
}
|
|
56
|
-
itemView?: {
|
|
57
|
-
fieldMode?: MaybeItemFieldFunctionWithFilter<
|
|
58
|
-
'edit' | 'read' | 'hidden',
|
|
59
|
-
'read' | 'hidden',
|
|
60
|
-
|
|
61
|
-
FieldTypeInfo
|
|
62
|
-
>
|
|
63
|
-
fieldPosition?: MaybeItemFieldFunction<'form' | 'sidebar',
|
|
64
|
-
isRequired?: MaybeBooleanSessionFunctionWithFilter<
|
|
65
|
-
}
|
|
66
|
-
listView?: {
|
|
67
|
-
fieldMode?: MaybeSessionFunction<'read' | 'hidden',
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
graphql?: {
|
|
71
|
-
cacheHint?: CacheHint
|
|
72
|
-
isNonNull?:
|
|
73
|
-
| boolean
|
|
74
|
-
| {
|
|
75
|
-
// whether this field is non-nullable on the {List} GraphQL type
|
|
76
|
-
read?: boolean
|
|
77
|
-
// whether this field is non-nullable on the {List}CreateInput GraphQL type
|
|
78
|
-
create?: boolean
|
|
79
|
-
// whether this field is non-nullable on the {List}UpdateInput GraphQL type
|
|
80
|
-
update?: boolean
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
omit?:
|
|
84
|
-
| boolean
|
|
85
|
-
| {
|
|
86
|
-
// whether this field is omitted from the {List} GraphQL type
|
|
87
|
-
read?: boolean
|
|
88
|
-
// whether this field is omitted from the {List}CreateInput GraphQL type
|
|
89
|
-
create?: boolean
|
|
90
|
-
// whether this field is omitted from the {List}UpdateInput GraphQL type
|
|
91
|
-
update?: boolean
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
isFilterable?: MaybeFieldFunction<
|
|
95
|
-
isOrderable?: MaybeFieldFunction<
|
|
96
|
-
}
|
|
1
|
+
import type { CacheHint } from '@apollo/cache-control-types'
|
|
2
|
+
import type { NixxieContext } from '..'
|
|
3
|
+
import type { FieldTypeFunc } from '../next-fields'
|
|
4
|
+
import type { BaseCollectionTypeInfo } from '../type-info'
|
|
5
|
+
import type { FieldAccessControl } from './access-control'
|
|
6
|
+
import type { FieldHooks } from './hooks'
|
|
7
|
+
import type {
|
|
8
|
+
MaybeBooleanSessionFunctionWithFilter,
|
|
9
|
+
MaybeFieldFunction,
|
|
10
|
+
MaybeItemFieldFunction,
|
|
11
|
+
MaybeItemFieldFunctionWithFilter,
|
|
12
|
+
MaybeSessionFunction,
|
|
13
|
+
MaybeSessionFunctionWithFilter,
|
|
14
|
+
} from './lists'
|
|
15
|
+
|
|
16
|
+
export type BaseFields<CollectionTypeInfo extends BaseCollectionTypeInfo> = {
|
|
17
|
+
[key: string]: FieldTypeFunc<CollectionTypeInfo>
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export type FilterOrderArgs<CollectionTypeInfo extends BaseCollectionTypeInfo> = {
|
|
21
|
+
context: NixxieContext<CollectionTypeInfo['all']>
|
|
22
|
+
session?: CollectionTypeInfo['all']['session']
|
|
23
|
+
listKey: CollectionTypeInfo['key']
|
|
24
|
+
fieldKey: CollectionTypeInfo['fields']
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export type BaseFieldTypeInfo = {
|
|
28
|
+
item: any
|
|
29
|
+
inputs: {
|
|
30
|
+
create: any
|
|
31
|
+
update: any
|
|
32
|
+
where: any
|
|
33
|
+
uniqueWhere: any
|
|
34
|
+
orderBy: any
|
|
35
|
+
}
|
|
36
|
+
prisma: {
|
|
37
|
+
create: any
|
|
38
|
+
update: any
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export type CommonFieldConfig<
|
|
43
|
+
CollectionTypeInfo extends BaseCollectionTypeInfo,
|
|
44
|
+
FieldTypeInfo extends BaseFieldTypeInfo,
|
|
45
|
+
> = {
|
|
46
|
+
access?: FieldAccessControl<CollectionTypeInfo>
|
|
47
|
+
hooks?: FieldHooks<CollectionTypeInfo, FieldTypeInfo>
|
|
48
|
+
ui?: {
|
|
49
|
+
label?: string
|
|
50
|
+
description?: string
|
|
51
|
+
views?: string
|
|
52
|
+
createView?: {
|
|
53
|
+
fieldMode?: MaybeSessionFunctionWithFilter<'edit' | 'hidden', 'hidden', CollectionTypeInfo>
|
|
54
|
+
isRequired?: MaybeBooleanSessionFunctionWithFilter<CollectionTypeInfo>
|
|
55
|
+
}
|
|
56
|
+
itemView?: {
|
|
57
|
+
fieldMode?: MaybeItemFieldFunctionWithFilter<
|
|
58
|
+
'edit' | 'read' | 'hidden',
|
|
59
|
+
'read' | 'hidden',
|
|
60
|
+
CollectionTypeInfo,
|
|
61
|
+
FieldTypeInfo
|
|
62
|
+
>
|
|
63
|
+
fieldPosition?: MaybeItemFieldFunction<'form' | 'sidebar', CollectionTypeInfo, FieldTypeInfo>
|
|
64
|
+
isRequired?: MaybeBooleanSessionFunctionWithFilter<CollectionTypeInfo>
|
|
65
|
+
}
|
|
66
|
+
listView?: {
|
|
67
|
+
fieldMode?: MaybeSessionFunction<'read' | 'hidden', CollectionTypeInfo>
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
graphql?: {
|
|
71
|
+
cacheHint?: CacheHint
|
|
72
|
+
isNonNull?:
|
|
73
|
+
| boolean
|
|
74
|
+
| {
|
|
75
|
+
// whether this field is non-nullable on the {List} GraphQL type
|
|
76
|
+
read?: boolean
|
|
77
|
+
// whether this field is non-nullable on the {List}CreateInput GraphQL type
|
|
78
|
+
create?: boolean
|
|
79
|
+
// whether this field is non-nullable on the {List}UpdateInput GraphQL type
|
|
80
|
+
update?: boolean
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
omit?:
|
|
84
|
+
| boolean
|
|
85
|
+
| {
|
|
86
|
+
// whether this field is omitted from the {List} GraphQL type
|
|
87
|
+
read?: boolean
|
|
88
|
+
// whether this field is omitted from the {List}CreateInput GraphQL type
|
|
89
|
+
create?: boolean
|
|
90
|
+
// whether this field is omitted from the {List}UpdateInput GraphQL type
|
|
91
|
+
update?: boolean
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
isFilterable?: MaybeFieldFunction<CollectionTypeInfo>
|
|
95
|
+
isOrderable?: MaybeFieldFunction<CollectionTypeInfo>
|
|
96
|
+
}
|