@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,214 +1,214 @@
1
- import type { GArg, GInputObjectType, InferValueFromArg } from '../graphql-ts'
2
- import type { ScalarDBField } from '../types'
3
- import {
4
- type BaseListTypeInfo,
5
- type DatabaseProvider,
6
- type FieldTypeFunc,
7
- type IdFieldConfig,
8
- fieldType,
9
- orderDirectionEnum,
10
- } from '../types'
11
- import { g } from '../types/schema'
12
- import { userInputError } from './core/graphql-errors'
13
-
14
- type IDType = string | number | null
15
-
16
- function isInt(x: IDType) {
17
- if (x === null) return
18
- if (x === '') return
19
- const nom = typeof x === 'string' ? Number(x) : x
20
- if (Number.isInteger(nom)) return nom
21
- }
22
-
23
- function isBigInt(x: IDType) {
24
- if (x === null) return
25
- if (x === '') return
26
- try {
27
- return BigInt(x)
28
- } catch {}
29
- }
30
-
31
- function isString(x: IDType) {
32
- if (typeof x !== 'string') return
33
- if (x === '') return
34
- return x
35
- }
36
-
37
- // TODO: this should be on the user, remove in breaking change?
38
- function isUuid(x: IDType) {
39
- if (typeof x !== 'string') return
40
- if (x === '') return
41
- return x.toLowerCase()
42
- }
43
-
44
- const nonCircularFields = {
45
- equals: g.arg({ type: g.ID }),
46
- in: g.arg({ type: g.list(g.nonNull(g.ID)) }),
47
- notIn: g.arg({ type: g.list(g.nonNull(g.ID)) }),
48
- lt: g.arg({ type: g.ID }),
49
- lte: g.arg({ type: g.ID }),
50
- gt: g.arg({ type: g.ID }),
51
- gte: g.arg({ type: g.ID }),
52
- }
53
-
54
- type IDFilterType = GInputObjectType<
55
- typeof nonCircularFields & {
56
- not: GArg<typeof IDFilter>
57
- }
58
- >
59
-
60
- const IDFilter: IDFilterType = g.inputObject({
61
- name: 'IDFilter',
62
- fields: () => ({
63
- ...nonCircularFields,
64
- not: g.arg({ type: IDFilter }),
65
- }),
66
- })
67
-
68
- const filterArg = g.arg({ type: IDFilter })
69
-
70
- function resolveInput(
71
- input: Exclude<InferValueFromArg<typeof filterArg>, undefined>,
72
- parseId: (x: IDType) => unknown
73
- ) {
74
- const where: any = {}
75
- if (input === null) return where
76
-
77
- for (const key of ['equals', 'gt', 'gte', 'lt', 'lte'] as const) {
78
- const value = input[key]
79
- if (value === undefined) continue
80
- where[key] = parseId(value)
81
- }
82
-
83
- for (const key of ['in', 'notIn'] as const) {
84
- const value = input[key]
85
- if (!Array.isArray(value)) continue
86
-
87
- where[key] = value.map(x => parseId(x))
88
- }
89
-
90
- if (input.not !== undefined) {
91
- where.not = resolveInput(input.not, parseId)
92
- }
93
-
94
- return where
95
- }
96
-
97
- const NATIVE_TYPES: {
98
- [k in DatabaseProvider]?: {
99
- [ku in IdFieldConfig['kind']]?: string
100
- }
101
- } = {
102
- postgresql: {
103
- uuid: 'Uuid' as const,
104
- },
105
- }
106
-
107
- function unpack(
108
- i: IdFieldConfig
109
- ): Pick<ScalarDBField<'String' | 'Int' | 'BigInt', 'required'>, 'scalar' | 'default'> {
110
- if (i.kind === 'random') {
111
- const { kind, bytes, encoding } = i
112
- if (typeof bytes === 'number') {
113
- if (bytes !== bytes >>> 0) {
114
- throw new TypeError(`Expected positive integer for random bytes, not ${bytes}`)
115
- }
116
- }
117
-
118
- return {
119
- scalar: 'String',
120
- // our defaults are 32 bytes, as base64url
121
- // 256 / Math.log2(64) ~ 43 characters
122
- //
123
- // for case-insensitive databases that is
124
- // 225 bits ~ Math.log2((26 + 10 + 2) ** 43)
125
- default: {
126
- kind,
127
- bytes: bytes ?? 32,
128
- encoding: encoding ?? 'base64url',
129
- },
130
- }
131
- }
132
- const { kind, type } = i
133
- if (kind === 'cuid') return { scalar: 'String', default: { kind, version: i.version } }
134
- if (kind === 'uuid') return { scalar: 'String', default: { kind, version: i.version } }
135
- if (kind === 'nanoid') return { scalar: 'String', default: { kind, length: i.length } }
136
- if (kind === 'ulid') return { scalar: 'String', default: { kind } }
137
- if (kind === 'string') return { scalar: 'String', default: undefined }
138
- if (kind === 'number') return { scalar: type ?? 'Int', default: undefined }
139
- if (kind === 'autoincrement') return { scalar: type ?? 'Int', default: { kind } }
140
- throw new Error(`Unknown id type ${kind}`)
141
- }
142
-
143
- export function idFieldType(config: IdFieldConfig): FieldTypeFunc<BaseListTypeInfo> {
144
- const kind = config.kind
145
- const dbFieldOptions = unpack(config)
146
- const parseTypeFn = {
147
- Int: isInt,
148
- BigInt: isBigInt,
149
- String: isString,
150
- UUID: isUuid, // TODO: remove in breaking change
151
- }[kind === 'uuid' ? 'UUID' : dbFieldOptions.scalar]
152
-
153
- function parse(value: IDType) {
154
- const result = parseTypeFn(value)
155
- if (result === undefined) {
156
- throw userInputError(
157
- `Only a ${dbFieldOptions.scalar.toLowerCase()} can be passed to id filters`
158
- )
159
- }
160
- return result
161
- }
162
-
163
- return meta => {
164
- if (
165
- meta.provider === 'sqlite' &&
166
- kind === 'autoincrement' &&
167
- dbFieldOptions.scalar === 'BigInt'
168
- ) {
169
- throw new Error(
170
- `{ kind: ${kind}, type: ${dbFieldOptions.scalar} } is not supported by SQLite`
171
- )
172
- }
173
-
174
- return fieldType({
175
- ...dbFieldOptions,
176
- kind: 'scalar',
177
- mode: 'required',
178
- nativeType: NATIVE_TYPES[meta.provider]?.[kind],
179
- })({
180
- ...config,
181
-
182
- // the ID field is always filterable and orderable
183
- isFilterable: true, // TODO: should it be?
184
- isOrderable: true, // TODO: should it be?
185
-
186
- input: {
187
- where: {
188
- arg: filterArg,
189
- resolve(val) {
190
- return resolveInput(val, parse)
191
- },
192
- },
193
- uniqueWhere: { arg: g.arg({ type: g.ID }), resolve: parse },
194
- orderBy: { arg: g.arg({ type: orderDirectionEnum }) },
195
- },
196
- output: g.field({
197
- type: g.nonNull(g.ID),
198
- resolve({ value }) {
199
- return value.toString()
200
- },
201
- }),
202
- views: '@nixxie-cms/core/___internal-do-not-use-will-break-in-patch/admin-ui/id-field-view',
203
- getAdminMeta: () => ({ kind, type: dbFieldOptions.scalar }),
204
- ui: {
205
- createView: {
206
- fieldMode: 'hidden',
207
- },
208
- itemView: {
209
- fieldPosition: 'sidebar',
210
- },
211
- },
212
- })
213
- }
214
- }
1
+ import type { GArg, GInputObjectType, InferValueFromArg } from '../graphql-ts'
2
+ import type { ScalarDBField } from '../types'
3
+ import {
4
+ type BaseListTypeInfo,
5
+ type DatabaseProvider,
6
+ type FieldTypeFunc,
7
+ type IdFieldConfig,
8
+ fieldType,
9
+ orderDirectionEnum,
10
+ } from '../types'
11
+ import { g } from '../types/schema'
12
+ import { userInputError } from './core/graphql-errors'
13
+
14
+ type IDType = string | number | null
15
+
16
+ function isInt(x: IDType) {
17
+ if (x === null) return
18
+ if (x === '') return
19
+ const nom = typeof x === 'string' ? Number(x) : x
20
+ if (Number.isInteger(nom)) return nom
21
+ }
22
+
23
+ function isBigInt(x: IDType) {
24
+ if (x === null) return
25
+ if (x === '') return
26
+ try {
27
+ return BigInt(x)
28
+ } catch {}
29
+ }
30
+
31
+ function isString(x: IDType) {
32
+ if (typeof x !== 'string') return
33
+ if (x === '') return
34
+ return x
35
+ }
36
+
37
+ // TODO: this should be on the user, remove in breaking change?
38
+ function isUuid(x: IDType) {
39
+ if (typeof x !== 'string') return
40
+ if (x === '') return
41
+ return x.toLowerCase()
42
+ }
43
+
44
+ const nonCircularFields = {
45
+ equals: g.arg({ type: g.ID }),
46
+ in: g.arg({ type: g.list(g.nonNull(g.ID)) }),
47
+ notIn: g.arg({ type: g.list(g.nonNull(g.ID)) }),
48
+ lt: g.arg({ type: g.ID }),
49
+ lte: g.arg({ type: g.ID }),
50
+ gt: g.arg({ type: g.ID }),
51
+ gte: g.arg({ type: g.ID }),
52
+ }
53
+
54
+ type IDFilterType = GInputObjectType<
55
+ typeof nonCircularFields & {
56
+ not: GArg<typeof IDFilter>
57
+ }
58
+ >
59
+
60
+ const IDFilter: IDFilterType = g.inputObject({
61
+ name: 'IDFilter',
62
+ fields: () => ({
63
+ ...nonCircularFields,
64
+ not: g.arg({ type: IDFilter }),
65
+ }),
66
+ })
67
+
68
+ const filterArg = g.arg({ type: IDFilter })
69
+
70
+ function resolveInput(
71
+ input: Exclude<InferValueFromArg<typeof filterArg>, undefined>,
72
+ parseId: (x: IDType) => unknown
73
+ ) {
74
+ const where: any = {}
75
+ if (input === null) return where
76
+
77
+ for (const key of ['equals', 'gt', 'gte', 'lt', 'lte'] as const) {
78
+ const value = input[key]
79
+ if (value === undefined) continue
80
+ where[key] = parseId(value)
81
+ }
82
+
83
+ for (const key of ['in', 'notIn'] as const) {
84
+ const value = input[key]
85
+ if (!Array.isArray(value)) continue
86
+
87
+ where[key] = value.map(x => parseId(x))
88
+ }
89
+
90
+ if (input.not !== undefined) {
91
+ where.not = resolveInput(input.not, parseId)
92
+ }
93
+
94
+ return where
95
+ }
96
+
97
+ const NATIVE_TYPES: {
98
+ [k in DatabaseProvider]?: {
99
+ [ku in IdFieldConfig['kind']]?: string
100
+ }
101
+ } = {
102
+ postgresql: {
103
+ uuid: 'Uuid' as const,
104
+ },
105
+ }
106
+
107
+ function unpack(
108
+ i: IdFieldConfig
109
+ ): Pick<ScalarDBField<'String' | 'Int' | 'BigInt', 'required'>, 'scalar' | 'default'> {
110
+ if (i.kind === 'random') {
111
+ const { kind, bytes, encoding } = i
112
+ if (typeof bytes === 'number') {
113
+ if (bytes !== bytes >>> 0) {
114
+ throw new TypeError(`Expected positive integer for random bytes, not ${bytes}`)
115
+ }
116
+ }
117
+
118
+ return {
119
+ scalar: 'String',
120
+ // our defaults are 32 bytes, as base64url
121
+ // 256 / Math.log2(64) ~ 43 characters
122
+ //
123
+ // for case-insensitive databases that is
124
+ // 225 bits ~ Math.log2((26 + 10 + 2) ** 43)
125
+ default: {
126
+ kind,
127
+ bytes: bytes ?? 32,
128
+ encoding: encoding ?? 'base64url',
129
+ },
130
+ }
131
+ }
132
+ const { kind, type } = i
133
+ if (kind === 'cuid') return { scalar: 'String', default: { kind, version: i.version } }
134
+ if (kind === 'uuid') return { scalar: 'String', default: { kind, version: i.version } }
135
+ if (kind === 'nanoid') return { scalar: 'String', default: { kind, length: i.length } }
136
+ if (kind === 'ulid') return { scalar: 'String', default: { kind } }
137
+ if (kind === 'string') return { scalar: 'String', default: undefined }
138
+ if (kind === 'number') return { scalar: type ?? 'Int', default: undefined }
139
+ if (kind === 'autoincrement') return { scalar: type ?? 'Int', default: { kind } }
140
+ throw new Error(`Unknown id type ${kind}`)
141
+ }
142
+
143
+ export function idFieldType(config: IdFieldConfig): FieldTypeFunc<BaseListTypeInfo> {
144
+ const kind = config.kind
145
+ const dbFieldOptions = unpack(config)
146
+ const parseTypeFn = {
147
+ Int: isInt,
148
+ BigInt: isBigInt,
149
+ String: isString,
150
+ UUID: isUuid, // TODO: remove in breaking change
151
+ }[kind === 'uuid' ? 'UUID' : dbFieldOptions.scalar]
152
+
153
+ function parse(value: IDType) {
154
+ const result = parseTypeFn(value)
155
+ if (result === undefined) {
156
+ throw userInputError(
157
+ `Only a ${dbFieldOptions.scalar.toLowerCase()} can be passed to id filters`
158
+ )
159
+ }
160
+ return result
161
+ }
162
+
163
+ return meta => {
164
+ if (
165
+ meta.provider === 'sqlite' &&
166
+ kind === 'autoincrement' &&
167
+ dbFieldOptions.scalar === 'BigInt'
168
+ ) {
169
+ throw new Error(
170
+ `{ kind: ${kind}, type: ${dbFieldOptions.scalar} } is not supported by SQLite`
171
+ )
172
+ }
173
+
174
+ return fieldType({
175
+ ...dbFieldOptions,
176
+ kind: 'scalar',
177
+ mode: 'required',
178
+ nativeType: NATIVE_TYPES[meta.provider]?.[kind],
179
+ })({
180
+ ...config,
181
+
182
+ // the ID field is always filterable and orderable
183
+ isFilterable: true, // TODO: should it be?
184
+ isOrderable: true, // TODO: should it be?
185
+
186
+ input: {
187
+ where: {
188
+ arg: filterArg,
189
+ resolve(val) {
190
+ return resolveInput(val, parse)
191
+ },
192
+ },
193
+ uniqueWhere: { arg: g.arg({ type: g.ID }), resolve: parse },
194
+ orderBy: { arg: g.arg({ type: orderDirectionEnum }) },
195
+ },
196
+ output: g.field({
197
+ type: g.nonNull(g.ID),
198
+ resolve({ value }) {
199
+ return value.toString()
200
+ },
201
+ }),
202
+ views: '@nixxie-cms/core/internal-unstable/admin-ui/id-field-view',
203
+ getAdminMeta: () => ({ kind, type: dbFieldOptions.scalar }),
204
+ ui: {
205
+ createView: {
206
+ fieldMode: 'hidden',
207
+ },
208
+ itemView: {
209
+ fieldPosition: 'sidebar',
210
+ },
211
+ },
212
+ })
213
+ }
214
+ }