@nixxie-cms/core 1.0.0 → 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (187) hide show
  1. package/README.md +2 -2
  2. package/admin-ui/components/dist/nixxie-cms-core-admin-ui-components.cjs.js +4 -4
  3. package/admin-ui/components/dist/nixxie-cms-core-admin-ui-components.esm.js +4 -4
  4. package/admin-ui/context/dist/nixxie-cms-core-admin-ui-context.cjs.js +2 -2
  5. package/admin-ui/context/dist/nixxie-cms-core-admin-ui-context.esm.js +2 -2
  6. package/context/dist/nixxie-cms-core-context.cjs.js +2 -2
  7. package/context/dist/nixxie-cms-core-context.esm.js +2 -2
  8. package/dist/{CreateItemDialog-33335548.esm.js → CreateItemDialog-7008b050.esm.js} +1 -1
  9. package/dist/{CreateItemDialog-56cf59b7.cjs.js → CreateItemDialog-a0cab315.cjs.js} +1 -1
  10. package/dist/{PageContainer-7db73317.esm.js → PageContainer-5ae731cc.esm.js} +25 -18
  11. package/dist/{PageContainer-27c27f10.cjs.js → PageContainer-abd7159f.cjs.js} +25 -18
  12. package/dist/{admin-meta-graphql-6f7f5331.esm.js → admin-meta-graphql-0e6e606e.esm.js} +1 -1
  13. package/dist/{admin-meta-graphql-c8f926e9.cjs.js → admin-meta-graphql-306c224a.cjs.js} +1 -1
  14. package/dist/{context-3132c3ed.esm.js → context-af9957ed.esm.js} +2 -2
  15. package/dist/{context-e7a45152.cjs.js → context-b5204629.cjs.js} +2 -2
  16. package/dist/declarations/src/admin-ui/components/Navigation.d.ts.map +1 -1
  17. package/dist/declarations/src/admin-ui/components/PageContainer.d.ts.map +1 -1
  18. package/dist/declarations/src/helpers.d.ts.map +1 -1
  19. package/dist/declarations/src/index.d.ts +1 -0
  20. package/dist/declarations/src/index.d.ts.map +1 -1
  21. package/dist/declarations/src/internal-unstable/admin-ui/id-field-view.d.ts.map +1 -0
  22. package/dist/declarations/src/internal-unstable/admin-ui/pages/App/index.d.ts.map +1 -0
  23. package/dist/declarations/src/internal-unstable/admin-ui/pages/CreateItemPage/index.d.ts.map +1 -0
  24. package/dist/declarations/src/internal-unstable/admin-ui/pages/HomePage/index.d.ts.map +1 -0
  25. package/dist/declarations/src/internal-unstable/admin-ui/pages/ItemPage/index.d.ts.map +1 -0
  26. package/dist/declarations/src/internal-unstable/admin-ui/pages/ListPage/index.d.ts.map +1 -0
  27. package/dist/declarations/src/internal-unstable/admin-ui/pages/NoAccessPage/index.d.ts.map +1 -0
  28. package/dist/declarations/src/internal-unstable/artifacts.d.ts.map +1 -0
  29. package/dist/declarations/src/lib/core/initialise-lists.d.ts +1 -1
  30. package/dist/declarations/src/schema.d.ts.map +1 -1
  31. package/dist/declarations/src/types/config/index.d.ts +60 -1
  32. package/dist/declarations/src/types/config/index.d.ts.map +1 -1
  33. package/dist/declarations/src/types/config/lists.d.ts +4 -4
  34. package/dist/declarations/src/types/context.d.ts +150 -0
  35. package/dist/declarations/src/types/context.d.ts.map +1 -1
  36. package/dist/declarations/src/types/next-fields.d.ts +1 -1
  37. package/dist/{express-e9ed9a7d.cjs.js → express-455ae20c.cjs.js} +1 -1
  38. package/dist/{express-6743b918.esm.js → express-7559ca2d.esm.js} +1 -1
  39. package/dist/{index-ac01583b.cjs.js → index-89635494.cjs.js} +4 -4
  40. package/dist/{index-24b78415.esm.js → index-baa799e0.esm.js} +4 -4
  41. package/dist/nixxie-cms-core.cjs.js +104 -77
  42. package/dist/nixxie-cms-core.esm.js +104 -77
  43. package/dist/{non-null-graphql-5315718c.esm.js → non-null-graphql-a84ed64d.esm.js} +1 -1
  44. package/dist/{non-null-graphql-17b83ddc.cjs.js → non-null-graphql-add6bb3d.cjs.js} +1 -1
  45. package/dist/{resolve-hooks-66fe8a8e.cjs.js → resolve-hooks-165a9ce2.cjs.js} +1 -1
  46. package/dist/{resolve-hooks-17aafd37.esm.js → resolve-hooks-6813a045.esm.js} +2 -2
  47. package/dist/{system-dfec2f0a.esm.js → system-03e49e4f.esm.js} +8 -4
  48. package/dist/{system-48c5f6df.cjs.js → system-a321642d.cjs.js} +8 -4
  49. package/dist/{useFilter-0b5a1ee6.esm.js → useFilter-9b6db1f9.esm.js} +1 -1
  50. package/dist/{useFilter-1a4e6900.cjs.js → useFilter-acc9d413.cjs.js} +1 -1
  51. package/fields/dist/nixxie-cms-core-fields.cjs.js +16 -16
  52. package/fields/dist/nixxie-cms-core-fields.esm.js +17 -17
  53. package/fields/types/bytes/dist/nixxie-cms-core-fields-types-bytes.cjs.js +3 -3
  54. package/fields/types/bytes/dist/nixxie-cms-core-fields-types-bytes.esm.js +3 -3
  55. package/fields/types/bytes/views/dist/nixxie-cms-core-fields-types-bytes-views.cjs.js +1 -1
  56. package/fields/types/bytes/views/dist/nixxie-cms-core-fields-types-bytes-views.esm.js +1 -1
  57. package/fields/types/password/dist/nixxie-cms-core-fields-types-password.cjs.js +3 -3
  58. package/fields/types/password/dist/nixxie-cms-core-fields-types-password.esm.js +3 -3
  59. package/fields/types/relationship/views/dist/nixxie-cms-core-fields-types-relationship-views.cjs.js +4 -4
  60. package/fields/types/relationship/views/dist/nixxie-cms-core-fields-types-relationship-views.esm.js +4 -4
  61. package/fields/types/select/views/dist/nixxie-cms-core-fields-types-select-views.cjs.js +1 -1
  62. package/fields/types/select/views/dist/nixxie-cms-core-fields-types-select-views.esm.js +1 -1
  63. package/fields/types/text/views/dist/nixxie-cms-core-fields-types-text-views.cjs.js +1 -1
  64. package/fields/types/text/views/dist/nixxie-cms-core-fields-types-text-views.esm.js +1 -1
  65. package/internal-unstable/admin-ui/id-field-view/dist/nixxie-cms-core-internal-unstable-admin-ui-id-field-view.cjs.d.ts +2 -0
  66. package/internal-unstable/admin-ui/id-field-view/dist/nixxie-cms-core-internal-unstable-admin-ui-id-field-view.cjs.js +244 -0
  67. package/internal-unstable/admin-ui/id-field-view/dist/nixxie-cms-core-internal-unstable-admin-ui-id-field-view.esm.js +235 -0
  68. package/internal-unstable/admin-ui/id-field-view/package.json +4 -0
  69. package/internal-unstable/admin-ui/next-config/package.json +4 -0
  70. package/internal-unstable/admin-ui/pages/App/dist/nixxie-cms-core-internal-unstable-admin-ui-pages-App.cjs.d.ts +2 -0
  71. package/internal-unstable/admin-ui/pages/App/dist/nixxie-cms-core-internal-unstable-admin-ui-pages-App.cjs.js +59 -0
  72. package/internal-unstable/admin-ui/pages/App/dist/nixxie-cms-core-internal-unstable-admin-ui-pages-App.esm.js +55 -0
  73. package/internal-unstable/admin-ui/pages/App/package.json +4 -0
  74. package/internal-unstable/admin-ui/pages/CreateItemPage/dist/nixxie-cms-core-internal-unstable-admin-ui-pages-CreateItemPage.cjs.d.ts +2 -0
  75. package/internal-unstable/admin-ui/pages/CreateItemPage/dist/nixxie-cms-core-internal-unstable-admin-ui-pages-CreateItemPage.cjs.js +116 -0
  76. package/internal-unstable/admin-ui/pages/CreateItemPage/dist/nixxie-cms-core-internal-unstable-admin-ui-pages-CreateItemPage.esm.js +112 -0
  77. package/internal-unstable/admin-ui/pages/CreateItemPage/package.json +4 -0
  78. package/internal-unstable/admin-ui/pages/HomePage/dist/nixxie-cms-core-internal-unstable-admin-ui-pages-HomePage.cjs.d.ts +2 -0
  79. package/internal-unstable/admin-ui/pages/HomePage/dist/nixxie-cms-core-internal-unstable-admin-ui-pages-HomePage.cjs.js +336 -0
  80. package/internal-unstable/admin-ui/pages/HomePage/dist/nixxie-cms-core-internal-unstable-admin-ui-pages-HomePage.esm.js +332 -0
  81. package/internal-unstable/admin-ui/pages/HomePage/package.json +4 -0
  82. package/internal-unstable/admin-ui/pages/ItemPage/dist/nixxie-cms-core-internal-unstable-admin-ui-pages-ItemPage.cjs.d.ts +2 -0
  83. package/internal-unstable/admin-ui/pages/ItemPage/dist/nixxie-cms-core-internal-unstable-admin-ui-pages-ItemPage.cjs.js +463 -0
  84. package/internal-unstable/admin-ui/pages/ItemPage/dist/nixxie-cms-core-internal-unstable-admin-ui-pages-ItemPage.esm.js +455 -0
  85. package/internal-unstable/admin-ui/pages/ItemPage/package.json +4 -0
  86. package/internal-unstable/admin-ui/pages/ListPage/dist/nixxie-cms-core-internal-unstable-admin-ui-pages-ListPage.cjs.d.ts +2 -0
  87. package/internal-unstable/admin-ui/pages/ListPage/dist/nixxie-cms-core-internal-unstable-admin-ui-pages-ListPage.cjs.js +1195 -0
  88. package/internal-unstable/admin-ui/pages/ListPage/dist/nixxie-cms-core-internal-unstable-admin-ui-pages-ListPage.esm.js +1187 -0
  89. package/internal-unstable/admin-ui/pages/ListPage/package.json +4 -0
  90. package/internal-unstable/admin-ui/pages/NoAccessPage/dist/nixxie-cms-core-internal-unstable-admin-ui-pages-NoAccessPage.cjs.d.ts +2 -0
  91. package/internal-unstable/admin-ui/pages/NoAccessPage/dist/nixxie-cms-core-internal-unstable-admin-ui-pages-NoAccessPage.cjs.js +40 -0
  92. package/internal-unstable/admin-ui/pages/NoAccessPage/dist/nixxie-cms-core-internal-unstable-admin-ui-pages-NoAccessPage.esm.js +35 -0
  93. package/internal-unstable/admin-ui/pages/NoAccessPage/package.json +4 -0
  94. package/internal-unstable/artifacts/dist/nixxie-cms-core-internal-unstable-artifacts.cjs.d.ts +2 -0
  95. package/internal-unstable/artifacts/dist/nixxie-cms-core-internal-unstable-artifacts.cjs.js +51 -0
  96. package/internal-unstable/artifacts/dist/nixxie-cms-core-internal-unstable-artifacts.esm.js +38 -0
  97. package/internal-unstable/artifacts/package.json +4 -0
  98. package/package.json +44 -44
  99. package/scripts/cli/dist/nixxie-cms-core-scripts-cli.cjs.js +44 -15
  100. package/scripts/cli/dist/nixxie-cms-core-scripts-cli.esm.js +44 -15
  101. package/scripts/dist/nixxie-cms-core-scripts.cjs.js +3 -3
  102. package/scripts/dist/nixxie-cms-core-scripts.esm.js +3 -3
  103. package/src/admin-ui/admin-meta-graphql.ts +168 -168
  104. package/src/admin-ui/components/CommandPalette.tsx +433 -431
  105. package/src/admin-ui/components/Navigation.tsx +389 -385
  106. package/src/admin-ui/components/PageContainer.tsx +311 -310
  107. package/src/admin-ui/components/WelcomeDialog.tsx +1 -1
  108. package/src/admin-ui/context.tsx +338 -338
  109. package/src/admin-ui/templates/app.ts +60 -60
  110. package/src/admin-ui/templates/create-item.ts +5 -5
  111. package/src/admin-ui/templates/home.ts +2 -2
  112. package/src/admin-ui/templates/item.tsx +5 -5
  113. package/src/admin-ui/templates/list.tsx +5 -5
  114. package/src/admin-ui/templates/next-config.ts +29 -0
  115. package/src/admin-ui/templates/no-access.ts +7 -7
  116. package/src/fields/types/bigInt/index.ts +181 -181
  117. package/src/fields/types/bytes/index.ts +275 -275
  118. package/src/fields/types/calendarDay/index.ts +194 -194
  119. package/src/fields/types/checkbox/index.ts +76 -76
  120. package/src/fields/types/decimal/index.ts +182 -182
  121. package/src/fields/types/file/index.ts +168 -168
  122. package/src/fields/types/float/index.ts +133 -133
  123. package/src/fields/types/image/index.ts +244 -244
  124. package/src/fields/types/integer/index.ts +156 -156
  125. package/src/fields/types/json/index.ts +77 -77
  126. package/src/fields/types/multiselect/index.ts +212 -212
  127. package/src/fields/types/password/index.ts +241 -241
  128. package/src/fields/types/relationship/index.ts +381 -381
  129. package/src/fields/types/relationship/views/RelationshipTable.tsx +190 -190
  130. package/src/fields/types/select/index.ts +226 -226
  131. package/src/fields/types/text/index.ts +207 -207
  132. package/src/fields/types/timestamp/index.ts +116 -116
  133. package/src/fields/types/virtual/index.ts +108 -108
  134. package/src/helpers.ts +342 -316
  135. package/src/index.ts +4 -0
  136. package/src/{___internal-do-not-use-will-break-in-patch → internal-unstable}/admin-ui/id-field-view.tsx +167 -167
  137. package/src/{___internal-do-not-use-will-break-in-patch → internal-unstable}/admin-ui/pages/App/index.tsx +22 -22
  138. package/src/{___internal-do-not-use-will-break-in-patch → internal-unstable}/admin-ui/pages/CreateItemPage/index.tsx +71 -71
  139. package/src/{___internal-do-not-use-will-break-in-patch → internal-unstable}/admin-ui/pages/HomePage/index.tsx +333 -333
  140. package/src/{___internal-do-not-use-will-break-in-patch → internal-unstable}/admin-ui/pages/ItemPage/common.tsx +358 -358
  141. package/src/{___internal-do-not-use-will-break-in-patch → internal-unstable}/admin-ui/pages/ItemPage/index.tsx +483 -483
  142. package/src/{___internal-do-not-use-will-break-in-patch → internal-unstable}/admin-ui/pages/ListPage/FilterAdd.tsx +221 -221
  143. package/src/{___internal-do-not-use-will-break-in-patch → internal-unstable}/admin-ui/pages/ListPage/PaginationControls.tsx +170 -170
  144. package/src/{___internal-do-not-use-will-break-in-patch → internal-unstable}/admin-ui/pages/ListPage/Tag.tsx +72 -72
  145. package/src/{___internal-do-not-use-will-break-in-patch → internal-unstable}/admin-ui/pages/ListPage/index.tsx +1006 -1006
  146. package/src/{___internal-do-not-use-will-break-in-patch → internal-unstable}/admin-ui/pages/NoAccessPage/index.tsx +24 -24
  147. package/src/{___internal-do-not-use-will-break-in-patch → internal-unstable}/artifacts.ts +5 -5
  148. package/src/lib/context/createContext.ts +165 -161
  149. package/src/lib/core/initialise-lists.ts +1097 -1097
  150. package/src/lib/id-field.ts +214 -214
  151. package/src/lib/telemetry.ts +342 -342
  152. package/src/schema.ts +237 -233
  153. package/src/scripts/telemetry.ts +1 -1
  154. package/src/types/config/index.ts +400 -333
  155. package/src/types/config/lists.ts +4 -4
  156. package/src/types/context.ts +700 -530
  157. package/src/types/next-fields.ts +499 -499
  158. package/src/types/telemetry.ts +51 -51
  159. package/tests/telemetry.test.ts +361 -361
  160. package/CHANGELOG.md +0 -3158
  161. package/___internal-do-not-use-will-break-in-patch/admin-ui/id-field-view/package.json +0 -4
  162. package/___internal-do-not-use-will-break-in-patch/admin-ui/next-config/package.json +0 -4
  163. package/___internal-do-not-use-will-break-in-patch/admin-ui/pages/App/package.json +0 -4
  164. package/___internal-do-not-use-will-break-in-patch/admin-ui/pages/CreateItemPage/package.json +0 -4
  165. package/___internal-do-not-use-will-break-in-patch/admin-ui/pages/HomePage/package.json +0 -4
  166. package/___internal-do-not-use-will-break-in-patch/admin-ui/pages/ItemPage/package.json +0 -4
  167. package/___internal-do-not-use-will-break-in-patch/admin-ui/pages/ListPage/package.json +0 -4
  168. package/___internal-do-not-use-will-break-in-patch/admin-ui/pages/NoAccessPage/package.json +0 -4
  169. package/___internal-do-not-use-will-break-in-patch/artifacts/package.json +0 -4
  170. package/dist/declarations/src/___internal-do-not-use-will-break-in-patch/admin-ui/id-field-view.d.ts.map +0 -1
  171. package/dist/declarations/src/___internal-do-not-use-will-break-in-patch/admin-ui/pages/App/index.d.ts.map +0 -1
  172. package/dist/declarations/src/___internal-do-not-use-will-break-in-patch/admin-ui/pages/CreateItemPage/index.d.ts.map +0 -1
  173. package/dist/declarations/src/___internal-do-not-use-will-break-in-patch/admin-ui/pages/HomePage/index.d.ts.map +0 -1
  174. package/dist/declarations/src/___internal-do-not-use-will-break-in-patch/admin-ui/pages/ItemPage/index.d.ts.map +0 -1
  175. package/dist/declarations/src/___internal-do-not-use-will-break-in-patch/admin-ui/pages/ListPage/index.d.ts.map +0 -1
  176. package/dist/declarations/src/___internal-do-not-use-will-break-in-patch/admin-ui/pages/NoAccessPage/index.d.ts.map +0 -1
  177. package/dist/declarations/src/___internal-do-not-use-will-break-in-patch/artifacts.d.ts.map +0 -1
  178. /package/dist/{common-1a350e11.cjs.js → common-5933f758.cjs.js} +0 -0
  179. /package/dist/{common-29fc82e6.esm.js → common-ea5c441a.esm.js} +0 -0
  180. /package/dist/declarations/src/{___internal-do-not-use-will-break-in-patch → internal-unstable}/admin-ui/id-field-view.d.ts +0 -0
  181. /package/dist/declarations/src/{___internal-do-not-use-will-break-in-patch → internal-unstable}/admin-ui/pages/App/index.d.ts +0 -0
  182. /package/dist/declarations/src/{___internal-do-not-use-will-break-in-patch → internal-unstable}/admin-ui/pages/CreateItemPage/index.d.ts +0 -0
  183. /package/dist/declarations/src/{___internal-do-not-use-will-break-in-patch → internal-unstable}/admin-ui/pages/HomePage/index.d.ts +0 -0
  184. /package/dist/declarations/src/{___internal-do-not-use-will-break-in-patch → internal-unstable}/admin-ui/pages/ItemPage/index.d.ts +0 -0
  185. /package/dist/declarations/src/{___internal-do-not-use-will-break-in-patch → internal-unstable}/admin-ui/pages/ListPage/index.d.ts +0 -0
  186. /package/dist/declarations/src/{___internal-do-not-use-will-break-in-patch → internal-unstable}/admin-ui/pages/NoAccessPage/index.d.ts +0 -0
  187. /package/dist/declarations/src/{___internal-do-not-use-will-break-in-patch → internal-unstable}/artifacts.d.ts +0 -0
