@nixxie-cms/core 1.0.0 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/admin-ui/components/dist/nixxie-cms-core-admin-ui-components.cjs.js +4 -4
- package/admin-ui/components/dist/nixxie-cms-core-admin-ui-components.esm.js +4 -4
- package/admin-ui/context/dist/nixxie-cms-core-admin-ui-context.cjs.js +2 -2
- package/admin-ui/context/dist/nixxie-cms-core-admin-ui-context.esm.js +2 -2
- package/context/dist/nixxie-cms-core-context.cjs.js +2 -2
- package/context/dist/nixxie-cms-core-context.esm.js +2 -2
- package/dist/{CreateItemDialog-33335548.esm.js → CreateItemDialog-7008b050.esm.js} +1 -1
- package/dist/{CreateItemDialog-56cf59b7.cjs.js → CreateItemDialog-a0cab315.cjs.js} +1 -1
- package/dist/{PageContainer-7db73317.esm.js → PageContainer-5ae731cc.esm.js} +25 -18
- package/dist/{PageContainer-27c27f10.cjs.js → PageContainer-abd7159f.cjs.js} +25 -18
- package/dist/{admin-meta-graphql-6f7f5331.esm.js → admin-meta-graphql-0e6e606e.esm.js} +1 -1
- package/dist/{admin-meta-graphql-c8f926e9.cjs.js → admin-meta-graphql-306c224a.cjs.js} +1 -1
- package/dist/{context-3132c3ed.esm.js → context-af9957ed.esm.js} +2 -2
- package/dist/{context-e7a45152.cjs.js → context-b5204629.cjs.js} +2 -2
- package/dist/declarations/src/admin-ui/components/Navigation.d.ts.map +1 -1
- package/dist/declarations/src/admin-ui/components/PageContainer.d.ts.map +1 -1
- package/dist/declarations/src/helpers.d.ts.map +1 -1
- package/dist/declarations/src/index.d.ts +1 -0
- package/dist/declarations/src/index.d.ts.map +1 -1
- package/dist/declarations/src/internal-unstable/admin-ui/id-field-view.d.ts.map +1 -0
- package/dist/declarations/src/internal-unstable/admin-ui/pages/App/index.d.ts.map +1 -0
- package/dist/declarations/src/internal-unstable/admin-ui/pages/CreateItemPage/index.d.ts.map +1 -0
- package/dist/declarations/src/internal-unstable/admin-ui/pages/HomePage/index.d.ts.map +1 -0
- package/dist/declarations/src/internal-unstable/admin-ui/pages/ItemPage/index.d.ts.map +1 -0
- package/dist/declarations/src/internal-unstable/admin-ui/pages/ListPage/index.d.ts.map +1 -0
- package/dist/declarations/src/internal-unstable/admin-ui/pages/NoAccessPage/index.d.ts.map +1 -0
- package/dist/declarations/src/internal-unstable/artifacts.d.ts.map +1 -0
- package/dist/declarations/src/lib/core/initialise-lists.d.ts +1 -1
- package/dist/declarations/src/schema.d.ts.map +1 -1
- package/dist/declarations/src/types/config/index.d.ts +60 -1
- package/dist/declarations/src/types/config/index.d.ts.map +1 -1
- package/dist/declarations/src/types/config/lists.d.ts +4 -4
- package/dist/declarations/src/types/context.d.ts +150 -0
- package/dist/declarations/src/types/context.d.ts.map +1 -1
- package/dist/declarations/src/types/next-fields.d.ts +1 -1
- package/dist/{express-e9ed9a7d.cjs.js → express-455ae20c.cjs.js} +1 -1
- package/dist/{express-6743b918.esm.js → express-7559ca2d.esm.js} +1 -1
- package/dist/{index-ac01583b.cjs.js → index-89635494.cjs.js} +4 -4
- package/dist/{index-24b78415.esm.js → index-baa799e0.esm.js} +4 -4
- package/dist/nixxie-cms-core.cjs.js +104 -77
- package/dist/nixxie-cms-core.esm.js +104 -77
- package/dist/{non-null-graphql-5315718c.esm.js → non-null-graphql-a84ed64d.esm.js} +1 -1
- package/dist/{non-null-graphql-17b83ddc.cjs.js → non-null-graphql-add6bb3d.cjs.js} +1 -1
- package/dist/{resolve-hooks-66fe8a8e.cjs.js → resolve-hooks-165a9ce2.cjs.js} +1 -1
- package/dist/{resolve-hooks-17aafd37.esm.js → resolve-hooks-6813a045.esm.js} +2 -2
- package/dist/{system-dfec2f0a.esm.js → system-03e49e4f.esm.js} +8 -4
- package/dist/{system-48c5f6df.cjs.js → system-a321642d.cjs.js} +8 -4
- package/dist/{useFilter-0b5a1ee6.esm.js → useFilter-9b6db1f9.esm.js} +1 -1
- package/dist/{useFilter-1a4e6900.cjs.js → useFilter-acc9d413.cjs.js} +1 -1
- package/fields/dist/nixxie-cms-core-fields.cjs.js +16 -16
- package/fields/dist/nixxie-cms-core-fields.esm.js +17 -17
- package/fields/types/bytes/dist/nixxie-cms-core-fields-types-bytes.cjs.js +3 -3
- package/fields/types/bytes/dist/nixxie-cms-core-fields-types-bytes.esm.js +3 -3
- package/fields/types/bytes/views/dist/nixxie-cms-core-fields-types-bytes-views.cjs.js +1 -1
- package/fields/types/bytes/views/dist/nixxie-cms-core-fields-types-bytes-views.esm.js +1 -1
- package/fields/types/password/dist/nixxie-cms-core-fields-types-password.cjs.js +3 -3
- package/fields/types/password/dist/nixxie-cms-core-fields-types-password.esm.js +3 -3
- package/fields/types/relationship/views/dist/nixxie-cms-core-fields-types-relationship-views.cjs.js +4 -4
- package/fields/types/relationship/views/dist/nixxie-cms-core-fields-types-relationship-views.esm.js +4 -4
- package/fields/types/select/views/dist/nixxie-cms-core-fields-types-select-views.cjs.js +1 -1
- package/fields/types/select/views/dist/nixxie-cms-core-fields-types-select-views.esm.js +1 -1
- package/fields/types/text/views/dist/nixxie-cms-core-fields-types-text-views.cjs.js +1 -1
- package/fields/types/text/views/dist/nixxie-cms-core-fields-types-text-views.esm.js +1 -1
- package/internal-unstable/admin-ui/id-field-view/dist/nixxie-cms-core-internal-unstable-admin-ui-id-field-view.cjs.d.ts +2 -0
- package/internal-unstable/admin-ui/id-field-view/dist/nixxie-cms-core-internal-unstable-admin-ui-id-field-view.cjs.js +244 -0
- package/internal-unstable/admin-ui/id-field-view/dist/nixxie-cms-core-internal-unstable-admin-ui-id-field-view.esm.js +235 -0
- package/internal-unstable/admin-ui/id-field-view/package.json +4 -0
- package/internal-unstable/admin-ui/next-config/package.json +4 -0
- package/internal-unstable/admin-ui/pages/App/dist/nixxie-cms-core-internal-unstable-admin-ui-pages-App.cjs.d.ts +2 -0
- package/internal-unstable/admin-ui/pages/App/dist/nixxie-cms-core-internal-unstable-admin-ui-pages-App.cjs.js +59 -0
- package/internal-unstable/admin-ui/pages/App/dist/nixxie-cms-core-internal-unstable-admin-ui-pages-App.esm.js +55 -0
- package/internal-unstable/admin-ui/pages/App/package.json +4 -0
- package/internal-unstable/admin-ui/pages/CreateItemPage/dist/nixxie-cms-core-internal-unstable-admin-ui-pages-CreateItemPage.cjs.d.ts +2 -0
- package/internal-unstable/admin-ui/pages/CreateItemPage/dist/nixxie-cms-core-internal-unstable-admin-ui-pages-CreateItemPage.cjs.js +116 -0
- package/internal-unstable/admin-ui/pages/CreateItemPage/dist/nixxie-cms-core-internal-unstable-admin-ui-pages-CreateItemPage.esm.js +112 -0
- package/internal-unstable/admin-ui/pages/CreateItemPage/package.json +4 -0
- package/internal-unstable/admin-ui/pages/HomePage/dist/nixxie-cms-core-internal-unstable-admin-ui-pages-HomePage.cjs.d.ts +2 -0
- package/internal-unstable/admin-ui/pages/HomePage/dist/nixxie-cms-core-internal-unstable-admin-ui-pages-HomePage.cjs.js +336 -0
- package/internal-unstable/admin-ui/pages/HomePage/dist/nixxie-cms-core-internal-unstable-admin-ui-pages-HomePage.esm.js +332 -0
- package/internal-unstable/admin-ui/pages/HomePage/package.json +4 -0
- package/internal-unstable/admin-ui/pages/ItemPage/dist/nixxie-cms-core-internal-unstable-admin-ui-pages-ItemPage.cjs.d.ts +2 -0
- package/internal-unstable/admin-ui/pages/ItemPage/dist/nixxie-cms-core-internal-unstable-admin-ui-pages-ItemPage.cjs.js +463 -0
- package/internal-unstable/admin-ui/pages/ItemPage/dist/nixxie-cms-core-internal-unstable-admin-ui-pages-ItemPage.esm.js +455 -0
- package/internal-unstable/admin-ui/pages/ItemPage/package.json +4 -0
- package/internal-unstable/admin-ui/pages/ListPage/dist/nixxie-cms-core-internal-unstable-admin-ui-pages-ListPage.cjs.d.ts +2 -0
- package/internal-unstable/admin-ui/pages/ListPage/dist/nixxie-cms-core-internal-unstable-admin-ui-pages-ListPage.cjs.js +1195 -0
- package/internal-unstable/admin-ui/pages/ListPage/dist/nixxie-cms-core-internal-unstable-admin-ui-pages-ListPage.esm.js +1187 -0
- package/internal-unstable/admin-ui/pages/ListPage/package.json +4 -0
- package/internal-unstable/admin-ui/pages/NoAccessPage/dist/nixxie-cms-core-internal-unstable-admin-ui-pages-NoAccessPage.cjs.d.ts +2 -0
- package/internal-unstable/admin-ui/pages/NoAccessPage/dist/nixxie-cms-core-internal-unstable-admin-ui-pages-NoAccessPage.cjs.js +40 -0
- package/internal-unstable/admin-ui/pages/NoAccessPage/dist/nixxie-cms-core-internal-unstable-admin-ui-pages-NoAccessPage.esm.js +35 -0
- package/internal-unstable/admin-ui/pages/NoAccessPage/package.json +4 -0
- package/internal-unstable/artifacts/dist/nixxie-cms-core-internal-unstable-artifacts.cjs.d.ts +2 -0
- package/internal-unstable/artifacts/dist/nixxie-cms-core-internal-unstable-artifacts.cjs.js +51 -0
- package/internal-unstable/artifacts/dist/nixxie-cms-core-internal-unstable-artifacts.esm.js +38 -0
- package/internal-unstable/artifacts/package.json +4 -0
- package/package.json +44 -44
- package/scripts/cli/dist/nixxie-cms-core-scripts-cli.cjs.js +15 -15
- package/scripts/cli/dist/nixxie-cms-core-scripts-cli.esm.js +15 -15
- package/scripts/dist/nixxie-cms-core-scripts.cjs.js +3 -3
- package/scripts/dist/nixxie-cms-core-scripts.esm.js +3 -3
- package/src/admin-ui/admin-meta-graphql.ts +168 -168
- package/src/admin-ui/components/CommandPalette.tsx +433 -431
- package/src/admin-ui/components/Navigation.tsx +389 -385
- package/src/admin-ui/components/PageContainer.tsx +311 -310
- package/src/admin-ui/components/WelcomeDialog.tsx +1 -1
- package/src/admin-ui/context.tsx +338 -338
- package/src/admin-ui/templates/app.ts +60 -60
- package/src/admin-ui/templates/create-item.ts +5 -5
- package/src/admin-ui/templates/home.ts +2 -2
- package/src/admin-ui/templates/item.tsx +5 -5
- package/src/admin-ui/templates/list.tsx +5 -5
- package/src/admin-ui/templates/no-access.ts +7 -7
- package/src/fields/types/bigInt/index.ts +181 -181
- package/src/fields/types/bytes/index.ts +275 -275
- package/src/fields/types/calendarDay/index.ts +194 -194
- package/src/fields/types/checkbox/index.ts +76 -76
- package/src/fields/types/decimal/index.ts +182 -182
- package/src/fields/types/file/index.ts +168 -168
- package/src/fields/types/float/index.ts +133 -133
- package/src/fields/types/image/index.ts +244 -244
- package/src/fields/types/integer/index.ts +156 -156
- package/src/fields/types/json/index.ts +77 -77
- package/src/fields/types/multiselect/index.ts +212 -212
- package/src/fields/types/password/index.ts +241 -241
- package/src/fields/types/relationship/index.ts +381 -381
- package/src/fields/types/relationship/views/RelationshipTable.tsx +190 -190
- package/src/fields/types/select/index.ts +226 -226
- package/src/fields/types/text/index.ts +207 -207
- package/src/fields/types/timestamp/index.ts +116 -116
- package/src/fields/types/virtual/index.ts +108 -108
- package/src/helpers.ts +342 -316
- package/src/index.ts +4 -0
- package/src/{___internal-do-not-use-will-break-in-patch → internal-unstable}/admin-ui/id-field-view.tsx +167 -167
- package/src/{___internal-do-not-use-will-break-in-patch → internal-unstable}/admin-ui/pages/App/index.tsx +22 -22
- package/src/{___internal-do-not-use-will-break-in-patch → internal-unstable}/admin-ui/pages/CreateItemPage/index.tsx +71 -71
- package/src/{___internal-do-not-use-will-break-in-patch → internal-unstable}/admin-ui/pages/HomePage/index.tsx +333 -333
- package/src/{___internal-do-not-use-will-break-in-patch → internal-unstable}/admin-ui/pages/ItemPage/common.tsx +358 -358
- package/src/{___internal-do-not-use-will-break-in-patch → internal-unstable}/admin-ui/pages/ItemPage/index.tsx +483 -483
- package/src/{___internal-do-not-use-will-break-in-patch → internal-unstable}/admin-ui/pages/ListPage/FilterAdd.tsx +221 -221
- package/src/{___internal-do-not-use-will-break-in-patch → internal-unstable}/admin-ui/pages/ListPage/PaginationControls.tsx +170 -170
- package/src/{___internal-do-not-use-will-break-in-patch → internal-unstable}/admin-ui/pages/ListPage/Tag.tsx +72 -72
- package/src/{___internal-do-not-use-will-break-in-patch → internal-unstable}/admin-ui/pages/ListPage/index.tsx +1006 -1006
- package/src/{___internal-do-not-use-will-break-in-patch → internal-unstable}/admin-ui/pages/NoAccessPage/index.tsx +24 -24
- package/src/{___internal-do-not-use-will-break-in-patch → internal-unstable}/artifacts.ts +5 -5
- package/src/lib/context/createContext.ts +165 -161
- package/src/lib/core/initialise-lists.ts +1097 -1097
- package/src/lib/id-field.ts +214 -214
- package/src/lib/telemetry.ts +342 -342
- package/src/schema.ts +237 -233
- package/src/scripts/telemetry.ts +1 -1
- package/src/types/config/index.ts +400 -333
- package/src/types/config/lists.ts +4 -4
- package/src/types/context.ts +700 -530
- package/src/types/next-fields.ts +499 -499
- package/src/types/telemetry.ts +51 -51
- package/tests/telemetry.test.ts +361 -361
- package/CHANGELOG.md +0 -3158
- package/___internal-do-not-use-will-break-in-patch/admin-ui/id-field-view/package.json +0 -4
- package/___internal-do-not-use-will-break-in-patch/admin-ui/next-config/package.json +0 -4
- package/___internal-do-not-use-will-break-in-patch/admin-ui/pages/App/package.json +0 -4
- package/___internal-do-not-use-will-break-in-patch/admin-ui/pages/CreateItemPage/package.json +0 -4
- package/___internal-do-not-use-will-break-in-patch/admin-ui/pages/HomePage/package.json +0 -4
- package/___internal-do-not-use-will-break-in-patch/admin-ui/pages/ItemPage/package.json +0 -4
- package/___internal-do-not-use-will-break-in-patch/admin-ui/pages/ListPage/package.json +0 -4
- package/___internal-do-not-use-will-break-in-patch/admin-ui/pages/NoAccessPage/package.json +0 -4
- package/___internal-do-not-use-will-break-in-patch/artifacts/package.json +0 -4
- package/dist/declarations/src/___internal-do-not-use-will-break-in-patch/admin-ui/id-field-view.d.ts.map +0 -1
- package/dist/declarations/src/___internal-do-not-use-will-break-in-patch/admin-ui/pages/App/index.d.ts.map +0 -1
- package/dist/declarations/src/___internal-do-not-use-will-break-in-patch/admin-ui/pages/CreateItemPage/index.d.ts.map +0 -1
- package/dist/declarations/src/___internal-do-not-use-will-break-in-patch/admin-ui/pages/HomePage/index.d.ts.map +0 -1
- package/dist/declarations/src/___internal-do-not-use-will-break-in-patch/admin-ui/pages/ItemPage/index.d.ts.map +0 -1
- package/dist/declarations/src/___internal-do-not-use-will-break-in-patch/admin-ui/pages/ListPage/index.d.ts.map +0 -1
- package/dist/declarations/src/___internal-do-not-use-will-break-in-patch/admin-ui/pages/NoAccessPage/index.d.ts.map +0 -1
- package/dist/declarations/src/___internal-do-not-use-will-break-in-patch/artifacts.d.ts.map +0 -1
- /package/dist/{common-1a350e11.cjs.js → common-5933f758.cjs.js} +0 -0
- /package/dist/{common-29fc82e6.esm.js → common-ea5c441a.esm.js} +0 -0
- /package/dist/declarations/src/{___internal-do-not-use-will-break-in-patch → internal-unstable}/admin-ui/id-field-view.d.ts +0 -0
- /package/dist/declarations/src/{___internal-do-not-use-will-break-in-patch → internal-unstable}/admin-ui/pages/App/index.d.ts +0 -0
- /package/dist/declarations/src/{___internal-do-not-use-will-break-in-patch → internal-unstable}/admin-ui/pages/CreateItemPage/index.d.ts +0 -0
- /package/dist/declarations/src/{___internal-do-not-use-will-break-in-patch → internal-unstable}/admin-ui/pages/HomePage/index.d.ts +0 -0
- /package/dist/declarations/src/{___internal-do-not-use-will-break-in-patch → internal-unstable}/admin-ui/pages/ItemPage/index.d.ts +0 -0
- /package/dist/declarations/src/{___internal-do-not-use-will-break-in-patch → internal-unstable}/admin-ui/pages/ListPage/index.d.ts +0 -0
- /package/dist/declarations/src/{___internal-do-not-use-will-break-in-patch → internal-unstable}/admin-ui/pages/NoAccessPage/index.d.ts +0 -0
- /package/dist/declarations/src/{___internal-do-not-use-will-break-in-patch → internal-unstable}/artifacts.d.ts +0 -0
|
@@ -1,381 +1,381 @@
|
|
|
1
|
-
import { g } from '../../..'
|
|
2
|
-
import { type ListMetaSource, getAdminMetaForRelationshipField } from '../../../lib/admin-meta'
|
|
3
|
-
import {
|
|
4
|
-
type BaseListTypeInfo,
|
|
5
|
-
type CommonFieldConfig,
|
|
6
|
-
type FieldTypeFunc,
|
|
7
|
-
type JSONValue,
|
|
8
|
-
type ListSortDescriptor,
|
|
9
|
-
fieldType,
|
|
10
|
-
} from '../../../types'
|
|
11
|
-
import type { controller } from './views'
|
|
12
|
-
|
|
13
|
-
type ListKeyFromRef<Ref extends string> = Ref extends `${infer ListKey}.${string}` ? ListKey : Ref
|
|
14
|
-
|
|
15
|
-
// This is the default display mode for Relationships
|
|
16
|
-
type SelectDisplayConfig<ListTypeInfo extends BaseListTypeInfo, Ref extends string> = {
|
|
17
|
-
ui?: {
|
|
18
|
-
// Sets the relationship to display as a Select field
|
|
19
|
-
displayMode?: 'select'
|
|
20
|
-
/**
|
|
21
|
-
* The path of the field to use from the related list for item labels in the select.
|
|
22
|
-
* Defaults to the labelField (if set) on the related list.
|
|
23
|
-
*/
|
|
24
|
-
labelField?: string
|
|
25
|
-
/**
|
|
26
|
-
* The paths of the fields to use from the related list when searching in the select.
|
|
27
|
-
* Defaults to the initialSearchFields (if set) on the related list.
|
|
28
|
-
*/
|
|
29
|
-
searchFields?: string[]
|
|
30
|
-
/**
|
|
31
|
-
* The filter to apply when shown in the select.
|
|
32
|
-
* Defaults to the initialSort (if set) on the related list.
|
|
33
|
-
*/
|
|
34
|
-
filter?: ListTypeInfo['all']['lists'][ListKeyFromRef<Ref>]['inputs']['where']
|
|
35
|
-
/**
|
|
36
|
-
* The sort to apply when shown in the select.
|
|
37
|
-
* Defaults to the initialSort (if set) on the related list.
|
|
38
|
-
*/
|
|
39
|
-
sort?: ListSortDescriptor<string>
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
type CountDisplayConfig = {
|
|
44
|
-
many: true
|
|
45
|
-
ui?: {
|
|
46
|
-
// Sets the relationship to display as a count
|
|
47
|
-
displayMode: 'count'
|
|
48
|
-
itemView: {
|
|
49
|
-
fieldMode: 'read'
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
type TableDisplayConfig = {
|
|
55
|
-
ref: `${string}.${string}`
|
|
56
|
-
many: true
|
|
57
|
-
ui?: {
|
|
58
|
-
displayMode: 'table'
|
|
59
|
-
initialSort?: ListSortDescriptor<string>
|
|
60
|
-
columns?: string[]
|
|
61
|
-
|
|
62
|
-
itemView: {
|
|
63
|
-
fieldMode: 'read'
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
type OneDbConfig = {
|
|
69
|
-
many?: false
|
|
70
|
-
db?: {
|
|
71
|
-
extendPrismaSchema?: (field: string) => string
|
|
72
|
-
foreignKey?:
|
|
73
|
-
| true
|
|
74
|
-
| {
|
|
75
|
-
map: string
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
type ManyDbConfig = {
|
|
81
|
-
many: true
|
|
82
|
-
db?: {
|
|
83
|
-
relationName?: string
|
|
84
|
-
extendPrismaSchema?: (field: string) => string
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
function throwIfMissingFields(
|
|
89
|
-
localListMeta: ListMetaSource,
|
|
90
|
-
foreignListMeta: ListMetaSource,
|
|
91
|
-
refLabelField: string,
|
|
92
|
-
refSearchFields: string[],
|
|
93
|
-
fieldKey: string
|
|
94
|
-
) {
|
|
95
|
-
if (!(refLabelField in foreignListMeta.fieldsByKey)) {
|
|
96
|
-
throw new Error(
|
|
97
|
-
`"${refLabelField}" is not a field of list "${foreignListMeta.key}", configured as labelField for "${localListMeta.key}.${fieldKey}"`
|
|
98
|
-
)
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
for (const searchFieldKey of refSearchFields) {
|
|
102
|
-
const field = foreignListMeta.fieldsByKey[searchFieldKey]
|
|
103
|
-
if (!field)
|
|
104
|
-
throw new Error(
|
|
105
|
-
`"${searchFieldKey}" is not a field of list "${foreignListMeta.key}", configured as searchField for "${localListMeta.key}.${fieldKey}"`
|
|
106
|
-
)
|
|
107
|
-
|
|
108
|
-
if (field.search === null)
|
|
109
|
-
throw new Error(
|
|
110
|
-
`"${searchFieldKey}" is not a searchable field of list "${foreignListMeta.key}", configured as searchField for "${localListMeta.key}.${fieldKey}"`
|
|
111
|
-
)
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
type ArrayOr<T> = T | T[]
|
|
116
|
-
|
|
117
|
-
// TODO: add types based on list types
|
|
118
|
-
type FieldTypeInfo = {
|
|
119
|
-
item: undefined
|
|
120
|
-
inputs: {
|
|
121
|
-
where: any
|
|
122
|
-
create: JSONValue | undefined
|
|
123
|
-
update: JSONValue | undefined
|
|
124
|
-
uniqueWhere: undefined
|
|
125
|
-
orderBy: undefined
|
|
126
|
-
}
|
|
127
|
-
prisma: {
|
|
128
|
-
create:
|
|
129
|
-
| {
|
|
130
|
-
connect?: ArrayOr<{ id?: string; [key: string]: unknown }>
|
|
131
|
-
create?: any
|
|
132
|
-
set?: ArrayOr<{ id?: string; [key: string]: unknown }>
|
|
133
|
-
}
|
|
134
|
-
| undefined
|
|
135
|
-
| null
|
|
136
|
-
update:
|
|
137
|
-
| {
|
|
138
|
-
connect?: ArrayOr<{ id?: string; [key: string]: unknown }>
|
|
139
|
-
create?: any
|
|
140
|
-
set?: ArrayOr<{ id?: string; [key: string]: unknown }>
|
|
141
|
-
disconnect?: boolean | ArrayOr<{ id?: string; [key: string]: unknown }> | undefined
|
|
142
|
-
}
|
|
143
|
-
| undefined
|
|
144
|
-
| null
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
export type RelationshipFieldConfig<
|
|
149
|
-
ListTypeInfo extends BaseListTypeInfo,
|
|
150
|
-
Ref extends `${keyof ListTypeInfo['all']['lists'] & string}${'' | `.${string}`}`,
|
|
151
|
-
> = CommonFieldConfig<ListTypeInfo, FieldTypeInfo> & {
|
|
152
|
-
many?: boolean
|
|
153
|
-
ref: Ref
|
|
154
|
-
ui?: {
|
|
155
|
-
hideCreate?: boolean
|
|
156
|
-
}
|
|
157
|
-
} & (OneDbConfig | ManyDbConfig) &
|
|
158
|
-
(SelectDisplayConfig<ListTypeInfo, Ref> | CountDisplayConfig | TableDisplayConfig)
|
|
159
|
-
|
|
160
|
-
export function relationship<
|
|
161
|
-
ListTypeInfo extends BaseListTypeInfo,
|
|
162
|
-
Ref extends `${keyof ListTypeInfo['all']['lists'] & string}${'' | `.${string}`}`,
|
|
163
|
-
>({ ref, ...config }: RelationshipFieldConfig<ListTypeInfo, Ref>): FieldTypeFunc<ListTypeInfo> {
|
|
164
|
-
const { many = false } = config
|
|
165
|
-
const [foreignListKey, foreignFieldKey] = ref.split('.') as [string, string | undefined]
|
|
166
|
-
|
|
167
|
-
return ({ fieldKey, listKey, lists }) => {
|
|
168
|
-
const foreignList = lists[foreignListKey]
|
|
169
|
-
if (!foreignList)
|
|
170
|
-
throw new Error(`${listKey}.${fieldKey} points to ${ref}, but ${ref} doesn't exist`)
|
|
171
|
-
|
|
172
|
-
const foreignListTypes = foreignList.types
|
|
173
|
-
const commonConfig = {
|
|
174
|
-
...config,
|
|
175
|
-
|
|
176
|
-
views: '@nixxie-cms/core/fields/types/relationship/views',
|
|
177
|
-
getAdminMeta: (): Parameters<typeof controller>[0]['fieldMeta'] => {
|
|
178
|
-
const adminMetaRoot = getAdminMetaForRelationshipField()
|
|
179
|
-
const localListMeta = adminMetaRoot.listsByKey[listKey]
|
|
180
|
-
const foreignListMeta = adminMetaRoot.listsByKey[foreignListKey]
|
|
181
|
-
|
|
182
|
-
if (!foreignListMeta) {
|
|
183
|
-
throw new Error(`The ref [${ref}] on relationship [${listKey}.${fieldKey}] is invalid`)
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
const refLabelField = foreignListMeta.labelField
|
|
187
|
-
const refSearchFields = foreignListMeta.initialSearchFields
|
|
188
|
-
|
|
189
|
-
const hasOmittedCreate =
|
|
190
|
-
!lists[foreignListKey].types.relateTo[many ? 'many' : 'one'].create.getFields().create
|
|
191
|
-
const hideCreate = config.ui?.hideCreate ?? hasOmittedCreate
|
|
192
|
-
if (!hideCreate && hasOmittedCreate) {
|
|
193
|
-
throw new Error(
|
|
194
|
-
`${listKey}.${fieldKey} has ui.hideCreate: false, but the related list ${foreignListKey} has graphql.omit.create: true`
|
|
195
|
-
)
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
if (config.ui?.displayMode === 'count') {
|
|
199
|
-
if (config.ui.itemView?.fieldMode !== 'read') {
|
|
200
|
-
throw new Error(
|
|
201
|
-
`displayMode: 'count' on relationship fields requires itemView.fieldMode to be 'read' but ${listKey}.${fieldKey} does not have this set`
|
|
202
|
-
)
|
|
203
|
-
}
|
|
204
|
-
return {
|
|
205
|
-
displayMode: 'count',
|
|
206
|
-
refListKey: foreignListKey,
|
|
207
|
-
refFieldKey: foreignFieldKey,
|
|
208
|
-
many,
|
|
209
|
-
hideCreate,
|
|
210
|
-
refLabelField,
|
|
211
|
-
refSearchFields,
|
|
212
|
-
}
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
if (config.ui?.displayMode === 'table') {
|
|
216
|
-
if (!foreignFieldKey) {
|
|
217
|
-
throw new Error(
|
|
218
|
-
`Using a two-sided relationship (\`ref\` must specify "List.fieldKey", not just "List") is required when using displayMode: 'table' for relationship fields but ${listKey}.${fieldKey} has \`ref: ${JSON.stringify(ref)}\``
|
|
219
|
-
)
|
|
220
|
-
}
|
|
221
|
-
if (config.ui.itemView?.fieldMode !== 'read') {
|
|
222
|
-
throw new Error(
|
|
223
|
-
`displayMode: 'table' on relationship fields currently requires itemView.fieldMode to be 'read' but ${listKey}.${fieldKey} does not have this set`
|
|
224
|
-
)
|
|
225
|
-
}
|
|
226
|
-
for (const key of config.ui.columns ?? []) {
|
|
227
|
-
if (!(key in foreignListMeta.fieldsByKey)) {
|
|
228
|
-
throw new Error(
|
|
229
|
-
`The field "${foreignListMeta.key}.${key}" does not exist, configured as a column for "${localListMeta.key}.${fieldKey}"`
|
|
230
|
-
)
|
|
231
|
-
}
|
|
232
|
-
}
|
|
233
|
-
if (config.ui.initialSort) {
|
|
234
|
-
const field = foreignListMeta.fieldsByKey[config.ui.initialSort.field]
|
|
235
|
-
if (!field) {
|
|
236
|
-
throw new Error(
|
|
237
|
-
`The field "${foreignListMeta.key}.${config.ui.initialSort.field}" does not exist, configured as the initialSort field for "${localListMeta.key}.${fieldKey}"`
|
|
238
|
-
)
|
|
239
|
-
}
|
|
240
|
-
if (!field.isOrderable) {
|
|
241
|
-
throw new Error(
|
|
242
|
-
`The field "${foreignListMeta.key}.${config.ui.initialSort.field}" is not orderable, configured as the initialSort field for "${localListMeta.key}.${fieldKey}"`
|
|
243
|
-
)
|
|
244
|
-
}
|
|
245
|
-
}
|
|
246
|
-
return {
|
|
247
|
-
displayMode: 'table',
|
|
248
|
-
refListKey: foreignListKey,
|
|
249
|
-
refFieldKey: foreignFieldKey,
|
|
250
|
-
initialSort: config.ui.initialSort ?? foreignListMeta.initialSort ?? null,
|
|
251
|
-
columns: config.ui.columns ?? null,
|
|
252
|
-
many,
|
|
253
|
-
hideCreate,
|
|
254
|
-
refLabelField,
|
|
255
|
-
refSearchFields,
|
|
256
|
-
}
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
// prefer the local definition to the foreign list, if provided
|
|
260
|
-
const specificRefLabelField = config.ui?.labelField ?? refLabelField
|
|
261
|
-
const specificRefSearchFields = config.ui?.searchFields ?? refSearchFields
|
|
262
|
-
throwIfMissingFields(
|
|
263
|
-
localListMeta,
|
|
264
|
-
foreignListMeta,
|
|
265
|
-
specificRefLabelField,
|
|
266
|
-
specificRefSearchFields,
|
|
267
|
-
fieldKey
|
|
268
|
-
)
|
|
269
|
-
return {
|
|
270
|
-
displayMode: 'select',
|
|
271
|
-
refListKey: foreignListKey,
|
|
272
|
-
refFieldKey: foreignFieldKey,
|
|
273
|
-
many,
|
|
274
|
-
hideCreate,
|
|
275
|
-
refLabelField: specificRefLabelField,
|
|
276
|
-
refSearchFields: specificRefSearchFields,
|
|
277
|
-
filter: config.ui?.filter ?? null,
|
|
278
|
-
sort: config.ui?.sort ?? foreignListMeta.initialSort ?? null,
|
|
279
|
-
}
|
|
280
|
-
},
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
if (config.many) {
|
|
284
|
-
return fieldType({
|
|
285
|
-
kind: 'relation',
|
|
286
|
-
mode: 'many',
|
|
287
|
-
list: foreignListKey,
|
|
288
|
-
field: foreignFieldKey,
|
|
289
|
-
relationName: config.db?.relationName,
|
|
290
|
-
extendPrismaSchema: config.db?.extendPrismaSchema,
|
|
291
|
-
})({
|
|
292
|
-
...commonConfig,
|
|
293
|
-
input: {
|
|
294
|
-
where: {
|
|
295
|
-
arg: g.arg({ type: foreignListTypes.relateTo.many.where }),
|
|
296
|
-
resolve(value, _context, resolve) {
|
|
297
|
-
return resolve(value)
|
|
298
|
-
},
|
|
299
|
-
},
|
|
300
|
-
create: {
|
|
301
|
-
arg: g.arg({ type: foreignListTypes.relateTo.many.create }),
|
|
302
|
-
async resolve(value, _context, resolve) {
|
|
303
|
-
return resolve(value)
|
|
304
|
-
},
|
|
305
|
-
},
|
|
306
|
-
update: {
|
|
307
|
-
arg: g.arg({ type: foreignListTypes.relateTo.many.update }),
|
|
308
|
-
async resolve(value, _context, resolve) {
|
|
309
|
-
return resolve(value)
|
|
310
|
-
},
|
|
311
|
-
},
|
|
312
|
-
},
|
|
313
|
-
output: g.field({
|
|
314
|
-
args: foreignListTypes.findManyArgs,
|
|
315
|
-
type: g.list(g.nonNull(foreignListTypes.output)),
|
|
316
|
-
resolve({ value }, args) {
|
|
317
|
-
return value.findMany(args)
|
|
318
|
-
},
|
|
319
|
-
}),
|
|
320
|
-
extraOutputFields: {
|
|
321
|
-
[`${fieldKey}Count`]: g.field({
|
|
322
|
-
type: g.Int,
|
|
323
|
-
args: {
|
|
324
|
-
where: g.arg({
|
|
325
|
-
type: g.nonNull(foreignListTypes.where),
|
|
326
|
-
defaultValue: {},
|
|
327
|
-
}),
|
|
328
|
-
},
|
|
329
|
-
resolve({ value }, args) {
|
|
330
|
-
return value.count({
|
|
331
|
-
where: args.where,
|
|
332
|
-
})
|
|
333
|
-
},
|
|
334
|
-
}),
|
|
335
|
-
},
|
|
336
|
-
})
|
|
337
|
-
}
|
|
338
|
-
|
|
339
|
-
return fieldType({
|
|
340
|
-
kind: 'relation',
|
|
341
|
-
mode: 'one',
|
|
342
|
-
list: foreignListKey,
|
|
343
|
-
field: foreignFieldKey,
|
|
344
|
-
foreignKey: config.db?.foreignKey,
|
|
345
|
-
extendPrismaSchema: config.db?.extendPrismaSchema,
|
|
346
|
-
})({
|
|
347
|
-
...commonConfig,
|
|
348
|
-
input: {
|
|
349
|
-
where: {
|
|
350
|
-
arg: g.arg({ type: foreignListTypes.where }),
|
|
351
|
-
resolve(value, _context, resolve) {
|
|
352
|
-
return resolve(value)
|
|
353
|
-
},
|
|
354
|
-
},
|
|
355
|
-
uniqueWhere: {
|
|
356
|
-
arg: g.arg({ type: foreignListTypes.uniqueWhere }),
|
|
357
|
-
},
|
|
358
|
-
|
|
359
|
-
create: foreignListTypes.relateTo.one.create && {
|
|
360
|
-
arg: g.arg({ type: foreignListTypes.relateTo.one.create }),
|
|
361
|
-
async resolve(value, _context, resolve) {
|
|
362
|
-
return resolve(value)
|
|
363
|
-
},
|
|
364
|
-
},
|
|
365
|
-
|
|
366
|
-
update: foreignListTypes.relateTo.one.update && {
|
|
367
|
-
arg: g.arg({ type: foreignListTypes.relateTo.one.update }),
|
|
368
|
-
async resolve(value, _context, resolve) {
|
|
369
|
-
return resolve(value)
|
|
370
|
-
},
|
|
371
|
-
},
|
|
372
|
-
},
|
|
373
|
-
output: g.field({
|
|
374
|
-
type: foreignListTypes.output,
|
|
375
|
-
resolve({ value }) {
|
|
376
|
-
return value()
|
|
377
|
-
},
|
|
378
|
-
}),
|
|
379
|
-
})
|
|
380
|
-
}
|
|
381
|
-
}
|
|
1
|
+
import { g } from '../../..'
|
|
2
|
+
import { type ListMetaSource, getAdminMetaForRelationshipField } from '../../../lib/admin-meta'
|
|
3
|
+
import {
|
|
4
|
+
type BaseListTypeInfo,
|
|
5
|
+
type CommonFieldConfig,
|
|
6
|
+
type FieldTypeFunc,
|
|
7
|
+
type JSONValue,
|
|
8
|
+
type ListSortDescriptor,
|
|
9
|
+
fieldType,
|
|
10
|
+
} from '../../../types'
|
|
11
|
+
import type { controller } from './views'
|
|
12
|
+
|
|
13
|
+
type ListKeyFromRef<Ref extends string> = Ref extends `${infer ListKey}.${string}` ? ListKey : Ref
|
|
14
|
+
|
|
15
|
+
// This is the default display mode for Relationships
|
|
16
|
+
type SelectDisplayConfig<ListTypeInfo extends BaseListTypeInfo, Ref extends string> = {
|
|
17
|
+
ui?: {
|
|
18
|
+
// Sets the relationship to display as a Select field
|
|
19
|
+
displayMode?: 'select'
|
|
20
|
+
/**
|
|
21
|
+
* The path of the field to use from the related list for item labels in the select.
|
|
22
|
+
* Defaults to the labelField (if set) on the related list.
|
|
23
|
+
*/
|
|
24
|
+
labelField?: string
|
|
25
|
+
/**
|
|
26
|
+
* The paths of the fields to use from the related list when searching in the select.
|
|
27
|
+
* Defaults to the initialSearchFields (if set) on the related list.
|
|
28
|
+
*/
|
|
29
|
+
searchFields?: string[]
|
|
30
|
+
/**
|
|
31
|
+
* The filter to apply when shown in the select.
|
|
32
|
+
* Defaults to the initialSort (if set) on the related list.
|
|
33
|
+
*/
|
|
34
|
+
filter?: ListTypeInfo['all']['lists'][ListKeyFromRef<Ref>]['inputs']['where']
|
|
35
|
+
/**
|
|
36
|
+
* The sort to apply when shown in the select.
|
|
37
|
+
* Defaults to the initialSort (if set) on the related list.
|
|
38
|
+
*/
|
|
39
|
+
sort?: ListSortDescriptor<string>
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
type CountDisplayConfig = {
|
|
44
|
+
many: true
|
|
45
|
+
ui?: {
|
|
46
|
+
// Sets the relationship to display as a count
|
|
47
|
+
displayMode: 'count'
|
|
48
|
+
itemView: {
|
|
49
|
+
fieldMode: 'read'
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
type TableDisplayConfig = {
|
|
55
|
+
ref: `${string}.${string}`
|
|
56
|
+
many: true
|
|
57
|
+
ui?: {
|
|
58
|
+
displayMode: 'table'
|
|
59
|
+
initialSort?: ListSortDescriptor<string>
|
|
60
|
+
columns?: string[]
|
|
61
|
+
|
|
62
|
+
itemView: {
|
|
63
|
+
fieldMode: 'read'
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
type OneDbConfig = {
|
|
69
|
+
many?: false
|
|
70
|
+
db?: {
|
|
71
|
+
extendPrismaSchema?: (field: string) => string
|
|
72
|
+
foreignKey?:
|
|
73
|
+
| true
|
|
74
|
+
| {
|
|
75
|
+
map: string
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
type ManyDbConfig = {
|
|
81
|
+
many: true
|
|
82
|
+
db?: {
|
|
83
|
+
relationName?: string
|
|
84
|
+
extendPrismaSchema?: (field: string) => string
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function throwIfMissingFields(
|
|
89
|
+
localListMeta: ListMetaSource,
|
|
90
|
+
foreignListMeta: ListMetaSource,
|
|
91
|
+
refLabelField: string,
|
|
92
|
+
refSearchFields: string[],
|
|
93
|
+
fieldKey: string
|
|
94
|
+
) {
|
|
95
|
+
if (!(refLabelField in foreignListMeta.fieldsByKey)) {
|
|
96
|
+
throw new Error(
|
|
97
|
+
`"${refLabelField}" is not a field of list "${foreignListMeta.key}", configured as labelField for "${localListMeta.key}.${fieldKey}"`
|
|
98
|
+
)
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
for (const searchFieldKey of refSearchFields) {
|
|
102
|
+
const field = foreignListMeta.fieldsByKey[searchFieldKey]
|
|
103
|
+
if (!field)
|
|
104
|
+
throw new Error(
|
|
105
|
+
`"${searchFieldKey}" is not a field of list "${foreignListMeta.key}", configured as searchField for "${localListMeta.key}.${fieldKey}"`
|
|
106
|
+
)
|
|
107
|
+
|
|
108
|
+
if (field.search === null)
|
|
109
|
+
throw new Error(
|
|
110
|
+
`"${searchFieldKey}" is not a searchable field of list "${foreignListMeta.key}", configured as searchField for "${localListMeta.key}.${fieldKey}"`
|
|
111
|
+
)
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
type ArrayOr<T> = T | T[]
|
|
116
|
+
|
|
117
|
+
// TODO: add types based on list types
|
|
118
|
+
type FieldTypeInfo = {
|
|
119
|
+
item: undefined
|
|
120
|
+
inputs: {
|
|
121
|
+
where: any
|
|
122
|
+
create: JSONValue | undefined
|
|
123
|
+
update: JSONValue | undefined
|
|
124
|
+
uniqueWhere: undefined
|
|
125
|
+
orderBy: undefined
|
|
126
|
+
}
|
|
127
|
+
prisma: {
|
|
128
|
+
create:
|
|
129
|
+
| {
|
|
130
|
+
connect?: ArrayOr<{ id?: string; [key: string]: unknown }>
|
|
131
|
+
create?: any
|
|
132
|
+
set?: ArrayOr<{ id?: string; [key: string]: unknown }>
|
|
133
|
+
}
|
|
134
|
+
| undefined
|
|
135
|
+
| null
|
|
136
|
+
update:
|
|
137
|
+
| {
|
|
138
|
+
connect?: ArrayOr<{ id?: string; [key: string]: unknown }>
|
|
139
|
+
create?: any
|
|
140
|
+
set?: ArrayOr<{ id?: string; [key: string]: unknown }>
|
|
141
|
+
disconnect?: boolean | ArrayOr<{ id?: string; [key: string]: unknown }> | undefined
|
|
142
|
+
}
|
|
143
|
+
| undefined
|
|
144
|
+
| null
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
export type RelationshipFieldConfig<
|
|
149
|
+
ListTypeInfo extends BaseListTypeInfo,
|
|
150
|
+
Ref extends `${keyof ListTypeInfo['all']['lists'] & string}${'' | `.${string}`}`,
|
|
151
|
+
> = CommonFieldConfig<ListTypeInfo, FieldTypeInfo> & {
|
|
152
|
+
many?: boolean
|
|
153
|
+
ref: Ref
|
|
154
|
+
ui?: {
|
|
155
|
+
hideCreate?: boolean
|
|
156
|
+
}
|
|
157
|
+
} & (OneDbConfig | ManyDbConfig) &
|
|
158
|
+
(SelectDisplayConfig<ListTypeInfo, Ref> | CountDisplayConfig | TableDisplayConfig)
|
|
159
|
+
|
|
160
|
+
export function relationship<
|
|
161
|
+
ListTypeInfo extends BaseListTypeInfo,
|
|
162
|
+
Ref extends `${keyof ListTypeInfo['all']['lists'] & string}${'' | `.${string}`}`,
|
|
163
|
+
>({ ref, ...config }: RelationshipFieldConfig<ListTypeInfo, Ref>): FieldTypeFunc<ListTypeInfo> {
|
|
164
|
+
const { many = false } = config
|
|
165
|
+
const [foreignListKey, foreignFieldKey] = ref.split('.') as [string, string | undefined]
|
|
166
|
+
|
|
167
|
+
return ({ fieldKey, listKey, lists }) => {
|
|
168
|
+
const foreignList = lists[foreignListKey]
|
|
169
|
+
if (!foreignList)
|
|
170
|
+
throw new Error(`${listKey}.${fieldKey} points to ${ref}, but ${ref} doesn't exist`)
|
|
171
|
+
|
|
172
|
+
const foreignListTypes = foreignList.types
|
|
173
|
+
const commonConfig = {
|
|
174
|
+
...config,
|
|
175
|
+
__nxTelemetryFieldTypeName: '@nixxie-cms/relationship',
|
|
176
|
+
views: '@nixxie-cms/core/fields/types/relationship/views',
|
|
177
|
+
getAdminMeta: (): Parameters<typeof controller>[0]['fieldMeta'] => {
|
|
178
|
+
const adminMetaRoot = getAdminMetaForRelationshipField()
|
|
179
|
+
const localListMeta = adminMetaRoot.listsByKey[listKey]
|
|
180
|
+
const foreignListMeta = adminMetaRoot.listsByKey[foreignListKey]
|
|
181
|
+
|
|
182
|
+
if (!foreignListMeta) {
|
|
183
|
+
throw new Error(`The ref [${ref}] on relationship [${listKey}.${fieldKey}] is invalid`)
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
const refLabelField = foreignListMeta.labelField
|
|
187
|
+
const refSearchFields = foreignListMeta.initialSearchFields
|
|
188
|
+
|
|
189
|
+
const hasOmittedCreate =
|
|
190
|
+
!lists[foreignListKey].types.relateTo[many ? 'many' : 'one'].create.getFields().create
|
|
191
|
+
const hideCreate = config.ui?.hideCreate ?? hasOmittedCreate
|
|
192
|
+
if (!hideCreate && hasOmittedCreate) {
|
|
193
|
+
throw new Error(
|
|
194
|
+
`${listKey}.${fieldKey} has ui.hideCreate: false, but the related list ${foreignListKey} has graphql.omit.create: true`
|
|
195
|
+
)
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
if (config.ui?.displayMode === 'count') {
|
|
199
|
+
if (config.ui.itemView?.fieldMode !== 'read') {
|
|
200
|
+
throw new Error(
|
|
201
|
+
`displayMode: 'count' on relationship fields requires itemView.fieldMode to be 'read' but ${listKey}.${fieldKey} does not have this set`
|
|
202
|
+
)
|
|
203
|
+
}
|
|
204
|
+
return {
|
|
205
|
+
displayMode: 'count',
|
|
206
|
+
refListKey: foreignListKey,
|
|
207
|
+
refFieldKey: foreignFieldKey,
|
|
208
|
+
many,
|
|
209
|
+
hideCreate,
|
|
210
|
+
refLabelField,
|
|
211
|
+
refSearchFields,
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
if (config.ui?.displayMode === 'table') {
|
|
216
|
+
if (!foreignFieldKey) {
|
|
217
|
+
throw new Error(
|
|
218
|
+
`Using a two-sided relationship (\`ref\` must specify "List.fieldKey", not just "List") is required when using displayMode: 'table' for relationship fields but ${listKey}.${fieldKey} has \`ref: ${JSON.stringify(ref)}\``
|
|
219
|
+
)
|
|
220
|
+
}
|
|
221
|
+
if (config.ui.itemView?.fieldMode !== 'read') {
|
|
222
|
+
throw new Error(
|
|
223
|
+
`displayMode: 'table' on relationship fields currently requires itemView.fieldMode to be 'read' but ${listKey}.${fieldKey} does not have this set`
|
|
224
|
+
)
|
|
225
|
+
}
|
|
226
|
+
for (const key of config.ui.columns ?? []) {
|
|
227
|
+
if (!(key in foreignListMeta.fieldsByKey)) {
|
|
228
|
+
throw new Error(
|
|
229
|
+
`The field "${foreignListMeta.key}.${key}" does not exist, configured as a column for "${localListMeta.key}.${fieldKey}"`
|
|
230
|
+
)
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
if (config.ui.initialSort) {
|
|
234
|
+
const field = foreignListMeta.fieldsByKey[config.ui.initialSort.field]
|
|
235
|
+
if (!field) {
|
|
236
|
+
throw new Error(
|
|
237
|
+
`The field "${foreignListMeta.key}.${config.ui.initialSort.field}" does not exist, configured as the initialSort field for "${localListMeta.key}.${fieldKey}"`
|
|
238
|
+
)
|
|
239
|
+
}
|
|
240
|
+
if (!field.isOrderable) {
|
|
241
|
+
throw new Error(
|
|
242
|
+
`The field "${foreignListMeta.key}.${config.ui.initialSort.field}" is not orderable, configured as the initialSort field for "${localListMeta.key}.${fieldKey}"`
|
|
243
|
+
)
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
return {
|
|
247
|
+
displayMode: 'table',
|
|
248
|
+
refListKey: foreignListKey,
|
|
249
|
+
refFieldKey: foreignFieldKey,
|
|
250
|
+
initialSort: config.ui.initialSort ?? foreignListMeta.initialSort ?? null,
|
|
251
|
+
columns: config.ui.columns ?? null,
|
|
252
|
+
many,
|
|
253
|
+
hideCreate,
|
|
254
|
+
refLabelField,
|
|
255
|
+
refSearchFields,
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
// prefer the local definition to the foreign list, if provided
|
|
260
|
+
const specificRefLabelField = config.ui?.labelField ?? refLabelField
|
|
261
|
+
const specificRefSearchFields = config.ui?.searchFields ?? refSearchFields
|
|
262
|
+
throwIfMissingFields(
|
|
263
|
+
localListMeta,
|
|
264
|
+
foreignListMeta,
|
|
265
|
+
specificRefLabelField,
|
|
266
|
+
specificRefSearchFields,
|
|
267
|
+
fieldKey
|
|
268
|
+
)
|
|
269
|
+
return {
|
|
270
|
+
displayMode: 'select',
|
|
271
|
+
refListKey: foreignListKey,
|
|
272
|
+
refFieldKey: foreignFieldKey,
|
|
273
|
+
many,
|
|
274
|
+
hideCreate,
|
|
275
|
+
refLabelField: specificRefLabelField,
|
|
276
|
+
refSearchFields: specificRefSearchFields,
|
|
277
|
+
filter: config.ui?.filter ?? null,
|
|
278
|
+
sort: config.ui?.sort ?? foreignListMeta.initialSort ?? null,
|
|
279
|
+
}
|
|
280
|
+
},
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
if (config.many) {
|
|
284
|
+
return fieldType({
|
|
285
|
+
kind: 'relation',
|
|
286
|
+
mode: 'many',
|
|
287
|
+
list: foreignListKey,
|
|
288
|
+
field: foreignFieldKey,
|
|
289
|
+
relationName: config.db?.relationName,
|
|
290
|
+
extendPrismaSchema: config.db?.extendPrismaSchema,
|
|
291
|
+
})({
|
|
292
|
+
...commonConfig,
|
|
293
|
+
input: {
|
|
294
|
+
where: {
|
|
295
|
+
arg: g.arg({ type: foreignListTypes.relateTo.many.where }),
|
|
296
|
+
resolve(value, _context, resolve) {
|
|
297
|
+
return resolve(value)
|
|
298
|
+
},
|
|
299
|
+
},
|
|
300
|
+
create: {
|
|
301
|
+
arg: g.arg({ type: foreignListTypes.relateTo.many.create }),
|
|
302
|
+
async resolve(value, _context, resolve) {
|
|
303
|
+
return resolve(value)
|
|
304
|
+
},
|
|
305
|
+
},
|
|
306
|
+
update: {
|
|
307
|
+
arg: g.arg({ type: foreignListTypes.relateTo.many.update }),
|
|
308
|
+
async resolve(value, _context, resolve) {
|
|
309
|
+
return resolve(value)
|
|
310
|
+
},
|
|
311
|
+
},
|
|
312
|
+
},
|
|
313
|
+
output: g.field({
|
|
314
|
+
args: foreignListTypes.findManyArgs,
|
|
315
|
+
type: g.list(g.nonNull(foreignListTypes.output)),
|
|
316
|
+
resolve({ value }, args) {
|
|
317
|
+
return value.findMany(args)
|
|
318
|
+
},
|
|
319
|
+
}),
|
|
320
|
+
extraOutputFields: {
|
|
321
|
+
[`${fieldKey}Count`]: g.field({
|
|
322
|
+
type: g.Int,
|
|
323
|
+
args: {
|
|
324
|
+
where: g.arg({
|
|
325
|
+
type: g.nonNull(foreignListTypes.where),
|
|
326
|
+
defaultValue: {},
|
|
327
|
+
}),
|
|
328
|
+
},
|
|
329
|
+
resolve({ value }, args) {
|
|
330
|
+
return value.count({
|
|
331
|
+
where: args.where,
|
|
332
|
+
})
|
|
333
|
+
},
|
|
334
|
+
}),
|
|
335
|
+
},
|
|
336
|
+
})
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
return fieldType({
|
|
340
|
+
kind: 'relation',
|
|
341
|
+
mode: 'one',
|
|
342
|
+
list: foreignListKey,
|
|
343
|
+
field: foreignFieldKey,
|
|
344
|
+
foreignKey: config.db?.foreignKey,
|
|
345
|
+
extendPrismaSchema: config.db?.extendPrismaSchema,
|
|
346
|
+
})({
|
|
347
|
+
...commonConfig,
|
|
348
|
+
input: {
|
|
349
|
+
where: {
|
|
350
|
+
arg: g.arg({ type: foreignListTypes.where }),
|
|
351
|
+
resolve(value, _context, resolve) {
|
|
352
|
+
return resolve(value)
|
|
353
|
+
},
|
|
354
|
+
},
|
|
355
|
+
uniqueWhere: {
|
|
356
|
+
arg: g.arg({ type: foreignListTypes.uniqueWhere }),
|
|
357
|
+
},
|
|
358
|
+
|
|
359
|
+
create: foreignListTypes.relateTo.one.create && {
|
|
360
|
+
arg: g.arg({ type: foreignListTypes.relateTo.one.create }),
|
|
361
|
+
async resolve(value, _context, resolve) {
|
|
362
|
+
return resolve(value)
|
|
363
|
+
},
|
|
364
|
+
},
|
|
365
|
+
|
|
366
|
+
update: foreignListTypes.relateTo.one.update && {
|
|
367
|
+
arg: g.arg({ type: foreignListTypes.relateTo.one.update }),
|
|
368
|
+
async resolve(value, _context, resolve) {
|
|
369
|
+
return resolve(value)
|
|
370
|
+
},
|
|
371
|
+
},
|
|
372
|
+
},
|
|
373
|
+
output: g.field({
|
|
374
|
+
type: foreignListTypes.output,
|
|
375
|
+
resolve({ value }) {
|
|
376
|
+
return value()
|
|
377
|
+
},
|
|
378
|
+
}),
|
|
379
|
+
})
|
|
380
|
+
}
|
|
381
|
+
}
|