@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,182 +1,182 @@
1
- import type { SimpleFieldTypeInfo } from '../../../types'
2
- import {
3
- type BaseListTypeInfo,
4
- type CommonFieldConfig,
5
- type FieldTypeFunc,
6
- fieldType,
7
- orderDirectionEnum,
8
- Decimal,
9
- } from '../../../types'
10
- import { g } from '../../..'
11
- import { filters } from '../../filters'
12
- import { makeValidateHook, defaultIsRequired } from '../../non-null-graphql'
13
- import type { controller } from './views'
14
-
15
- export type DecimalFieldConfig<ListTypeInfo extends BaseListTypeInfo> = CommonFieldConfig<
16
- ListTypeInfo,
17
- SimpleFieldTypeInfo<'Decimal'>
18
- > & {
19
- isIndexed?: boolean | 'unique'
20
- defaultValue?: string | null
21
- validation?: {
22
- isRequired?: boolean
23
- min?: string
24
- max?: string
25
- }
26
- precision?: number
27
- scale?: number
28
- db?: {
29
- isNullable?: boolean
30
- map?: string
31
- extendPrismaSchema?: (field: string) => string
32
- }
33
- }
34
-
35
- function safeParseDecimal(value: string | null | undefined) {
36
- if (value === null || value === undefined) return value
37
- const result = new Decimal(value)
38
- if (!result.isFinite()) throw new Error(`"${value}" is not finite`)
39
- return result
40
- }
41
-
42
- // TODO: https://github.com/Nixxie/keystatic/blob/main/design-system/pkg/src/number-field/NumberField.tsx
43
- export function decimal<ListTypeInfo extends BaseListTypeInfo>(
44
- config: DecimalFieldConfig<ListTypeInfo> = {}
45
- ): FieldTypeFunc<ListTypeInfo> {
46
- const {
47
- defaultValue: defaultValue_,
48
- isIndexed,
49
- precision = 18,
50
- scale = 4,
51
- validation = {},
52
- } = config
53
-
54
- const { isRequired = false, min, max } = validation
55
- const defaultValue = typeof defaultValue_ === 'string' ? defaultValue_ : null
56
-
57
- const parsedDefaultValue = safeParseDecimal(defaultValue)
58
- const parsedMax = safeParseDecimal(max) ?? undefined
59
- const parsedMin = safeParseDecimal(min) ?? undefined
60
-
61
- return meta => {
62
- if (meta.provider === 'sqlite') {
63
- throw new Error('The decimal field does not support sqlite')
64
- }
65
- if (!Number.isInteger(scale)) {
66
- throw new TypeError(
67
- `The scale for decimal fields must be an integer but the scale for the decimal field at ${meta.listKey}.${meta.fieldKey} is not an integer`
68
- )
69
- }
70
- if (!Number.isInteger(precision)) {
71
- throw new TypeError(
72
- `The precision for decimal fields must be an integer but the precision for the decimal field at ${meta.listKey}.${meta.fieldKey} is not an integer`
73
- )
74
- }
75
- if (scale > precision) {
76
- throw new Error(
77
- `The scale configured for decimal field at ${meta.listKey}.${meta.fieldKey} (${scale}) ` +
78
- `must not be larger than the field's precision (${precision})`
79
- )
80
- }
81
- if (defaultValue !== null && !parsedDefaultValue) {
82
- throw new Error(
83
- `${meta.listKey}.${meta.fieldKey} specifies a default value of: ${defaultValue} but it must be a valid finite number`
84
- )
85
- }
86
- if (min !== undefined && !parsedMin) {
87
- throw new Error(
88
- `${meta.listKey}.${meta.fieldKey} specifies validation.min: ${min} but it must be a valid finite number`
89
- )
90
- }
91
- if (max !== undefined && !parsedMax) {
92
- throw new Error(
93
- `${meta.listKey}.${meta.fieldKey} specifies validation.max: ${max} but it must be a valid finite number`
94
- )
95
- }
96
- if (min !== undefined && max !== undefined && parsedMin && parsedMax && parsedMin > parsedMax) {
97
- throw new Error(
98
- `${meta.listKey}.${meta.fieldKey} specifies a validation.max that is less than the validation.min, and therefore has no valid options`
99
- )
100
- }
101
-
102
- const hasAdditionalValidation = min !== undefined || max !== undefined
103
- const { mode, validate } = makeValidateHook(
104
- meta,
105
- config,
106
- hasAdditionalValidation
107
- ? ({ resolvedData, operation, addValidationError }) => {
108
- if (operation === 'delete') return
109
-
110
- const value = safeParseDecimal(resolvedData[meta.fieldKey])
111
- if (value != null) {
112
- if (parsedMin !== undefined && value.lessThan(parsedMin)) {
113
- addValidationError(`value must be greater than or equal to ${min}`)
114
- }
115
-
116
- if (parsedMax !== undefined && value.greaterThan(parsedMax)) {
117
- addValidationError(`value must be less than or equal to ${max}`)
118
- }
119
- }
120
- }
121
- : undefined
122
- )
123
-
124
- return fieldType({
125
- kind: 'scalar',
126
- mode,
127
- scalar: 'Decimal',
128
- nativeType: `Decimal(${precision}, ${scale})`,
129
- index: isIndexed === true ? 'index' : isIndexed || undefined,
130
- default:
131
- typeof defaultValue === 'string' ? { kind: 'literal', value: defaultValue } : undefined,
132
- map: config.db?.map,
133
- extendPrismaSchema: config.db?.extendPrismaSchema,
134
- })({
135
- ...config,
136
- ...defaultIsRequired(config, isRequired),
137
- hooks: {
138
- ...config.hooks,
139
- validate,
140
- },
141
- input: {
142
- uniqueWhere: isIndexed === 'unique' ? { arg: g.arg({ type: g.Decimal }) } : undefined,
143
- where: {
144
- arg: g.arg({ type: filters[meta.provider].Decimal[mode] }),
145
- resolve: mode === 'optional' ? filters.resolveCommon : undefined,
146
- },
147
- create: {
148
- arg: g.arg({
149
- type: g.Decimal,
150
- defaultValue: parsedDefaultValue,
151
- }),
152
- resolve(val) {
153
- if (val === undefined) return parsedDefaultValue
154
- return val
155
- },
156
- },
157
- update: { arg: g.arg({ type: g.Decimal }) },
158
- orderBy: { arg: g.arg({ type: orderDirectionEnum }) },
159
- },
160
- output: g.field({
161
- type: g.Decimal,
162
- resolve({ value }) {
163
- if (value === null) return null
164
- const val: Decimal & { scaleToPrint?: number } = new Decimal(value)
165
- val.scaleToPrint = scale
166
- return val
167
- },
168
- }),
169
- __ksTelemetryFieldTypeName: '@nixxie-cms/decimal',
170
- views: '@nixxie-cms/core/fields/types/decimal/views',
171
- getAdminMeta(): Parameters<typeof controller>[0]['fieldMeta'] {
172
- return {
173
- validation: {
174
- max: max ?? null,
175
- min: min ?? null,
176
- },
177
- defaultValue,
178
- }
179
- },
180
- })
181
- }
182
- }
1
+ import type { SimpleFieldTypeInfo } from '../../../types'
2
+ import {
3
+ type BaseListTypeInfo,
4
+ type CommonFieldConfig,
5
+ type FieldTypeFunc,
6
+ fieldType,
7
+ orderDirectionEnum,
8
+ Decimal,
9
+ } from '../../../types'
10
+ import { g } from '../../..'
11
+ import { filters } from '../../filters'
12
+ import { makeValidateHook, defaultIsRequired } from '../../non-null-graphql'
13
+ import type { controller } from './views'
14
+
15
+ export type DecimalFieldConfig<ListTypeInfo extends BaseListTypeInfo> = CommonFieldConfig<
16
+ ListTypeInfo,
17
+ SimpleFieldTypeInfo<'Decimal'>
18
+ > & {
19
+ isIndexed?: boolean | 'unique'
20
+ defaultValue?: string | null
21
+ validation?: {
22
+ isRequired?: boolean
23
+ min?: string
24
+ max?: string
25
+ }
26
+ precision?: number
27
+ scale?: number
28
+ db?: {
29
+ isNullable?: boolean
30
+ map?: string
31
+ extendPrismaSchema?: (field: string) => string
32
+ }
33
+ }
34
+
35
+ function safeParseDecimal(value: string | null | undefined) {
36
+ if (value === null || value === undefined) return value
37
+ const result = new Decimal(value)
38
+ if (!result.isFinite()) throw new Error(`"${value}" is not finite`)
39
+ return result
40
+ }
41
+
42
+ // TODO: https://github.com/Nixxie/keystatic/blob/main/design-system/pkg/src/number-field/NumberField.tsx
43
+ export function decimal<ListTypeInfo extends BaseListTypeInfo>(
44
+ config: DecimalFieldConfig<ListTypeInfo> = {}
45
+ ): FieldTypeFunc<ListTypeInfo> {
46
+ const {
47
+ defaultValue: defaultValue_,
48
+ isIndexed,
49
+ precision = 18,
50
+ scale = 4,
51
+ validation = {},
52
+ } = config
53
+
54
+ const { isRequired = false, min, max } = validation
55
+ const defaultValue = typeof defaultValue_ === 'string' ? defaultValue_ : null
56
+
57
+ const parsedDefaultValue = safeParseDecimal(defaultValue)
58
+ const parsedMax = safeParseDecimal(max) ?? undefined
59
+ const parsedMin = safeParseDecimal(min) ?? undefined
60
+
61
+ return meta => {
62
+ if (meta.provider === 'sqlite') {
63
+ throw new Error('The decimal field does not support sqlite')
64
+ }
65
+ if (!Number.isInteger(scale)) {
66
+ throw new TypeError(
67
+ `The scale for decimal fields must be an integer but the scale for the decimal field at ${meta.listKey}.${meta.fieldKey} is not an integer`
68
+ )
69
+ }
70
+ if (!Number.isInteger(precision)) {
71
+ throw new TypeError(
72
+ `The precision for decimal fields must be an integer but the precision for the decimal field at ${meta.listKey}.${meta.fieldKey} is not an integer`
73
+ )
74
+ }
75
+ if (scale > precision) {
76
+ throw new Error(
77
+ `The scale configured for decimal field at ${meta.listKey}.${meta.fieldKey} (${scale}) ` +
78
+ `must not be larger than the field's precision (${precision})`
79
+ )
80
+ }
81
+ if (defaultValue !== null && !parsedDefaultValue) {
82
+ throw new Error(
83
+ `${meta.listKey}.${meta.fieldKey} specifies a default value of: ${defaultValue} but it must be a valid finite number`
84
+ )
85
+ }
86
+ if (min !== undefined && !parsedMin) {
87
+ throw new Error(
88
+ `${meta.listKey}.${meta.fieldKey} specifies validation.min: ${min} but it must be a valid finite number`
89
+ )
90
+ }
91
+ if (max !== undefined && !parsedMax) {
92
+ throw new Error(
93
+ `${meta.listKey}.${meta.fieldKey} specifies validation.max: ${max} but it must be a valid finite number`
94
+ )
95
+ }
96
+ if (min !== undefined && max !== undefined && parsedMin && parsedMax && parsedMin > parsedMax) {
97
+ throw new Error(
98
+ `${meta.listKey}.${meta.fieldKey} specifies a validation.max that is less than the validation.min, and therefore has no valid options`
99
+ )
100
+ }
101
+
102
+ const hasAdditionalValidation = min !== undefined || max !== undefined
103
+ const { mode, validate } = makeValidateHook(
104
+ meta,
105
+ config,
106
+ hasAdditionalValidation
107
+ ? ({ resolvedData, operation, addValidationError }) => {
108
+ if (operation === 'delete') return
109
+
110
+ const value = safeParseDecimal(resolvedData[meta.fieldKey])
111
+ if (value != null) {
112
+ if (parsedMin !== undefined && value.lessThan(parsedMin)) {
113
+ addValidationError(`value must be greater than or equal to ${min}`)
114
+ }
115
+
116
+ if (parsedMax !== undefined && value.greaterThan(parsedMax)) {
117
+ addValidationError(`value must be less than or equal to ${max}`)
118
+ }
119
+ }
120
+ }
121
+ : undefined
122
+ )
123
+
124
+ return fieldType({
125
+ kind: 'scalar',
126
+ mode,
127
+ scalar: 'Decimal',
128
+ nativeType: `Decimal(${precision}, ${scale})`,
129
+ index: isIndexed === true ? 'index' : isIndexed || undefined,
130
+ default:
131
+ typeof defaultValue === 'string' ? { kind: 'literal', value: defaultValue } : undefined,
132
+ map: config.db?.map,
133
+ extendPrismaSchema: config.db?.extendPrismaSchema,
134
+ })({
135
+ ...config,
136
+ ...defaultIsRequired(config, isRequired),
137
+ hooks: {
138
+ ...config.hooks,
139
+ validate,
140
+ },
141
+ input: {
142
+ uniqueWhere: isIndexed === 'unique' ? { arg: g.arg({ type: g.Decimal }) } : undefined,
143
+ where: {
144
+ arg: g.arg({ type: filters[meta.provider].Decimal[mode] }),
145
+ resolve: mode === 'optional' ? filters.resolveCommon : undefined,
146
+ },
147
+ create: {
148
+ arg: g.arg({
149
+ type: g.Decimal,
150
+ defaultValue: parsedDefaultValue,
151
+ }),
152
+ resolve(val) {
153
+ if (val === undefined) return parsedDefaultValue
154
+ return val
155
+ },
156
+ },
157
+ update: { arg: g.arg({ type: g.Decimal }) },
158
+ orderBy: { arg: g.arg({ type: orderDirectionEnum }) },
159
+ },
160
+ output: g.field({
161
+ type: g.Decimal,
162
+ resolve({ value }) {
163
+ if (value === null) return null
164
+ const val: Decimal & { scaleToPrint?: number } = new Decimal(value)
165
+ val.scaleToPrint = scale
166
+ return val
167
+ },
168
+ }),
169
+ __nxTelemetryFieldTypeName: '@nixxie-cms/decimal',
170
+ views: '@nixxie-cms/core/fields/types/decimal/views',
171
+ getAdminMeta(): Parameters<typeof controller>[0]['fieldMeta'] {
172
+ return {
173
+ validation: {
174
+ max: max ?? null,
175
+ min: min ?? null,
176
+ },
177
+ defaultValue,
178
+ }
179
+ },
180
+ })
181
+ }
182
+ }