@@ -1,226 +1,226 @@
1
- import { g } from '../../..'
2
- import { humanize } from '../../../lib/utils'
3
- import type { SimpleFieldTypeInfo } from '../../../types'
4
- import {
5
- type BaseListTypeInfo,
6
- type CommonFieldConfig,
7
- type FieldTypeFunc,
8
- fieldType,
9
- orderDirectionEnum,
10
- } from '../../../types'
11
- import { filters } from '../../filters'
12
- import { defaultIsRequired, makeValidateHook } from '../../non-null-graphql'
13
- import type { controller } from './views'
14
-
15
- export type SelectFieldConfig<ListTypeInfo extends BaseListTypeInfo> = CommonFieldConfig<
16
- ListTypeInfo,
17
- SimpleFieldTypeInfo<'String' | 'Int'>
18
- > &
19
- (
20
- | {
21
- /**
22
- * When a value is provided as just a string, it will be formatted in the same way
23
- * as field labels are to create the label.
24
- */
25
- options: readonly ({ label: string; value: string } | string)[]
26
- /**
27
- * If `enum` is provided on SQLite, it will use an enum in GraphQL but a string in the database.
28
- */
29
- type?: 'string' | 'enum'
30
- defaultValue?: string
31
- }
32
- | {
33
- options: readonly { label: string; value: number }[]
34
- type: 'integer'
35
- defaultValue?: number
36
- }
37
- ) & {
38
- ui?: {
39
- displayMode?: 'select' | 'segmented-control' | 'radio'
40
- }
41
-
42
- validation?: {
43
- /**
44
- * @default false
45
- */
46
- isRequired?: boolean
47
- }
48
- isIndexed?: boolean | 'unique'
49
- db?: {
50
- isNullable?: boolean
51
- map?: string
52
- extendPrismaSchema?: (field: string) => string
53
- }
54
- }
55
-
56
- // these are the lowest and highest values for a signed 32-bit integer
57
- const MAX_INT = 2147483647
58
- const MIN_INT = -2147483648
59
-
60
- export function select<ListTypeInfo extends BaseListTypeInfo>(
61
- config: SelectFieldConfig<ListTypeInfo>
62
- ): FieldTypeFunc<ListTypeInfo> {
63
- const { isIndexed, ui: { displayMode = 'select', ...ui } = {}, defaultValue, validation } = config
64
-
65
- return meta => {
66
- const options = config.options.map(option => {
67
- if (typeof option === 'string') {
68
- return {
69
- label: humanize(option),
70
- value: option,
71
- }
72
- }
73
- return option
74
- })
75
-
76
- const accepted = new Set(options.map(x => x.value))
77
- if (accepted.size !== options.length) {
78
- throw new Error(`${meta.listKey}.${meta.fieldKey}: duplicate options, this is not allowed`)
79
- }
80
-
81
- const { mode, validate } = makeValidateHook(
82
- meta,
83
- config,
84
- ({ resolvedData, operation, addValidationError }) => {
85
- if (operation === 'delete') return
86
-
87
- const value = resolvedData[meta.fieldKey]
88
- if (value != null && !accepted.has(value)) {
89
- addValidationError(`value is not an accepted option`)
90
- }
91
- }
92
- )
93
-
94
- const commonConfig = {
95
- ...config,
96
- mode,
97
- ...defaultIsRequired({ ui }, validation?.isRequired ?? false),
98
- hooks: {
99
- ...config.hooks,
100
- validate,
101
- },
102
- __ksTelemetryFieldTypeName: '@nixxie-cms/select',
103
- views: '@nixxie-cms/core/fields/types/select/views',
104
- getAdminMeta: (): Parameters<typeof controller>[0]['fieldMeta'] => ({
105
- options,
106
- type: config.type ?? 'string',
107
- displayMode: displayMode,
108
- defaultValue: defaultValue ?? null,
109
- }),
110
- }
111
-
112
- const commonDbFieldConfig = {
113
- mode,
114
- index: isIndexed === true ? 'index' : isIndexed || undefined,
115
- default:
116
- defaultValue === undefined
117
- ? undefined
118
- : { kind: 'literal' as const, value: defaultValue as any },
119
- map: config.db?.map,
120
- extendPrismaSchema: config.db?.extendPrismaSchema,
121
- } as const
122
-
123
- const resolveCreate = <T extends string | number>(val: T | null | undefined): T | null => {
124
- if (val === undefined) {
125
- return (defaultValue as T | undefined) ?? null
126
- }
127
- return val
128
- }
129
-
130
- if (config.type === 'integer') {
131
- if (
132
- config.options.some(
133
- ({ value }) => !Number.isInteger(value) || value > MAX_INT || value < MIN_INT
134
- )
135
- ) {
136
- throw new Error(
137
- `${meta.listKey}.${meta.fieldKey} specifies integer values that are outside the range of a 32-bit signed integer`
138
- )
139
- }
140
- return fieldType({
141
- kind: 'scalar',
142
- scalar: 'Int',
143
- ...commonDbFieldConfig,
144
- })({
145
- ...commonConfig,
146
- input: {
147
- uniqueWhere: isIndexed === 'unique' ? { arg: g.arg({ type: g.Int }) } : undefined,
148
- where: {
149
- arg: g.arg({ type: filters[meta.provider].Int[mode] }),
150
- resolve: mode === 'required' ? undefined : filters.resolveCommon,
151
- },
152
- create: {
153
- arg: g.arg({
154
- type: g.Int,
155
- defaultValue: typeof defaultValue === 'number' ? defaultValue : undefined,
156
- }),
157
- resolve: resolveCreate,
158
- },
159
- update: { arg: g.arg({ type: g.Int }) },
160
- orderBy: { arg: g.arg({ type: orderDirectionEnum }) },
161
- },
162
- output: g.field({ type: g.Int }),
163
- })
164
- }
165
-
166
- if (config.type === 'enum') {
167
- const enumName = `${meta.listKey}${humanize(meta.fieldKey).replace(/ /g, '')}Type`
168
- const enumValues = options.map(x => `${x.value}`)
169
-
170
- const graphQLType = g.enum({
171
- name: enumName,
172
- values: g.enumValues(enumValues),
173
- })
174
- return fieldType(
175
- meta.provider === 'sqlite'
176
- ? { kind: 'scalar', scalar: 'String', ...commonDbFieldConfig }
177
- : {
178
- kind: 'enum',
179
- values: enumValues,
180
- name: enumName,
181
- ...commonDbFieldConfig,
182
- }
183
- )({
184
- ...commonConfig,
185
- input: {
186
- uniqueWhere: isIndexed === 'unique' ? { arg: g.arg({ type: graphQLType }) } : undefined,
187
- where: {
188
- arg: g.arg({ type: filters[meta.provider].enum(graphQLType).optional }),
189
- resolve: mode === 'required' ? undefined : filters.resolveCommon,
190
- },
191
- create: {
192
- arg: g.arg({
193
- type: graphQLType,
194
- defaultValue: typeof defaultValue === 'string' ? defaultValue : undefined,
195
- }),
196
- resolve: resolveCreate,
197
- },
198
- update: { arg: g.arg({ type: graphQLType }) },
199
- orderBy: { arg: g.arg({ type: orderDirectionEnum }) },
200
- },
201
- output: g.field({ type: graphQLType }),
202
- })
203
- }
204
-
205
- return fieldType({ kind: 'scalar', scalar: 'String', ...commonDbFieldConfig })({
206
- ...commonConfig,
207
- input: {
208
- uniqueWhere: isIndexed === 'unique' ? { arg: g.arg({ type: g.String }) } : undefined,
209
- where: {
210
- arg: g.arg({ type: filters[meta.provider].String[mode] }),
211
- resolve: mode === 'required' ? undefined : filters.resolveString,
212
- },
213
- create: {
214
- arg: g.arg({
215
- type: g.String,
216
- defaultValue: typeof defaultValue === 'string' ? defaultValue : undefined,
217
- }),
218
- resolve: resolveCreate,
219
- },
220
- update: { arg: g.arg({ type: g.String }) },
221
- orderBy: { arg: g.arg({ type: orderDirectionEnum }) },
222
- },
223
- output: g.field({ type: g.String }),
224
- })
225
- }
226
- }
1
+ import { g } from '../../..'
2
+ import { humanize } from '../../../lib/utils'
3
+ import type { SimpleFieldTypeInfo } from '../../../types'
4
+ import {
5
+ type BaseListTypeInfo,
6
+ type CommonFieldConfig,
7
+ type FieldTypeFunc,
8
+ fieldType,
9
+ orderDirectionEnum,
10
+ } from '../../../types'
11
+ import { filters } from '../../filters'
12
+ import { defaultIsRequired, makeValidateHook } from '../../non-null-graphql'
13
+ import type { controller } from './views'
14
+
15
+ export type SelectFieldConfig<ListTypeInfo extends BaseListTypeInfo> = CommonFieldConfig<
16
+ ListTypeInfo,
17
+ SimpleFieldTypeInfo<'String' | 'Int'>
18
+ > &
19
+ (
20
+ | {
21
+ /**
22
+ * When a value is provided as just a string, it will be formatted in the same way
23
+ * as field labels are to create the label.
24
+ */
25
+ options: readonly ({ label: string; value: string } | string)[]
26
+ /**
27
+ * If `enum` is provided on SQLite, it will use an enum in GraphQL but a string in the database.
28
+ */
29
+ type?: 'string' | 'enum'
30
+ defaultValue?: string
31
+ }
32
+ | {
33
+ options: readonly { label: string; value: number }[]
34
+ type: 'integer'
35
+ defaultValue?: number
36
+ }
37
+ ) & {
38
+ ui?: {
39
+ displayMode?: 'select' | 'segmented-control' | 'radio'
40
+ }
41
+
42
+ validation?: {
43
+ /**
44
+ * @default false
45
+ */
46
+ isRequired?: boolean
47
+ }
48
+ isIndexed?: boolean | 'unique'
49
+ db?: {
50
+ isNullable?: boolean
51
+ map?: string
52
+ extendPrismaSchema?: (field: string) => string
53
+ }
54
+ }
55
+
56
+ // these are the lowest and highest values for a signed 32-bit integer
57
+ const MAX_INT = 2147483647
58
+ const MIN_INT = -2147483648
59
+
60
+ export function select<ListTypeInfo extends BaseListTypeInfo>(
61
+ config: SelectFieldConfig<ListTypeInfo>
62
+ ): FieldTypeFunc<ListTypeInfo> {
63
+ const { isIndexed, ui: { displayMode = 'select', ...ui } = {}, defaultValue, validation } = config
64
+
65
+ return meta => {
66
+ const options = config.options.map(option => {
67
+ if (typeof option === 'string') {
68
+ return {
69
+ label: humanize(option),
70
+ value: option,
71
+ }
72
+ }
73
+ return option
74
+ })
75
+
76
+ const accepted = new Set(options.map(x => x.value))
77
+ if (accepted.size !== options.length) {
78
+ throw new Error(`${meta.listKey}.${meta.fieldKey}: duplicate options, this is not allowed`)
79
+ }
80
+
81
+ const { mode, validate } = makeValidateHook(
82
+ meta,
83
+ config,
84
+ ({ resolvedData, operation, addValidationError }) => {
85
+ if (operation === 'delete') return
86
+
87
+ const value = resolvedData[meta.fieldKey]
88
+ if (value != null && !accepted.has(value)) {
89
+ addValidationError(`value is not an accepted option`)
90
+ }
91
+ }
92
+ )
93
+
94
+ const commonConfig = {
95
+ ...config,
96
+ mode,
97
+ ...defaultIsRequired({ ui }, validation?.isRequired ?? false),
98
+ hooks: {
99
+ ...config.hooks,
100
+ validate,
101
+ },
102
+ __nxTelemetryFieldTypeName: '@nixxie-cms/select',
103
+ views: '@nixxie-cms/core/fields/types/select/views',
104
+ getAdminMeta: (): Parameters<typeof controller>[0]['fieldMeta'] => ({
105
+ options,
106
+ type: config.type ?? 'string',
107
+ displayMode: displayMode,
108
+ defaultValue: defaultValue ?? null,
109
+ }),
110
+ }
111
+
112
+ const commonDbFieldConfig = {
113
+ mode,
114
+ index: isIndexed === true ? 'index' : isIndexed || undefined,
115
+ default:
116
+ defaultValue === undefined
117
+ ? undefined
118
+ : { kind: 'literal' as const, value: defaultValue as any },
119
+ map: config.db?.map,
120
+ extendPrismaSchema: config.db?.extendPrismaSchema,
121
+ } as const
122
+
123
+ const resolveCreate = <T extends string | number>(val: T | null | undefined): T | null => {
124
+ if (val === undefined) {
125
+ return (defaultValue as T | undefined) ?? null
126
+ }
127
+ return val
128
+ }
129
+
130
+ if (config.type === 'integer') {
131
+ if (
132
+ config.options.some(
133
+ ({ value }) => !Number.isInteger(value) || value > MAX_INT || value < MIN_INT
134
+ )
135
+ ) {
136
+ throw new Error(
137
+ `${meta.listKey}.${meta.fieldKey} specifies integer values that are outside the range of a 32-bit signed integer`
138
+ )
139
+ }
140
+ return fieldType({
141
+ kind: 'scalar',
142
+ scalar: 'Int',
143
+ ...commonDbFieldConfig,
144
+ })({
145
+ ...commonConfig,
146
+ input: {
147
+ uniqueWhere: isIndexed === 'unique' ? { arg: g.arg({ type: g.Int }) } : undefined,
148
+ where: {
149
+ arg: g.arg({ type: filters[meta.provider].Int[mode] }),
150
+ resolve: mode === 'required' ? undefined : filters.resolveCommon,
151
+ },
152
+ create: {
153
+ arg: g.arg({
154
+ type: g.Int,
155
+ defaultValue: typeof defaultValue === 'number' ? defaultValue : undefined,
156
+ }),
157
+ resolve: resolveCreate,
158
+ },
159
+ update: { arg: g.arg({ type: g.Int }) },
160
+ orderBy: { arg: g.arg({ type: orderDirectionEnum }) },
161
+ },
162
+ output: g.field({ type: g.Int }),
163
+ })
164
+ }
165
+
166
+ if (config.type === 'enum') {
167
+ const enumName = `${meta.listKey}${humanize(meta.fieldKey).replace(/ /g, '')}Type`
168
+ const enumValues = options.map(x => `${x.value}`)
169
+
170
+ const graphQLType = g.enum({
171
+ name: enumName,
172
+ values: g.enumValues(enumValues),
173
+ })
174
+ return fieldType(
175
+ meta.provider === 'sqlite'
176
+ ? { kind: 'scalar', scalar: 'String', ...commonDbFieldConfig }
177
+ : {
178
+ kind: 'enum',
179
+ values: enumValues,
180
+ name: enumName,
181
+ ...commonDbFieldConfig,
182
+ }
183
+ )({
184
+ ...commonConfig,
185
+ input: {
186
+ uniqueWhere: isIndexed === 'unique' ? { arg: g.arg({ type: graphQLType }) } : undefined,
187
+ where: {
188
+ arg: g.arg({ type: filters[meta.provider].enum(graphQLType).optional }),
189
+ resolve: mode === 'required' ? undefined : filters.resolveCommon,
190
+ },
191
+ create: {
192
+ arg: g.arg({
193
+ type: graphQLType,
194
+ defaultValue: typeof defaultValue === 'string' ? defaultValue : undefined,
195
+ }),
196
+ resolve: resolveCreate,
197
+ },
198
+ update: { arg: g.arg({ type: graphQLType }) },
199
+ orderBy: { arg: g.arg({ type: orderDirectionEnum }) },
200
+ },
201
+ output: g.field({ type: graphQLType }),
202
+ })
203
+ }
204
+
205
+ return fieldType({ kind: 'scalar', scalar: 'String', ...commonDbFieldConfig })({
206
+ ...commonConfig,
207
+ input: {
208
+ uniqueWhere: isIndexed === 'unique' ? { arg: g.arg({ type: g.String }) } : undefined,
209
+ where: {
210
+ arg: g.arg({ type: filters[meta.provider].String[mode] }),
211
+ resolve: mode === 'required' ? undefined : filters.resolveString,
212
+ },
213
+ create: {
214
+ arg: g.arg({
215
+ type: g.String,
216
+ defaultValue: typeof defaultValue === 'string' ? defaultValue : undefined,
217
+ }),
218
+ resolve: resolveCreate,
219
+ },
220
+ update: { arg: g.arg({ type: g.String }) },
221
+ orderBy: { arg: g.arg({ type: orderDirectionEnum }) },
222
+ },
223
+ output: g.field({ type: g.String }),
224
+ })
225
+ }
226
+ }