@nixxie-cms/core 1.0.3 → 1.1.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/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 +171 -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 +349 -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-7559ca2d.esm.js → express-0abbce07.esm.js} +6 -6
- package/dist/{express-455ae20c.cjs.js → express-7ca6f76a.cjs.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 +1387 -30
- package/dist/nixxie-cms-core.esm.js +1361 -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-03e49e4f.esm.js → system-4d2a2648.esm.js} +32 -7
- package/dist/{system-a321642d.cjs.js → system-69e1a285.cjs.js} +32 -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 +5 -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 +91 -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 +185 -7
- package/src/types/config/lists.ts +606 -565
- package/src/types/context.ts +426 -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,565 +1,606 @@
|
|
|
1
|
-
import type { CacheHint } from '@apollo/cache-control-types'
|
|
2
|
-
import type { allIcons as KeystarIcons } from '@keystar/ui/icon/all'
|
|
3
|
-
import type { GArg, InferValueFromArgs } from '@graphql-ts/schema'
|
|
4
|
-
|
|
5
|
-
import type { NixxieContext } from '../context'
|
|
6
|
-
import type {
|
|
7
|
-
import type { MaybePromise } from '../utils'
|
|
8
|
-
import type {
|
|
9
|
-
import type { BaseFields, BaseFieldTypeInfo } from './fields'
|
|
10
|
-
import type {
|
|
11
|
-
|
|
12
|
-
export type ActionArgumentsConfig = Record<string, GArg<any, any>>
|
|
13
|
-
|
|
14
|
-
export type ActionArgsConfig<
|
|
15
|
-
string,
|
|
16
|
-
{
|
|
17
|
-
graphql: GArg<any, any>
|
|
18
|
-
ui?: {
|
|
19
|
-
source?: {
|
|
20
|
-
itemField:
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
>
|
|
25
|
-
|
|
26
|
-
type ActionArgs<Args extends ActionArgsConfig<any> | undefined> =
|
|
27
|
-
Args extends ActionArgsConfig<any>
|
|
28
|
-
? InferValueFromArgs<{ [K in keyof Args]: Args[K]['graphql'] }>
|
|
29
|
-
: Record<string, never>
|
|
30
|
-
|
|
31
|
-
export type DeclaredAction<
|
|
32
|
-
___defineActionsWithActionFunction: true
|
|
33
|
-
} & Action<
|
|
34
|
-
|
|
35
|
-
export type Action<
|
|
36
|
-
|
|
37
|
-
Args extends ActionArgsConfig<
|
|
38
|
-
> = {
|
|
39
|
-
/**
|
|
40
|
-
* Controls who or what can use this action
|
|
41
|
-
* @see https://www.nixxieinternational.com/guides/auth-and-access-control
|
|
42
|
-
*/
|
|
43
|
-
access: ActionAccessControlFunction<
|
|
44
|
-
resolve: (
|
|
45
|
-
args: {
|
|
46
|
-
listKey:
|
|
47
|
-
actionKey:
|
|
48
|
-
where:
|
|
49
|
-
args: ActionArgs<Args>
|
|
50
|
-
},
|
|
51
|
-
context: NixxieContext<
|
|
52
|
-
) => MaybePromise<
|
|
53
|
-
graphql?: {
|
|
54
|
-
/**
|
|
55
|
-
* The name of the singular mutation in the GraphQL schema
|
|
56
|
-
* @default {action}{list.graphql.singular}
|
|
57
|
-
*/
|
|
58
|
-
singular?: string
|
|
59
|
-
/**
|
|
60
|
-
* The name of the plural mutation in the GraphQL schema
|
|
61
|
-
* @default {action}{list.graphql.plural}
|
|
62
|
-
*/
|
|
63
|
-
plural?: string
|
|
64
|
-
/**
|
|
65
|
-
* The description added to the GraphQL schema
|
|
66
|
-
* @default empty
|
|
67
|
-
*/
|
|
68
|
-
description?: string
|
|
69
|
-
}
|
|
70
|
-
/**
|
|
71
|
-
* Defines what arguments the action should accept as input.
|
|
72
|
-
* @experimental This feature is not yet stable.
|
|
73
|
-
*/
|
|
74
|
-
args?: Args
|
|
75
|
-
ui: {
|
|
76
|
-
/**
|
|
77
|
-
* The label used to identify the action in the Admin UI.
|
|
78
|
-
*/
|
|
79
|
-
label: string
|
|
80
|
-
|
|
81
|
-
/**
|
|
82
|
-
* The icon name used to represent the action in the Admin UI.
|
|
83
|
-
* @default null
|
|
84
|
-
*/
|
|
85
|
-
icon?: keyof typeof KeystarIcons | null
|
|
86
|
-
|
|
87
|
-
/**
|
|
88
|
-
* The style used for the success message in the Admin UI.
|
|
89
|
-
* @default 'neutral'
|
|
90
|
-
*/
|
|
91
|
-
// TODO: ? maybe ?
|
|
92
|
-
// result?: 'positive' | 'info' | 'neutral' | 'critical'
|
|
93
|
-
|
|
94
|
-
/**
|
|
95
|
-
* The locale messages used in the Admin UI, with support for the following template tags:
|
|
96
|
-
* - {label}: The action label in lowercase
|
|
97
|
-
* - {Label}: The action label as-is
|
|
98
|
-
* - {singular}: Uses {list}.ui.singular
|
|
99
|
-
* - {plural}: Uses {list}.ui.plural
|
|
100
|
-
* - {singular|plural}: Uses {list}.ui.singular if {count} is 1, otherwise uses {list}.ui.plural
|
|
101
|
-
* - {itemLabel}: The label of the item being acted upon
|
|
102
|
-
* - {count}: The number of items being acted upon
|
|
103
|
-
* - {countSuccess}: The number of items successfully acted upon
|
|
104
|
-
* - {countFail}: The number of items that failed to be acted upon
|
|
105
|
-
*/
|
|
106
|
-
messages?: {
|
|
107
|
-
promptTitle?: string
|
|
108
|
-
promptTitleMany?: string
|
|
109
|
-
prompt?: string
|
|
110
|
-
promptMany?: string
|
|
111
|
-
promptConfirmLabel?: string
|
|
112
|
-
promptConfirmLabelMany?: string
|
|
113
|
-
fail?: string
|
|
114
|
-
failMany?: string
|
|
115
|
-
success?: string
|
|
116
|
-
successMany?: string
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
itemView?: {
|
|
120
|
-
/**
|
|
121
|
-
* Controls the action mode for this action in the item view in the Admin UI.
|
|
122
|
-
* @default 'enabled'
|
|
123
|
-
*/
|
|
124
|
-
actionMode?: MaybeItemActionFunctionWithFilter<
|
|
125
|
-
'enabled' | 'disabled' | 'hidden',
|
|
126
|
-
'disabled' | 'hidden',
|
|
127
|
-
|
|
128
|
-
>
|
|
129
|
-
/**
|
|
130
|
-
* Controls the navigation behaviour after the action completes in the item view in the Admin UI.
|
|
131
|
-
* @default 'follow'
|
|
132
|
-
*/
|
|
133
|
-
navigation?: 'follow' | 'refetch' | 'return'
|
|
134
|
-
|
|
135
|
-
/**
|
|
136
|
-
* Controls whether to show a prompt prior to the action in the item view in the Admin UI.
|
|
137
|
-
* @default false
|
|
138
|
-
*/
|
|
139
|
-
hidePrompt?: boolean
|
|
140
|
-
|
|
141
|
-
/**
|
|
142
|
-
* Controls whether to show a toast notification after completing the action in the item view in the Admin UI.
|
|
143
|
-
* @default false
|
|
144
|
-
*/
|
|
145
|
-
hideToast?: boolean
|
|
146
|
-
}
|
|
147
|
-
listView?: {
|
|
148
|
-
/**
|
|
149
|
-
* Controls the action mode for this action in the list view in the Admin UI.
|
|
150
|
-
* @default 'enabled'
|
|
151
|
-
*/
|
|
152
|
-
actionMode?: MaybeSessionFunctionWithFilter<
|
|
153
|
-
'enabled' | 'disabled' | 'hidden',
|
|
154
|
-
'disabled' | 'hidden',
|
|
155
|
-
|
|
156
|
-
>
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
export type BaseActions<
|
|
162
|
-
/**
|
|
163
|
-
* The key of the action, by default this is used to prefix the mutation in the GraphQL schema
|
|
164
|
-
*/
|
|
165
|
-
[action: string]: DeclaredAction<
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
*
|
|
193
|
-
*
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
/**
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
*
|
|
224
|
-
* @
|
|
225
|
-
*/
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
*
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
*
|
|
264
|
-
*
|
|
265
|
-
* @default
|
|
266
|
-
*/
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
*
|
|
271
|
-
*
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
*
|
|
288
|
-
*/
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
/**
|
|
304
|
-
*
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
AND
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
export type
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
> =
|
|
433
|
-
|
|
|
434
|
-
| ((args: {
|
|
435
|
-
context: NixxieContext<
|
|
436
|
-
session?:
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
1
|
+
import type { CacheHint } from '@apollo/cache-control-types'
|
|
2
|
+
import type { allIcons as KeystarIcons } from '@keystar/ui/icon/all'
|
|
3
|
+
import type { GArg, InferValueFromArgs } from '@graphql-ts/schema'
|
|
4
|
+
|
|
5
|
+
import type { NixxieContext } from '../context'
|
|
6
|
+
import type { BaseCollectionTypeInfo } from '../type-info'
|
|
7
|
+
import type { MaybePromise } from '../utils'
|
|
8
|
+
import type { CollectionAccessControl, ActionAccessControlFunction } from './access-control'
|
|
9
|
+
import type { BaseFields, BaseFieldTypeInfo } from './fields'
|
|
10
|
+
import type { CollectionHooks } from './hooks'
|
|
11
|
+
|
|
12
|
+
export type ActionArgumentsConfig = Record<string, GArg<any, any>>
|
|
13
|
+
|
|
14
|
+
export type ActionArgsConfig<CollectionTypeInfo extends BaseCollectionTypeInfo> = Record<
|
|
15
|
+
string,
|
|
16
|
+
{
|
|
17
|
+
graphql: GArg<any, any>
|
|
18
|
+
ui?: {
|
|
19
|
+
source?: {
|
|
20
|
+
itemField: CollectionTypeInfo['fields']
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
>
|
|
25
|
+
|
|
26
|
+
type ActionArgs<Args extends ActionArgsConfig<any> | undefined> =
|
|
27
|
+
Args extends ActionArgsConfig<any>
|
|
28
|
+
? InferValueFromArgs<{ [K in keyof Args]: Args[K]['graphql'] }>
|
|
29
|
+
: Record<string, never>
|
|
30
|
+
|
|
31
|
+
export type DeclaredAction<CollectionTypeInfo extends BaseCollectionTypeInfo> = {
|
|
32
|
+
___defineActionsWithActionFunction: true
|
|
33
|
+
} & Action<CollectionTypeInfo, ActionArgsConfig<CollectionTypeInfo> | undefined>
|
|
34
|
+
|
|
35
|
+
export type Action<
|
|
36
|
+
CollectionTypeInfo extends BaseCollectionTypeInfo,
|
|
37
|
+
Args extends ActionArgsConfig<CollectionTypeInfo> | undefined,
|
|
38
|
+
> = {
|
|
39
|
+
/**
|
|
40
|
+
* Controls who or what can use this action
|
|
41
|
+
* @see https://www.nixxieinternational.com/guides/auth-and-access-control
|
|
42
|
+
*/
|
|
43
|
+
access: ActionAccessControlFunction<CollectionTypeInfo>
|
|
44
|
+
resolve: (
|
|
45
|
+
args: {
|
|
46
|
+
listKey: CollectionTypeInfo['key']
|
|
47
|
+
actionKey: CollectionTypeInfo['actions']
|
|
48
|
+
where: CollectionTypeInfo['inputs']['uniqueWhere']
|
|
49
|
+
args: ActionArgs<Args>
|
|
50
|
+
},
|
|
51
|
+
context: NixxieContext<CollectionTypeInfo['all']>
|
|
52
|
+
) => MaybePromise<CollectionTypeInfo['item'] | null>
|
|
53
|
+
graphql?: {
|
|
54
|
+
/**
|
|
55
|
+
* The name of the singular mutation in the GraphQL schema
|
|
56
|
+
* @default {action}{list.graphql.singular}
|
|
57
|
+
*/
|
|
58
|
+
singular?: string
|
|
59
|
+
/**
|
|
60
|
+
* The name of the plural mutation in the GraphQL schema
|
|
61
|
+
* @default {action}{list.graphql.plural}
|
|
62
|
+
*/
|
|
63
|
+
plural?: string
|
|
64
|
+
/**
|
|
65
|
+
* The description added to the GraphQL schema
|
|
66
|
+
* @default empty
|
|
67
|
+
*/
|
|
68
|
+
description?: string
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Defines what arguments the action should accept as input.
|
|
72
|
+
* @experimental This feature is not yet stable.
|
|
73
|
+
*/
|
|
74
|
+
args?: Args
|
|
75
|
+
ui: {
|
|
76
|
+
/**
|
|
77
|
+
* The label used to identify the action in the Admin UI.
|
|
78
|
+
*/
|
|
79
|
+
label: string
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* The icon name used to represent the action in the Admin UI.
|
|
83
|
+
* @default null
|
|
84
|
+
*/
|
|
85
|
+
icon?: keyof typeof KeystarIcons | null
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* The style used for the success message in the Admin UI.
|
|
89
|
+
* @default 'neutral'
|
|
90
|
+
*/
|
|
91
|
+
// TODO: ? maybe ?
|
|
92
|
+
// result?: 'positive' | 'info' | 'neutral' | 'critical'
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* The locale messages used in the Admin UI, with support for the following template tags:
|
|
96
|
+
* - {label}: The action label in lowercase
|
|
97
|
+
* - {Label}: The action label as-is
|
|
98
|
+
* - {singular}: Uses {list}.ui.singular
|
|
99
|
+
* - {plural}: Uses {list}.ui.plural
|
|
100
|
+
* - {singular|plural}: Uses {list}.ui.singular if {count} is 1, otherwise uses {list}.ui.plural
|
|
101
|
+
* - {itemLabel}: The label of the item being acted upon
|
|
102
|
+
* - {count}: The number of items being acted upon
|
|
103
|
+
* - {countSuccess}: The number of items successfully acted upon
|
|
104
|
+
* - {countFail}: The number of items that failed to be acted upon
|
|
105
|
+
*/
|
|
106
|
+
messages?: {
|
|
107
|
+
promptTitle?: string
|
|
108
|
+
promptTitleMany?: string
|
|
109
|
+
prompt?: string
|
|
110
|
+
promptMany?: string
|
|
111
|
+
promptConfirmLabel?: string
|
|
112
|
+
promptConfirmLabelMany?: string
|
|
113
|
+
fail?: string
|
|
114
|
+
failMany?: string
|
|
115
|
+
success?: string
|
|
116
|
+
successMany?: string
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
itemView?: {
|
|
120
|
+
/**
|
|
121
|
+
* Controls the action mode for this action in the item view in the Admin UI.
|
|
122
|
+
* @default 'enabled'
|
|
123
|
+
*/
|
|
124
|
+
actionMode?: MaybeItemActionFunctionWithFilter<
|
|
125
|
+
'enabled' | 'disabled' | 'hidden',
|
|
126
|
+
'disabled' | 'hidden',
|
|
127
|
+
CollectionTypeInfo
|
|
128
|
+
>
|
|
129
|
+
/**
|
|
130
|
+
* Controls the navigation behaviour after the action completes in the item view in the Admin UI.
|
|
131
|
+
* @default 'follow'
|
|
132
|
+
*/
|
|
133
|
+
navigation?: 'follow' | 'refetch' | 'return'
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Controls whether to show a prompt prior to the action in the item view in the Admin UI.
|
|
137
|
+
* @default false
|
|
138
|
+
*/
|
|
139
|
+
hidePrompt?: boolean
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* Controls whether to show a toast notification after completing the action in the item view in the Admin UI.
|
|
143
|
+
* @default false
|
|
144
|
+
*/
|
|
145
|
+
hideToast?: boolean
|
|
146
|
+
}
|
|
147
|
+
listView?: {
|
|
148
|
+
/**
|
|
149
|
+
* Controls the action mode for this action in the list view in the Admin UI.
|
|
150
|
+
* @default 'enabled'
|
|
151
|
+
*/
|
|
152
|
+
actionMode?: MaybeSessionFunctionWithFilter<
|
|
153
|
+
'enabled' | 'disabled' | 'hidden',
|
|
154
|
+
'disabled' | 'hidden',
|
|
155
|
+
CollectionTypeInfo
|
|
156
|
+
>
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
export type BaseActions<CollectionTypeInfo extends BaseCollectionTypeInfo> = {
|
|
162
|
+
/**
|
|
163
|
+
* The key of the action, by default this is used to prefix the mutation in the GraphQL schema
|
|
164
|
+
*/
|
|
165
|
+
[action: string]: DeclaredAction<CollectionTypeInfo>
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/** What to do with related records when an item in this collection is deleted. */
|
|
169
|
+
export type CascadeAction = 'delete' | 'setNull' | 'restrict' | 'softDelete'
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* A referential-integrity rule enacted when an item of this collection is deleted.
|
|
173
|
+
* Rules run inside the delete pipeline through the normal mutation APIs, so the target
|
|
174
|
+
* collections' own hooks, events and cascade rules all fire (cascades recurse, with
|
|
175
|
+
* cycle protection).
|
|
176
|
+
*
|
|
177
|
+
* @example
|
|
178
|
+
* cascade: [
|
|
179
|
+
* { collection: 'Comment', field: 'post', action: 'delete' },
|
|
180
|
+
* { collection: 'Draft', field: 'original', action: 'setNull' },
|
|
181
|
+
* { collection: 'Order', field: 'product', action: 'restrict' },
|
|
182
|
+
* ]
|
|
183
|
+
*/
|
|
184
|
+
export type CascadeRule = {
|
|
185
|
+
/** Target collection holding the related records. */
|
|
186
|
+
collection: string
|
|
187
|
+
/** Relationship field on the target collection that points at this collection. */
|
|
188
|
+
field: string
|
|
189
|
+
/**
|
|
190
|
+
* - `'delete'` — delete the related records (recursing into their own cascade rules)
|
|
191
|
+
* - `'setNull'` — disconnect the relationship, keeping the records
|
|
192
|
+
* - `'restrict'` — refuse the delete while related records exist
|
|
193
|
+
* - `'softDelete'` — stamp the records' `softDeleteField` instead of deleting
|
|
194
|
+
* @default 'delete'
|
|
195
|
+
*/
|
|
196
|
+
action?: CascadeAction
|
|
197
|
+
/** Set when `field` on the target collection is a many-relationship. @default false */
|
|
198
|
+
many?: boolean
|
|
199
|
+
/** Timestamp field stamped by `'softDelete'`. @default 'deletedAt' */
|
|
200
|
+
softDeleteField?: string
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
export type CollectionConfig<CollectionTypeInfo extends BaseCollectionTypeInfo> = {
|
|
204
|
+
/**
|
|
205
|
+
* Controls what data users of the Admin UI and GraphQL can access and change
|
|
206
|
+
* @see https://nixxieinternational.com/guides/auth-and-access-control
|
|
207
|
+
*/
|
|
208
|
+
access: CollectionAccessControl<CollectionTypeInfo>
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
* Referential-integrity rules enacted when items of this collection are deleted.
|
|
212
|
+
* Use `previewDelete()` to compute what a delete would affect before running it.
|
|
213
|
+
*/
|
|
214
|
+
cascade?: CascadeRule[]
|
|
215
|
+
|
|
216
|
+
fields: BaseFields<CollectionTypeInfo>
|
|
217
|
+
actions?: BaseActions<CollectionTypeInfo>
|
|
218
|
+
|
|
219
|
+
/** Options for how this list should show in the Admin UI */
|
|
220
|
+
ui?: CollectionAdminUIConfig<CollectionTypeInfo>
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
* Hooks to modify the behaviour of GraphQL operations at certain points
|
|
224
|
+
* @see https://nixxieinternational.com/guides/hooks
|
|
225
|
+
*/
|
|
226
|
+
hooks?: CollectionHooks<CollectionTypeInfo>
|
|
227
|
+
|
|
228
|
+
graphql?: CollectionGraphQLConfig<CollectionTypeInfo>
|
|
229
|
+
|
|
230
|
+
db?: CollectionDBConfig
|
|
231
|
+
|
|
232
|
+
/**
|
|
233
|
+
* Controls if this list is a singleton
|
|
234
|
+
* @see https://nixxieinternational.com/docs/config/lists#is-singleton
|
|
235
|
+
*/
|
|
236
|
+
isSingleton?: boolean
|
|
237
|
+
|
|
238
|
+
/**
|
|
239
|
+
* The default value to use for graphql.isEnabled.filter on all fields for this list
|
|
240
|
+
*/
|
|
241
|
+
defaultIsFilterable?: MaybeFieldFunction<CollectionTypeInfo>
|
|
242
|
+
|
|
243
|
+
/**
|
|
244
|
+
* The default value to use for graphql.isEnabled.orderBy on all fields for this list
|
|
245
|
+
*/
|
|
246
|
+
defaultIsOrderable?: MaybeFieldFunction<CollectionTypeInfo>
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
export type CollectionSortDescriptor<Fields extends string> = {
|
|
250
|
+
field: 'id' | Fields
|
|
251
|
+
direction: 'ASC' | 'DESC'
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
export type CollectionAdminUIConfig<CollectionTypeInfo extends BaseCollectionTypeInfo> = {
|
|
255
|
+
/**
|
|
256
|
+
* The label used to identify the list in navigation and etc.
|
|
257
|
+
* @default listKey.replace(/([a-z])([A-Z])/g, '$1 $2').split(/\s|_|\-/).filter(i => i).map(upcase).join(' ');
|
|
258
|
+
*/
|
|
259
|
+
label?: string
|
|
260
|
+
|
|
261
|
+
/**
|
|
262
|
+
* The singular form of the list key.
|
|
263
|
+
*
|
|
264
|
+
* It is used in sentences like `Are you sure you want to delete these {plural}?`
|
|
265
|
+
* @default pluralize.singular(label)
|
|
266
|
+
*/
|
|
267
|
+
singular?: string
|
|
268
|
+
|
|
269
|
+
/**
|
|
270
|
+
* The plural form of the list key.
|
|
271
|
+
*
|
|
272
|
+
* It is used in sentences like `Are you sure you want to delete this {singular}?`.
|
|
273
|
+
* @default pluralize.plural(label)
|
|
274
|
+
*/
|
|
275
|
+
plural?: string
|
|
276
|
+
|
|
277
|
+
/**
|
|
278
|
+
* The path segment to identify the list in URLs.
|
|
279
|
+
*
|
|
280
|
+
* It must match the pattern `/^[a-z-_][a-z0-9-_]*$/`.
|
|
281
|
+
* @default label.split(' ').join('-').toLowerCase()
|
|
282
|
+
*/
|
|
283
|
+
path?: string
|
|
284
|
+
|
|
285
|
+
/**
|
|
286
|
+
* The field to use as a label in the Admin UI. If you want to base the label off more than a single field, use a virtual field and reference that field here.
|
|
287
|
+
* @default 'label', if it exists, falling back to 'name', then 'title', and finally 'id', which is guaranteed to exist.
|
|
288
|
+
*/
|
|
289
|
+
labelField?: 'id' | Exclude<CollectionTypeInfo['fields'], number>
|
|
290
|
+
|
|
291
|
+
/**
|
|
292
|
+
* The fields used by the Admin UI when searching this list.
|
|
293
|
+
* It is always possible to search by id and `id` should not be specified in this option.
|
|
294
|
+
* @default The `labelField` if it has a string `contains` filter, otherwise none.
|
|
295
|
+
*/
|
|
296
|
+
searchFields?: CollectionTypeInfo['fields'][]
|
|
297
|
+
|
|
298
|
+
/**
|
|
299
|
+
* Hides this list from the Admin UI navigation, it only hides the list, you can still navigate directly.
|
|
300
|
+
* @default false
|
|
301
|
+
*/
|
|
302
|
+
hideNavigation?: MaybeSessionFunction<boolean, CollectionTypeInfo>
|
|
303
|
+
/**
|
|
304
|
+
* Hides the create button in the Admin UI.
|
|
305
|
+
* Note that this does **not** disable creating items through the GraphQL API, it only hides the button to create an item for this list in the Admin UI.
|
|
306
|
+
* @default false
|
|
307
|
+
*/
|
|
308
|
+
hideCreate?: MaybeSessionFunction<boolean, CollectionTypeInfo>
|
|
309
|
+
/**
|
|
310
|
+
* Hides the delete button in the Admin UI.
|
|
311
|
+
* Note that this does **not** disable deleting items through the GraphQL API, it only hides the button to delete an item for this list in the Admin UI.
|
|
312
|
+
* @default false
|
|
313
|
+
*/
|
|
314
|
+
hideDelete?: MaybeSessionFunction<boolean, CollectionTypeInfo>
|
|
315
|
+
/**
|
|
316
|
+
* Configuration specific to the create view in the Admin UI
|
|
317
|
+
*/
|
|
318
|
+
createView?: {
|
|
319
|
+
/**
|
|
320
|
+
* The default field mode for fields on the create view for this list.
|
|
321
|
+
* Specific field modes on a per-field basis via a field's config.
|
|
322
|
+
* @default 'edit'
|
|
323
|
+
*/
|
|
324
|
+
defaultFieldMode?: MaybeSessionFunctionWithFilter<'edit' | 'hidden', 'hidden', CollectionTypeInfo>
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
/**
|
|
328
|
+
* Configuration specific to the item view in the Admin UI
|
|
329
|
+
*/
|
|
330
|
+
itemView?: {
|
|
331
|
+
/**
|
|
332
|
+
* The default field mode for fields on the item view for this list.
|
|
333
|
+
* This controls what people can do for fields
|
|
334
|
+
* Specific field modes on a per-field basis via a field's config.
|
|
335
|
+
* @default 'edit'
|
|
336
|
+
*/
|
|
337
|
+
defaultFieldMode?: MaybeItemFunctionWithFilter<
|
|
338
|
+
'edit' | 'read' | 'hidden',
|
|
339
|
+
'read' | 'hidden',
|
|
340
|
+
CollectionTypeInfo
|
|
341
|
+
>
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
/**
|
|
345
|
+
* Configuration specific to the list view in the Admin UI
|
|
346
|
+
*/
|
|
347
|
+
listView?: {
|
|
348
|
+
/**
|
|
349
|
+
* The default field mode for fields on the list view for this list.
|
|
350
|
+
* Specific field modes on a per-field basis via a field's config.
|
|
351
|
+
* @default 'read'
|
|
352
|
+
*/
|
|
353
|
+
defaultFieldMode?: MaybeSessionFunction<'read' | 'hidden', CollectionTypeInfo>
|
|
354
|
+
/**
|
|
355
|
+
* The columns(which refer to fields) that should be shown to users of the Admin UI.
|
|
356
|
+
* Users of the Admin UI can select different columns to show in the UI.
|
|
357
|
+
* @default the first three fields in the list
|
|
358
|
+
*/
|
|
359
|
+
initialColumns?: readonly ('id' | CollectionTypeInfo['fields'])[]
|
|
360
|
+
initialFilter?: MaybeSessionFunction<
|
|
361
|
+
Omit<CollectionTypeInfo['inputs']['where'], 'AND' | 'OR' | 'NOT'>,
|
|
362
|
+
CollectionTypeInfo
|
|
363
|
+
>
|
|
364
|
+
initialSort?: CollectionSortDescriptor<CollectionTypeInfo['fields']>
|
|
365
|
+
|
|
366
|
+
// TODO: rename to initialItemsPerPage or initialPageSize?
|
|
367
|
+
pageSize?: number // default number of items to display per page on the list screen
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
export type MaybeFieldFunction<CollectionTypeInfo extends BaseCollectionTypeInfo> =
|
|
372
|
+
| boolean
|
|
373
|
+
| ((args: {
|
|
374
|
+
context: NixxieContext<CollectionTypeInfo['all']>
|
|
375
|
+
session?: CollectionTypeInfo['all']['session'] // TODO: use context.session, remove in breaking change
|
|
376
|
+
listKey: CollectionTypeInfo['key']
|
|
377
|
+
fieldKey: CollectionTypeInfo['fields']
|
|
378
|
+
}) => MaybePromise<boolean>)
|
|
379
|
+
|
|
380
|
+
export type MaybeSessionFunction<T, CollectionTypeInfo extends BaseCollectionTypeInfo> =
|
|
381
|
+
| T
|
|
382
|
+
| ((args: {
|
|
383
|
+
context: NixxieContext<CollectionTypeInfo['all']>
|
|
384
|
+
session?: CollectionTypeInfo['all']['session'] // TODO: use context.session, remove in breaking change
|
|
385
|
+
}) => MaybePromise<T>)
|
|
386
|
+
|
|
387
|
+
type ConditionalFilterFieldValue<Value> = {
|
|
388
|
+
equals?: Value
|
|
389
|
+
in?: Value[]
|
|
390
|
+
not?: {
|
|
391
|
+
equals?: Value
|
|
392
|
+
in?: Value[]
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
// this conditional type is to avoid inconvenient type errors
|
|
397
|
+
// [] is just a placeholder for something that is never a valid BaseCollectionTypeInfo so
|
|
398
|
+
// CollectionTypeInfo must be `any`
|
|
399
|
+
type ConditionalFilterObject<CollectionTypeInfo extends BaseCollectionTypeInfo> = CollectionTypeInfo extends []
|
|
400
|
+
? any
|
|
401
|
+
: {
|
|
402
|
+
AND?: ReadonlyArray<ConditionalFilterObject<CollectionTypeInfo>>
|
|
403
|
+
OR?: ReadonlyArray<ConditionalFilterObject<CollectionTypeInfo>>
|
|
404
|
+
NOT?: ConditionalFilterObject<CollectionTypeInfo>
|
|
405
|
+
} & {
|
|
406
|
+
[K in keyof CollectionTypeInfo['inputs']['update']]?: ConditionalFilterFieldValue<
|
|
407
|
+
CollectionTypeInfo['inputs']['update'][K]
|
|
408
|
+
>
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
export type ConditionalFilterCase<CollectionTypeInfo extends BaseCollectionTypeInfo> =
|
|
412
|
+
| boolean
|
|
413
|
+
| ConditionalFilterObject<CollectionTypeInfo>
|
|
414
|
+
|
|
415
|
+
export type ConditionalFilter<
|
|
416
|
+
StaticState extends string,
|
|
417
|
+
Filterable extends string,
|
|
418
|
+
CollectionTypeInfo extends BaseCollectionTypeInfo,
|
|
419
|
+
> = StaticState | { [_ in Filterable]?: ConditionalFilterCase<CollectionTypeInfo> }
|
|
420
|
+
|
|
421
|
+
export type MaybeSessionFunctionWithFilter<
|
|
422
|
+
StaticState extends string,
|
|
423
|
+
Filterable extends string,
|
|
424
|
+
CollectionTypeInfo extends BaseCollectionTypeInfo,
|
|
425
|
+
> =
|
|
426
|
+
| ConditionalFilter<StaticState, Filterable, CollectionTypeInfo>
|
|
427
|
+
| ((args: {
|
|
428
|
+
context: NixxieContext<CollectionTypeInfo['all']>
|
|
429
|
+
session?: NixxieContext<CollectionTypeInfo['all']>['session']
|
|
430
|
+
}) => MaybePromise<ConditionalFilter<StaticState, Filterable, CollectionTypeInfo>>)
|
|
431
|
+
|
|
432
|
+
export type MaybeBooleanSessionFunctionWithFilter<CollectionTypeInfo extends BaseCollectionTypeInfo> =
|
|
433
|
+
| ConditionalFilterCase<CollectionTypeInfo>
|
|
434
|
+
| ((args: {
|
|
435
|
+
context: NixxieContext<CollectionTypeInfo['all']>
|
|
436
|
+
session?: CollectionTypeInfo['all']['session'] // TODO: use context.session, remove in breaking change
|
|
437
|
+
}) => MaybePromise<ConditionalFilterCase<CollectionTypeInfo>>)
|
|
438
|
+
|
|
439
|
+
export type MaybeBooleanItemFunctionWithFilter<
|
|
440
|
+
CollectionTypeInfo extends BaseCollectionTypeInfo,
|
|
441
|
+
FieldTypeInfo extends BaseFieldTypeInfo,
|
|
442
|
+
> =
|
|
443
|
+
| ConditionalFilterCase<CollectionTypeInfo>
|
|
444
|
+
| ((args: {
|
|
445
|
+
context: NixxieContext<CollectionTypeInfo['all']>
|
|
446
|
+
listKey: CollectionTypeInfo['key']
|
|
447
|
+
fieldKey: CollectionTypeInfo['fields']
|
|
448
|
+
item: CollectionTypeInfo['item'] | null
|
|
449
|
+
itemField: FieldTypeInfo['item'] | null
|
|
450
|
+
session?: CollectionTypeInfo['all']['session'] // TODO: use context.session, remove in breaking change
|
|
451
|
+
}) => MaybePromise<ConditionalFilterCase<CollectionTypeInfo>>)
|
|
452
|
+
|
|
453
|
+
export type MaybeItemFieldFunctionWithFilter<
|
|
454
|
+
StaticState extends string,
|
|
455
|
+
Filterable extends string,
|
|
456
|
+
CollectionTypeInfo extends BaseCollectionTypeInfo,
|
|
457
|
+
FieldTypeInfo extends BaseFieldTypeInfo,
|
|
458
|
+
> =
|
|
459
|
+
| ConditionalFilter<StaticState, Filterable, CollectionTypeInfo>
|
|
460
|
+
| ((args: {
|
|
461
|
+
context: NixxieContext<CollectionTypeInfo['all']>
|
|
462
|
+
session?: CollectionTypeInfo['all']['session'] // TODO: use context.session, remove in breaking change
|
|
463
|
+
listKey: CollectionTypeInfo['key']
|
|
464
|
+
fieldKey: CollectionTypeInfo['fields']
|
|
465
|
+
item: CollectionTypeInfo['item'] | null
|
|
466
|
+
itemField: FieldTypeInfo['item'] | null
|
|
467
|
+
}) => MaybePromise<ConditionalFilter<StaticState, Filterable, CollectionTypeInfo>>)
|
|
468
|
+
|
|
469
|
+
export type MaybeItemFieldFunction<
|
|
470
|
+
T,
|
|
471
|
+
CollectionTypeInfo extends BaseCollectionTypeInfo,
|
|
472
|
+
FieldTypeInfo extends BaseFieldTypeInfo,
|
|
473
|
+
> =
|
|
474
|
+
| T
|
|
475
|
+
| ((args: {
|
|
476
|
+
context: NixxieContext<CollectionTypeInfo['all']>
|
|
477
|
+
session?: CollectionTypeInfo['all']['session'] // TODO: use context.session, remove in breaking change
|
|
478
|
+
listKey: CollectionTypeInfo['key']
|
|
479
|
+
fieldKey: CollectionTypeInfo['fields']
|
|
480
|
+
item: CollectionTypeInfo['item'] | null
|
|
481
|
+
itemField: FieldTypeInfo['item'] | null
|
|
482
|
+
}) => MaybePromise<T>)
|
|
483
|
+
|
|
484
|
+
export type MaybeItemFunctionWithFilter<
|
|
485
|
+
StaticState extends string,
|
|
486
|
+
Filterable extends string,
|
|
487
|
+
CollectionTypeInfo extends BaseCollectionTypeInfo,
|
|
488
|
+
> =
|
|
489
|
+
| ConditionalFilter<StaticState, Filterable, CollectionTypeInfo>
|
|
490
|
+
| ((args: {
|
|
491
|
+
context: NixxieContext<CollectionTypeInfo['all']>
|
|
492
|
+
session?: CollectionTypeInfo['all']['session'] // TODO: use context.session, remove in breaking change
|
|
493
|
+
listKey: CollectionTypeInfo['key']
|
|
494
|
+
item: CollectionTypeInfo['item'] | null
|
|
495
|
+
}) => MaybePromise<ConditionalFilter<StaticState, Filterable, CollectionTypeInfo>>)
|
|
496
|
+
|
|
497
|
+
export type MaybeItemActionFunction<
|
|
498
|
+
T extends string,
|
|
499
|
+
CollectionTypeInfo extends BaseCollectionTypeInfo,
|
|
500
|
+
> = (args: {
|
|
501
|
+
context: NixxieContext<CollectionTypeInfo['all']>
|
|
502
|
+
session?: CollectionTypeInfo['all']['session'] // TODO: use context.session, remove in breaking change
|
|
503
|
+
listKey: CollectionTypeInfo['key']
|
|
504
|
+
actionKey: CollectionTypeInfo['actions']
|
|
505
|
+
item: CollectionTypeInfo['item'] | null
|
|
506
|
+
}) => MaybePromise<T>
|
|
507
|
+
|
|
508
|
+
export type MaybeItemActionFunctionWithFilter<
|
|
509
|
+
StaticState extends string,
|
|
510
|
+
Filterable extends string,
|
|
511
|
+
CollectionTypeInfo extends BaseCollectionTypeInfo,
|
|
512
|
+
> =
|
|
513
|
+
| ConditionalFilter<StaticState, Filterable, CollectionTypeInfo>
|
|
514
|
+
| ((args: {
|
|
515
|
+
context: NixxieContext<CollectionTypeInfo['all']>
|
|
516
|
+
session?: CollectionTypeInfo['all']['session'] // TODO: use context.session, remove in breaking change
|
|
517
|
+
listKey: CollectionTypeInfo['key']
|
|
518
|
+
actionKey: CollectionTypeInfo['actions']
|
|
519
|
+
item: CollectionTypeInfo['item'] | null
|
|
520
|
+
}) => MaybePromise<ConditionalFilter<StaticState, Filterable, CollectionTypeInfo>>)
|
|
521
|
+
|
|
522
|
+
export type CollectionGraphQLConfig<CollectionTypeInfo extends BaseCollectionTypeInfo> = {
|
|
523
|
+
/**
|
|
524
|
+
* The description added to the GraphQL schema
|
|
525
|
+
* @default empty
|
|
526
|
+
*/
|
|
527
|
+
description?: string
|
|
528
|
+
/**
|
|
529
|
+
* The singular form of the list key to use in the generated GraphQL schema.
|
|
530
|
+
*/
|
|
531
|
+
singular?: string
|
|
532
|
+
/**
|
|
533
|
+
* The plural form of the list key to use in the generated GraphQL schema.
|
|
534
|
+
*/
|
|
535
|
+
plural?: string
|
|
536
|
+
/**
|
|
537
|
+
* The maximum value for the take parameter when querying this list
|
|
538
|
+
*/
|
|
539
|
+
maxTake?: number
|
|
540
|
+
cacheHint?: ((args: CacheHintArgs<CollectionTypeInfo>) => CacheHint) | CacheHint
|
|
541
|
+
// Setting any of these values will remove the corresponding operations from the GraphQL schema.
|
|
542
|
+
// Queries:
|
|
543
|
+
// 'query': Does item()/items() exist?
|
|
544
|
+
// Mutations:
|
|
545
|
+
// 'create': Does createItem/createItems exist? Does `create` exist on the RelationshipInput types?
|
|
546
|
+
// 'update': Does updateItem/updateItems exist?
|
|
547
|
+
// 'delete': Does deleteItem/deleteItems exist?
|
|
548
|
+
// If `true`, then everything will be omitted, including the output type. This makes it a DB only list,
|
|
549
|
+
// including from the point of view of relationships to this list.
|
|
550
|
+
//
|
|
551
|
+
// Default: undefined
|
|
552
|
+
omit?:
|
|
553
|
+
| boolean
|
|
554
|
+
| {
|
|
555
|
+
query?: boolean
|
|
556
|
+
create?: boolean
|
|
557
|
+
update?: boolean
|
|
558
|
+
delete?: boolean
|
|
559
|
+
}
|
|
560
|
+
}
|
|
561
|
+
|
|
562
|
+
export type CacheHintArgs<CollectionTypeInfo extends BaseCollectionTypeInfo> =
|
|
563
|
+
| {
|
|
564
|
+
results: CollectionTypeInfo['item'][]
|
|
565
|
+
operationName?: string
|
|
566
|
+
meta: false
|
|
567
|
+
}
|
|
568
|
+
| {
|
|
569
|
+
results: number
|
|
570
|
+
operationName?: string
|
|
571
|
+
meta: true
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
// TODO: duplicate, merge with next-fields?
|
|
575
|
+
export type IdFieldConfig =
|
|
576
|
+
| {
|
|
577
|
+
kind: 'random'
|
|
578
|
+
type?: 'String'
|
|
579
|
+
bytes?: number
|
|
580
|
+
encoding?: 'hex' | 'base64url'
|
|
581
|
+
}
|
|
582
|
+
| { kind: 'string' | 'ulid'; type?: 'String' }
|
|
583
|
+
| { kind: 'cuid'; version?: 1 | 2; type?: 'String' }
|
|
584
|
+
| { kind: 'uuid'; version?: 4 | 7; type?: 'String' }
|
|
585
|
+
| { kind: 'nanoid'; length?: number; type?: 'String' }
|
|
586
|
+
| { kind: 'autoincrement'; type?: 'Int' | 'BigInt' }
|
|
587
|
+
| { kind: 'number'; type: 'Int' | 'BigInt' }
|
|
588
|
+
|
|
589
|
+
export type CollectionDBConfig = {
|
|
590
|
+
/**
|
|
591
|
+
* The kind of id to use.
|
|
592
|
+
* @default { kind: "cuid" }
|
|
593
|
+
*/
|
|
594
|
+
idField?: IdFieldConfig
|
|
595
|
+
/**
|
|
596
|
+
* Specifies an alternative name name for the table to use, if you don't want
|
|
597
|
+
* the default (derived from the list key)
|
|
598
|
+
*/
|
|
599
|
+
map?: string
|
|
600
|
+
/**
|
|
601
|
+
* Customise the Prisma Schema for this list. This function is passed the
|
|
602
|
+
* Prisma Model for this list and should return a string containing the valid
|
|
603
|
+
* Prisma Model definition.
|
|
604
|
+
*/
|
|
605
|
+
extendPrismaSchema?: (schema: string) => string
|
|
606
|
+
}
|