@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.
Files changed (203) hide show
  1. package/CHANGELOG.md +36 -0
  2. package/CHANGES-1.1.md +134 -0
  3. package/context/dist/nixxie-cms-core-context.cjs.js +4 -3
  4. package/context/dist/nixxie-cms-core-context.esm.js +3 -2
  5. package/dist/declarations/src/access.d.ts +2 -2
  6. package/dist/declarations/src/access.d.ts.map +1 -1
  7. package/dist/declarations/src/admin-ui/components/Navigation.d.ts +2 -2
  8. package/dist/declarations/src/admin-ui/components/Navigation.d.ts.map +1 -1
  9. package/dist/declarations/src/admin-ui/context.d.ts +6 -6
  10. package/dist/declarations/src/admin-ui/context.d.ts.map +1 -1
  11. package/dist/declarations/src/admin-ui/utils/Fields.d.ts +3 -3
  12. package/dist/declarations/src/admin-ui/utils/Fields.d.ts.map +1 -1
  13. package/dist/declarations/src/admin-ui/utils/filters.d.ts +5 -5
  14. package/dist/declarations/src/admin-ui/utils/filters.d.ts.map +1 -1
  15. package/dist/declarations/src/admin-ui/utils/useCreateItem.d.ts +3 -3
  16. package/dist/declarations/src/admin-ui/utils/useCreateItem.d.ts.map +1 -1
  17. package/dist/declarations/src/admin-ui/utils/utils.d.ts +2 -2
  18. package/dist/declarations/src/admin-ui/utils/utils.d.ts.map +1 -1
  19. package/dist/declarations/src/context.d.ts +1 -1
  20. package/dist/declarations/src/context.d.ts.map +1 -1
  21. package/dist/declarations/src/fields/types/bigInt/index.d.ts +3 -3
  22. package/dist/declarations/src/fields/types/bigInt/index.d.ts.map +1 -1
  23. package/dist/declarations/src/fields/types/bytes/index.d.ts +3 -3
  24. package/dist/declarations/src/fields/types/bytes/index.d.ts.map +1 -1
  25. package/dist/declarations/src/fields/types/calendarDay/index.d.ts +3 -3
  26. package/dist/declarations/src/fields/types/calendarDay/index.d.ts.map +1 -1
  27. package/dist/declarations/src/fields/types/checkbox/index.d.ts +3 -3
  28. package/dist/declarations/src/fields/types/checkbox/index.d.ts.map +1 -1
  29. package/dist/declarations/src/fields/types/decimal/index.d.ts +3 -3
  30. package/dist/declarations/src/fields/types/decimal/index.d.ts.map +1 -1
  31. package/dist/declarations/src/fields/types/file/index.d.ts +4 -4
  32. package/dist/declarations/src/fields/types/file/index.d.ts.map +1 -1
  33. package/dist/declarations/src/fields/types/float/index.d.ts +3 -3
  34. package/dist/declarations/src/fields/types/float/index.d.ts.map +1 -1
  35. package/dist/declarations/src/fields/types/image/index.d.ts +4 -4
  36. package/dist/declarations/src/fields/types/image/index.d.ts.map +1 -1
  37. package/dist/declarations/src/fields/types/integer/index.d.ts +3 -3
  38. package/dist/declarations/src/fields/types/integer/index.d.ts.map +1 -1
  39. package/dist/declarations/src/fields/types/json/index.d.ts +3 -3
  40. package/dist/declarations/src/fields/types/json/index.d.ts.map +1 -1
  41. package/dist/declarations/src/fields/types/multiselect/index.d.ts +3 -3
  42. package/dist/declarations/src/fields/types/multiselect/index.d.ts.map +1 -1
  43. package/dist/declarations/src/fields/types/multiselect/views/index.d.ts.map +1 -1
  44. package/dist/declarations/src/fields/types/password/index.d.ts +3 -3
  45. package/dist/declarations/src/fields/types/password/index.d.ts.map +1 -1
  46. package/dist/declarations/src/fields/types/relationship/index.d.ts +8 -8
  47. package/dist/declarations/src/fields/types/relationship/index.d.ts.map +1 -1
  48. package/dist/declarations/src/fields/types/relationship/views/ComboboxMany.d.ts +3 -3
  49. package/dist/declarations/src/fields/types/relationship/views/ComboboxMany.d.ts.map +1 -1
  50. package/dist/declarations/src/fields/types/relationship/views/ComboboxSingle.d.ts +3 -3
  51. package/dist/declarations/src/fields/types/relationship/views/ComboboxSingle.d.ts.map +1 -1
  52. package/dist/declarations/src/fields/types/relationship/views/index.d.ts +3 -3
  53. package/dist/declarations/src/fields/types/relationship/views/index.d.ts.map +1 -1
  54. package/dist/declarations/src/fields/types/relationship/views/types.d.ts +3 -3
  55. package/dist/declarations/src/fields/types/relationship/views/types.d.ts.map +1 -1
  56. package/dist/declarations/src/fields/types/select/index.d.ts +3 -3
  57. package/dist/declarations/src/fields/types/select/index.d.ts.map +1 -1
  58. package/dist/declarations/src/fields/types/text/index.d.ts +3 -3
  59. package/dist/declarations/src/fields/types/text/index.d.ts.map +1 -1
  60. package/dist/declarations/src/fields/types/timestamp/index.d.ts +3 -3
  61. package/dist/declarations/src/fields/types/timestamp/index.d.ts.map +1 -1
  62. package/dist/declarations/src/fields/types/virtual/index.d.ts +7 -7
  63. package/dist/declarations/src/fields/types/virtual/index.d.ts.map +1 -1
  64. package/dist/declarations/src/helpers.d.ts +249 -13
  65. package/dist/declarations/src/helpers.d.ts.map +1 -1
  66. package/dist/declarations/src/index.d.ts +9 -4
  67. package/dist/declarations/src/index.d.ts.map +1 -1
  68. package/dist/declarations/src/internal-unstable/admin-ui/pages/ListPage/index.d.ts.map +1 -1
  69. package/dist/declarations/src/lib/admin-meta.d.ts +11 -11
  70. package/dist/declarations/src/lib/admin-meta.d.ts.map +1 -1
  71. package/dist/declarations/src/lib/core/access-control.d.ts +18 -18
  72. package/dist/declarations/src/lib/core/access-control.d.ts.map +1 -1
  73. package/dist/declarations/src/lib/core/cascade.d.ts +47 -0
  74. package/dist/declarations/src/lib/core/cascade.d.ts.map +1 -0
  75. package/dist/declarations/src/lib/core/initialise-lists.d.ts +27 -24
  76. package/dist/declarations/src/lib/core/initialise-lists.d.ts.map +1 -1
  77. package/dist/declarations/src/lib/env.d.ts +9 -0
  78. package/dist/declarations/src/lib/env.d.ts.map +1 -0
  79. package/dist/declarations/src/lib/system.d.ts +1 -1
  80. package/dist/declarations/src/lib/system.d.ts.map +1 -1
  81. package/dist/declarations/src/list-features.d.ts +162 -0
  82. package/dist/declarations/src/list-features.d.ts.map +1 -0
  83. package/dist/declarations/src/schema.d.ts +24 -23
  84. package/dist/declarations/src/schema.d.ts.map +1 -1
  85. package/dist/declarations/src/session.d.ts +75 -0
  86. package/dist/declarations/src/session.d.ts.map +1 -1
  87. package/dist/declarations/src/types/admin-meta.d.ts +11 -11
  88. package/dist/declarations/src/types/admin-meta.d.ts.map +1 -1
  89. package/dist/declarations/src/types/config/access-control.d.ts +42 -42
  90. package/dist/declarations/src/types/config/access-control.d.ts.map +1 -1
  91. package/dist/declarations/src/types/config/fields.d.ts +19 -19
  92. package/dist/declarations/src/types/config/fields.d.ts.map +1 -1
  93. package/dist/declarations/src/types/config/hooks.d.ts +131 -131
  94. package/dist/declarations/src/types/config/hooks.d.ts.map +1 -1
  95. package/dist/declarations/src/types/config/index.d.ts +190 -8
  96. package/dist/declarations/src/types/config/index.d.ts.map +1 -1
  97. package/dist/declarations/src/types/config/lists.d.ts +146 -108
  98. package/dist/declarations/src/types/config/lists.d.ts.map +1 -1
  99. package/dist/declarations/src/types/context.d.ts +507 -47
  100. package/dist/declarations/src/types/context.d.ts.map +1 -1
  101. package/dist/declarations/src/types/next-fields.d.ts +28 -28
  102. package/dist/declarations/src/types/next-fields.d.ts.map +1 -1
  103. package/dist/declarations/src/types/type-info.d.ts +3 -3
  104. package/dist/declarations/src/types/type-info.d.ts.map +1 -1
  105. package/dist/{express-455ae20c.cjs.js → express-84d534c2.cjs.js} +6 -6
  106. package/dist/{express-7559ca2d.esm.js → express-d0a4ce99.esm.js} +6 -6
  107. package/dist/{index-15c8f81e.esm.js → index-5d8b0b4e.esm.js} +363 -183
  108. package/dist/index-6055753b.cjs.js +393 -0
  109. package/dist/{index-42045902.cjs.js → index-ac29f382.cjs.js} +363 -185
  110. package/dist/index-f1703b7b.esm.js +386 -0
  111. package/dist/nixxie-cms-core.cjs.js +1388 -30
  112. package/dist/nixxie-cms-core.esm.js +1362 -24
  113. package/dist/{non-null-graphql-add6bb3d.cjs.js → non-null-graphql-4a44c122.cjs.js} +1 -1
  114. package/dist/{non-null-graphql-a84ed64d.esm.js → non-null-graphql-8c5feaae.esm.js} +1 -1
  115. package/dist/{resolve-hooks-165a9ce2.cjs.js → resolve-hooks-10a5f84c.cjs.js} +240 -6
  116. package/dist/{resolve-hooks-6813a045.esm.js → resolve-hooks-9e676794.esm.js} +238 -7
  117. package/dist/{system-a321642d.cjs.js → system-6b37a5f8.cjs.js} +33 -7
  118. package/dist/{system-03e49e4f.esm.js → system-e591d821.esm.js} +33 -7
  119. package/fields/dist/nixxie-cms-core-fields.cjs.js +29 -576
  120. package/fields/dist/nixxie-cms-core-fields.esm.js +18 -565
  121. package/fields/types/bytes/dist/nixxie-cms-core-fields-types-bytes.cjs.js +4 -2
  122. package/fields/types/bytes/dist/nixxie-cms-core-fields-types-bytes.esm.js +4 -2
  123. package/fields/types/multiselect/views/dist/nixxie-cms-core-fields-types-multiselect-views.cjs.js +1 -6
  124. package/fields/types/multiselect/views/dist/nixxie-cms-core-fields-types-multiselect-views.esm.js +1 -6
  125. package/fields/types/password/dist/nixxie-cms-core-fields-types-password.cjs.js +4 -2
  126. package/fields/types/password/dist/nixxie-cms-core-fields-types-password.esm.js +4 -2
  127. package/internal-unstable/artifacts/dist/nixxie-cms-core-internal-unstable-artifacts.cjs.js +4 -3
  128. package/internal-unstable/artifacts/dist/nixxie-cms-core-internal-unstable-artifacts.esm.js +4 -3
  129. package/package.json +4 -4
  130. package/scripts/cli/dist/nixxie-cms-core-scripts-cli.cjs.js +4 -3
  131. package/scripts/cli/dist/nixxie-cms-core-scripts-cli.esm.js +4 -3
  132. package/scripts/dist/nixxie-cms-core-scripts.cjs.js +4 -3
  133. package/scripts/dist/nixxie-cms-core-scripts.esm.js +4 -3
  134. package/session/dist/nixxie-cms-core-session.cjs.js +286 -0
  135. package/session/dist/nixxie-cms-core-session.esm.js +279 -1
  136. package/src/access.ts +25 -25
  137. package/src/admin-ui/admin-meta-graphql.ts +5 -5
  138. package/src/admin-ui/components/CreateButtonLink.tsx +46 -46
  139. package/src/admin-ui/components/Navigation.tsx +3 -3
  140. package/src/admin-ui/context.tsx +6 -6
  141. package/src/admin-ui/utils/Fields.tsx +241 -241
  142. package/src/admin-ui/utils/actionData.ts +36 -36
  143. package/src/admin-ui/utils/filters.ts +148 -148
  144. package/src/admin-ui/utils/useCreateItem.ts +171 -171
  145. package/src/admin-ui/utils/utils.tsx +127 -127
  146. package/src/context.ts +1 -1
  147. package/src/fields/non-null-graphql.ts +115 -115
  148. package/src/fields/types/bigInt/index.ts +6 -6
  149. package/src/fields/types/bytes/index.ts +6 -6
  150. package/src/fields/types/calendarDay/index.ts +18 -19
  151. package/src/fields/types/checkbox/index.ts +6 -6
  152. package/src/fields/types/decimal/index.ts +6 -6
  153. package/src/fields/types/file/index.ts +8 -8
  154. package/src/fields/types/float/index.ts +6 -6
  155. package/src/fields/types/image/index.ts +8 -8
  156. package/src/fields/types/integer/index.ts +6 -6
  157. package/src/fields/types/json/index.ts +5 -5
  158. package/src/fields/types/multiselect/index.ts +7 -7
  159. package/src/fields/types/multiselect/views/index.tsx +149 -151
  160. package/src/fields/types/password/index.ts +6 -6
  161. package/src/fields/types/relationship/index.ts +13 -13
  162. package/src/fields/types/relationship/views/ComboboxMany.tsx +110 -110
  163. package/src/fields/types/relationship/views/ComboboxSingle.tsx +115 -115
  164. package/src/fields/types/relationship/views/ContextualActions.tsx +139 -139
  165. package/src/fields/types/relationship/views/index.tsx +492 -492
  166. package/src/fields/types/relationship/views/types.ts +46 -46
  167. package/src/fields/types/relationship/views/useApolloQuery.ts +185 -185
  168. package/src/fields/types/relationship/views/useFilter.tsx +109 -109
  169. package/src/fields/types/select/index.ts +6 -6
  170. package/src/fields/types/text/index.ts +6 -6
  171. package/src/fields/types/timestamp/index.ts +23 -21
  172. package/src/fields/types/virtual/index.ts +11 -11
  173. package/src/helpers.ts +773 -42
  174. package/src/index.ts +66 -24
  175. package/src/internal-unstable/admin-ui/pages/ItemPage/common.tsx +4 -4
  176. package/src/internal-unstable/admin-ui/pages/ItemPage/index.tsx +5 -5
  177. package/src/internal-unstable/admin-ui/pages/ListPage/index.tsx +8 -8
  178. package/src/lib/admin-meta.ts +369 -369
  179. package/src/lib/context/createContext.ts +6 -0
  180. package/src/lib/core/access-control.ts +434 -434
  181. package/src/lib/core/cascade.ts +236 -0
  182. package/src/lib/core/initialise-lists.ts +49 -33
  183. package/src/lib/core/mutations/index.ts +7 -0
  184. package/src/lib/core/mutations/nested-mutation-many-input-resolvers.ts +145 -145
  185. package/src/lib/core/mutations/nested-mutation-one-input-resolvers.ts +71 -71
  186. package/src/lib/core/queries/output-field.ts +178 -178
  187. package/src/lib/env.ts +50 -0
  188. package/src/lib/id-field.ts +2 -2
  189. package/src/lib/system.ts +221 -207
  190. package/src/lib/typescript-schema-printer.ts +227 -227
  191. package/src/list-features.ts +476 -0
  192. package/src/schema.ts +92 -22
  193. package/src/session.ts +225 -0
  194. package/src/types/admin-meta.ts +218 -218
  195. package/src/types/config/access-control.ts +186 -186
  196. package/src/types/config/fields.ts +96 -96
  197. package/src/types/config/hooks.ts +529 -529
  198. package/src/types/config/index.ts +206 -7
  199. package/src/types/config/lists.ts +606 -565
  200. package/src/types/context.ts +592 -55
  201. package/src/types/next-fields.ts +31 -31
  202. package/src/types/type-info.ts +38 -38
  203. package/src/types/type-tests.ts +21 -21
@@ -1,186 +1,186 @@
1
- import type { NixxieContext } from '../context'
2
- import type { BaseListTypeInfo } from '../type-info'
3
- import type { MaybePromise } from '../utils'
4
-
5
- export type BaseAccessArgs<ListTypeInfo extends BaseListTypeInfo> = {
6
- context: NixxieContext<ListTypeInfo['all']>
7
- session?: ListTypeInfo['all']['session'] // TODO: use context.session, remove in breaking change
8
- listKey: ListTypeInfo['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 ListOperationAccessControl<
16
- Operation extends AccessOperation,
17
- ListTypeInfo extends BaseListTypeInfo,
18
- > = (args: BaseAccessArgs<ListTypeInfo> & { operation: Operation }) => MaybePromise<boolean>
19
-
20
- export type ListFilterAccessControl<
21
- Operation extends FilterOperation,
22
- ListTypeInfo extends BaseListTypeInfo,
23
- > = (
24
- args: BaseAccessArgs<ListTypeInfo> & { operation: Operation }
25
- ) => MaybePromise<boolean | ListTypeInfo['inputs']['where']>
26
-
27
- export type ListItemAccessControl<
28
- Operation extends ItemOperation,
29
- ListTypeInfo extends BaseListTypeInfo,
30
- > = (
31
- args: BaseAccessArgs<ListTypeInfo> &
32
- {
33
- create: {
34
- operation: 'create'
35
-
36
- /**
37
- * The input passed in from the GraphQL API
38
- */
39
- inputData: ListTypeInfo['inputs']['create']
40
- }
41
- update: {
42
- operation: 'update'
43
-
44
- /**
45
- * The input passed in from the GraphQL API
46
- */
47
- inputData: ListTypeInfo['inputs']['update']
48
-
49
- /**
50
- * The item being updated
51
- */
52
- item: ListTypeInfo['item']
53
- }
54
- delete: {
55
- operation: 'delete'
56
-
57
- /**
58
- * The item being deleted
59
- */
60
- item: ListTypeInfo['item']
61
- }
62
- }[Operation]
63
- ) => MaybePromise<boolean>
64
-
65
- export type CreateListItemAccessControl<ListTypeInfo extends BaseListTypeInfo> =
66
- ListItemAccessControl<'create', ListTypeInfo>
67
- export type UpdateListItemAccessControl<ListTypeInfo extends BaseListTypeInfo> =
68
- ListItemAccessControl<'update', ListTypeInfo>
69
- export type DeleteListItemAccessControl<ListTypeInfo extends BaseListTypeInfo> =
70
- ListItemAccessControl<'delete', ListTypeInfo>
71
-
72
- type ListAccessControlFunction<ListTypeInfo extends BaseListTypeInfo> = (
73
- args: BaseAccessArgs<ListTypeInfo> & { operation: AccessOperation }
74
- ) => MaybePromise<boolean>
75
-
76
- type ListAccessControlObject<ListTypeInfo extends BaseListTypeInfo> = {
77
- // these functions should return `true` if access is allowed or `false` if access is denied.
78
- operation:
79
- | ListOperationAccessControl<AccessOperation, ListTypeInfo>
80
- | {
81
- query: ListOperationAccessControl<'query', ListTypeInfo>
82
- create: ListOperationAccessControl<'create', ListTypeInfo>
83
- update: ListOperationAccessControl<'update', ListTypeInfo>
84
- delete: ListOperationAccessControl<'delete', ListTypeInfo>
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?: ListFilterAccessControl<'query', ListTypeInfo>
93
- // create?: not supported
94
- update?: ListFilterAccessControl<'update', ListTypeInfo>
95
- delete?: ListFilterAccessControl<'delete', ListTypeInfo>
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?: ListItemAccessControl<'create', ListTypeInfo>
103
- update?: ListItemAccessControl<'update', ListTypeInfo>
104
- delete?: ListItemAccessControl<'delete', ListTypeInfo>
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 ListAccessControl<ListTypeInfo extends BaseListTypeInfo> =
127
- | ListAccessControlFunction<ListTypeInfo>
128
- | ListAccessControlObject<ListTypeInfo>
129
-
130
- // Field Access
131
- export type FieldAccessControlFunction<Args> = (args: Args) => MaybePromise<boolean>
132
-
133
- export type FieldCreateItemAccessArgs<ListTypeInfo extends BaseListTypeInfo> =
134
- BaseAccessArgs<ListTypeInfo> & {
135
- operation: 'create'
136
- fieldKey: string
137
- /**
138
- * The input passed in from the GraphQL API
139
- */
140
- inputData: ListTypeInfo['inputs']['create']
141
- }
142
-
143
- export type FieldReadItemAccessArgs<ListTypeInfo extends BaseListTypeInfo> =
144
- BaseAccessArgs<ListTypeInfo> & {
145
- operation: 'read'
146
- fieldKey: string
147
- /**
148
- * The item being read
149
- */
150
- item: ListTypeInfo['item']
151
- }
152
-
153
- export type FieldUpdateItemAccessArgs<ListTypeInfo extends BaseListTypeInfo> =
154
- BaseAccessArgs<ListTypeInfo> & {
155
- operation: 'update'
156
- fieldKey: string
157
- /**
158
- * The item being updated
159
- */
160
- item: ListTypeInfo['item']
161
- /**
162
- * The input passed in from the GraphQL API
163
- */
164
- inputData: ListTypeInfo['inputs']['update']
165
- }
166
-
167
- export type FieldAccessControl<ListTypeInfo extends BaseListTypeInfo> =
168
- | FieldAccessControlFunction<
169
- | FieldReadItemAccessArgs<ListTypeInfo>
170
- | FieldCreateItemAccessArgs<ListTypeInfo>
171
- | FieldUpdateItemAccessArgs<ListTypeInfo>
172
- // delete: not supported
173
- >
174
- | {
175
- read?: FieldAccessControlFunction<FieldReadItemAccessArgs<ListTypeInfo>>
176
- create?: FieldAccessControlFunction<FieldCreateItemAccessArgs<ListTypeInfo>>
177
- update?: FieldAccessControlFunction<FieldUpdateItemAccessArgs<ListTypeInfo>>
178
- // delete: not supported
179
- }
180
-
181
- // Action Access
182
- export type ActionAccessControlFunction<ListTypeInfo extends BaseListTypeInfo> = (
183
- args: BaseAccessArgs<ListTypeInfo> & {
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 { BaseListTypeInfo } 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<ListTypeInfo extends BaseListTypeInfo> = {
17
- [key: string]: FieldTypeFunc<ListTypeInfo>
18
- }
19
-
20
- export type FilterOrderArgs<ListTypeInfo extends BaseListTypeInfo> = {
21
- context: NixxieContext<ListTypeInfo['all']>
22
- session?: ListTypeInfo['all']['session']
23
- listKey: ListTypeInfo['key']
24
- fieldKey: ListTypeInfo['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
- ListTypeInfo extends BaseListTypeInfo,
44
- FieldTypeInfo extends BaseFieldTypeInfo,
45
- > = {
46
- access?: FieldAccessControl<ListTypeInfo>
47
- hooks?: FieldHooks<ListTypeInfo, FieldTypeInfo>
48
- ui?: {
49
- label?: string
50
- description?: string
51
- views?: string
52
- createView?: {
53
- fieldMode?: MaybeSessionFunctionWithFilter<'edit' | 'hidden', 'hidden', ListTypeInfo>
54
- isRequired?: MaybeBooleanSessionFunctionWithFilter<ListTypeInfo>
55
- }
56
- itemView?: {
57
- fieldMode?: MaybeItemFieldFunctionWithFilter<
58
- 'edit' | 'read' | 'hidden',
59
- 'read' | 'hidden',
60
- ListTypeInfo,
61
- FieldTypeInfo
62
- >
63
- fieldPosition?: MaybeItemFieldFunction<'form' | 'sidebar', ListTypeInfo, FieldTypeInfo>
64
- isRequired?: MaybeBooleanSessionFunctionWithFilter<ListTypeInfo>
65
- }
66
- listView?: {
67
- fieldMode?: MaybeSessionFunction<'read' | 'hidden', ListTypeInfo>
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<ListTypeInfo>
95
- isOrderable?: MaybeFieldFunction<ListTypeInfo>
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
+ }