@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.
Files changed (186) 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 +15 -15
  100. package/scripts/cli/dist/nixxie-cms-core-scripts-cli.esm.js +15 -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/no-access.ts +7 -7
  115. package/src/fields/types/bigInt/index.ts +181 -181
  116. package/src/fields/types/bytes/index.ts +275 -275
  117. package/src/fields/types/calendarDay/index.ts +194 -194
  118. package/src/fields/types/checkbox/index.ts +76 -76
  119. package/src/fields/types/decimal/index.ts +182 -182
  120. package/src/fields/types/file/index.ts +168 -168
  121. package/src/fields/types/float/index.ts +133 -133
  122. package/src/fields/types/image/index.ts +244 -244
  123. package/src/fields/types/integer/index.ts +156 -156
  124. package/src/fields/types/json/index.ts +77 -77
  125. package/src/fields/types/multiselect/index.ts +212 -212
  126. package/src/fields/types/password/index.ts +241 -241
  127. package/src/fields/types/relationship/index.ts +381 -381
  128. package/src/fields/types/relationship/views/RelationshipTable.tsx +190 -190
  129. package/src/fields/types/select/index.ts +226 -226
  130. package/src/fields/types/text/index.ts +207 -207
  131. package/src/fields/types/timestamp/index.ts +116 -116
  132. package/src/fields/types/virtual/index.ts +108 -108
  133. package/src/helpers.ts +342 -316
  134. package/src/index.ts +4 -0
  135. package/src/{___internal-do-not-use-will-break-in-patch → internal-unstable}/admin-ui/id-field-view.tsx +167 -167
  136. package/src/{___internal-do-not-use-will-break-in-patch → internal-unstable}/admin-ui/pages/App/index.tsx +22 -22
  137. package/src/{___internal-do-not-use-will-break-in-patch → internal-unstable}/admin-ui/pages/CreateItemPage/index.tsx +71 -71
  138. package/src/{___internal-do-not-use-will-break-in-patch → internal-unstable}/admin-ui/pages/HomePage/index.tsx +333 -333
  139. package/src/{___internal-do-not-use-will-break-in-patch → internal-unstable}/admin-ui/pages/ItemPage/common.tsx +358 -358
  140. package/src/{___internal-do-not-use-will-break-in-patch → internal-unstable}/admin-ui/pages/ItemPage/index.tsx +483 -483
  141. package/src/{___internal-do-not-use-will-break-in-patch → internal-unstable}/admin-ui/pages/ListPage/FilterAdd.tsx +221 -221
  142. package/src/{___internal-do-not-use-will-break-in-patch → internal-unstable}/admin-ui/pages/ListPage/PaginationControls.tsx +170 -170
  143. package/src/{___internal-do-not-use-will-break-in-patch → internal-unstable}/admin-ui/pages/ListPage/Tag.tsx +72 -72
  144. package/src/{___internal-do-not-use-will-break-in-patch → internal-unstable}/admin-ui/pages/ListPage/index.tsx +1006 -1006
  145. package/src/{___internal-do-not-use-will-break-in-patch → internal-unstable}/admin-ui/pages/NoAccessPage/index.tsx +24 -24
  146. package/src/{___internal-do-not-use-will-break-in-patch → internal-unstable}/artifacts.ts +5 -5
  147. package/src/lib/context/createContext.ts +165 -161
  148. package/src/lib/core/initialise-lists.ts +1097 -1097
  149. package/src/lib/id-field.ts +214 -214
  150. package/src/lib/telemetry.ts +342 -342
  151. package/src/schema.ts +237 -233
  152. package/src/scripts/telemetry.ts +1 -1
  153. package/src/types/config/index.ts +400 -333
  154. package/src/types/config/lists.ts +4 -4
  155. package/src/types/context.ts +700 -530
  156. package/src/types/next-fields.ts +499 -499
  157. package/src/types/telemetry.ts +51 -51
  158. package/tests/telemetry.test.ts +361 -361
  159. package/CHANGELOG.md +0 -3158
  160. package/___internal-do-not-use-will-break-in-patch/admin-ui/id-field-view/package.json +0 -4
  161. package/___internal-do-not-use-will-break-in-patch/admin-ui/next-config/package.json +0 -4
  162. package/___internal-do-not-use-will-break-in-patch/admin-ui/pages/App/package.json +0 -4
  163. package/___internal-do-not-use-will-break-in-patch/admin-ui/pages/CreateItemPage/package.json +0 -4
  164. package/___internal-do-not-use-will-break-in-patch/admin-ui/pages/HomePage/package.json +0 -4
  165. package/___internal-do-not-use-will-break-in-patch/admin-ui/pages/ItemPage/package.json +0 -4
  166. package/___internal-do-not-use-will-break-in-patch/admin-ui/pages/ListPage/package.json +0 -4
  167. package/___internal-do-not-use-will-break-in-patch/admin-ui/pages/NoAccessPage/package.json +0 -4
  168. package/___internal-do-not-use-will-break-in-patch/artifacts/package.json +0 -4
  169. package/dist/declarations/src/___internal-do-not-use-will-break-in-patch/admin-ui/id-field-view.d.ts.map +0 -1
  170. package/dist/declarations/src/___internal-do-not-use-will-break-in-patch/admin-ui/pages/App/index.d.ts.map +0 -1
  171. package/dist/declarations/src/___internal-do-not-use-will-break-in-patch/admin-ui/pages/CreateItemPage/index.d.ts.map +0 -1
  172. package/dist/declarations/src/___internal-do-not-use-will-break-in-patch/admin-ui/pages/HomePage/index.d.ts.map +0 -1
  173. package/dist/declarations/src/___internal-do-not-use-will-break-in-patch/admin-ui/pages/ItemPage/index.d.ts.map +0 -1
  174. package/dist/declarations/src/___internal-do-not-use-will-break-in-patch/admin-ui/pages/ListPage/index.d.ts.map +0 -1
  175. package/dist/declarations/src/___internal-do-not-use-will-break-in-patch/admin-ui/pages/NoAccessPage/index.d.ts.map +0 -1
  176. package/dist/declarations/src/___internal-do-not-use-will-break-in-patch/artifacts.d.ts.map +0 -1
  177. /package/dist/{common-1a350e11.cjs.js → common-5933f758.cjs.js} +0 -0
  178. /package/dist/{common-29fc82e6.esm.js → common-ea5c441a.esm.js} +0 -0
  179. /package/dist/declarations/src/{___internal-do-not-use-will-break-in-patch → internal-unstable}/admin-ui/id-field-view.d.ts +0 -0
  180. /package/dist/declarations/src/{___internal-do-not-use-will-break-in-patch → internal-unstable}/admin-ui/pages/App/index.d.ts +0 -0
  181. /package/dist/declarations/src/{___internal-do-not-use-will-break-in-patch → internal-unstable}/admin-ui/pages/CreateItemPage/index.d.ts +0 -0
  182. /package/dist/declarations/src/{___internal-do-not-use-will-break-in-patch → internal-unstable}/admin-ui/pages/HomePage/index.d.ts +0 -0
  183. /package/dist/declarations/src/{___internal-do-not-use-will-break-in-patch → internal-unstable}/admin-ui/pages/ItemPage/index.d.ts +0 -0
  184. /package/dist/declarations/src/{___internal-do-not-use-will-break-in-patch → internal-unstable}/admin-ui/pages/ListPage/index.d.ts +0 -0
  185. /package/dist/declarations/src/{___internal-do-not-use-will-break-in-patch → internal-unstable}/admin-ui/pages/NoAccessPage/index.d.ts +0 -0
  186. /package/dist/declarations/src/{___internal-do-not-use-will-break-in-patch → internal-unstable}/artifacts.d.ts +0 -0
package/src/schema.ts CHANGED
@@ -1,233 +1,237 @@
1
- import type { ListenOptions } from 'node:net'
2
-
3
- import { idFieldType } from './lib/id-field'
4
- import type {
5
- Action,
6
- ActionArgsConfig,
7
- BaseFields,
8
- BaseNixxieTypeInfo,
9
- BaseListTypeInfo,
10
- DeclaredAction,
11
- IdFieldConfig,
12
- NixxieConfig,
13
- NixxieConfigPre,
14
- NixxieContext,
15
- ListConfig,
16
- MaybeItemFunctionWithFilter,
17
- MaybeSessionFunction,
18
- MaybeSessionFunctionWithFilter,
19
- } from './types'
20
-
21
- function listsWithDefaults(config: NixxieConfigPre, defaultIdField: IdFieldConfig) {
22
- // some error checking
23
- for (const [listKey, list] of Object.entries(config.lists)) {
24
- if (list.fields.id) {
25
- throw new Error(
26
- `"fields.id" is reserved by Nixxie, use "db.idField" for the "${listKey}" list`
27
- )
28
- }
29
-
30
- if (list.isSingleton && list.db?.idField) {
31
- throw new Error(`"db.idField" on the "${listKey}" list conflicts with singleton defaults`)
32
- }
33
- }
34
-
35
- return Object.fromEntries([
36
- ...(function* () {
37
- for (const [listKey, list] of Object.entries(config.lists)) {
38
- yield [
39
- listKey,
40
- {
41
- listKey,
42
- defaultIsFilterable: true, // TODO: move to access control?
43
- defaultIsOrderable: true, // TODO: move to access control?
44
- isSingleton: false,
45
- ...list,
46
- db: {
47
- ...list.db,
48
- },
49
- fields: {
50
- ...(list.isSingleton
51
- ? {
52
- id: idFieldType({ kind: 'number', type: 'Int' }),
53
- ...list.fields,
54
- }
55
- : {
56
- id: idFieldType(list.db?.idField ?? defaultIdField),
57
- ...list.fields,
58
- }),
59
- },
60
- actions: {
61
- ...list.actions,
62
- },
63
- hooks: {
64
- ...list.hooks,
65
- },
66
- graphql: {
67
- ...list.graphql,
68
- },
69
- ui: {
70
- ...list.ui,
71
- },
72
- } satisfies NixxieConfig['lists'][string],
73
- ]
74
- }
75
- })(),
76
- ]) satisfies NixxieConfig['lists']
77
- }
78
-
79
- function defaultIsAccessAllowed({ session, sessionStrategy }: NixxieContext) {
80
- if (!sessionStrategy) return true
81
- return session !== undefined
82
- }
83
-
84
- async function noop() {}
85
- function identity<T>(x: T) {
86
- return x
87
- }
88
-
89
- export function config<TypeInfo extends BaseNixxieTypeInfo>(
90
- config: NixxieConfigPre<TypeInfo>
91
- ): NixxieConfig<TypeInfo> {
92
- if (!['postgresql', 'sqlite', 'mysql'].includes(config.db.provider)) {
93
- throw new TypeError(`"db.provider" only supports "sqlite", "postgresql" or "mysql"`)
94
- }
95
-
96
- // WARNING: Typescript should prevent this, but any string is useful for Prisma errors
97
- config.db.url ??= 'postgres://'
98
-
99
- const defaultIdField = config.db.idField ?? { kind: 'cuid' }
100
- const cors =
101
- config.server?.cors === true
102
- ? { origin: true, credentials: true }
103
- : config.server?.cors === false
104
- ? null
105
- : (config.server?.cors ?? null)
106
-
107
- const httpOptions: ListenOptions = { port: 3000 }
108
- if (config?.server && 'port' in config.server) {
109
- httpOptions.port = config.server.port
110
- }
111
-
112
- if (config?.server && 'options' in config.server && config.server.options) {
113
- Object.assign(httpOptions, config.server.options)
114
- }
115
-
116
- return {
117
- types: {
118
- ...config.types,
119
- path: config.types?.path ?? 'node_modules/.nixxie/types.ts',
120
- },
121
- db: {
122
- ...config.db,
123
- shadowDatabaseUrl: config.db?.shadowDatabaseUrl ?? '',
124
- extendPrismaSchema: config.db?.extendPrismaSchema ?? identity,
125
- extendPrismaClient: config.db?.extendPrismaClient ?? identity,
126
- onConnect: config.db.onConnect ?? noop,
127
- prismaClientPath: config.db?.prismaClientPath ?? '@prisma/client',
128
- prismaSchemaPath: config.db?.prismaSchemaPath ?? 'schema.prisma',
129
- idField: config.db?.idField ?? defaultIdField,
130
- enableLogging:
131
- config.db.enableLogging === true
132
- ? ['query']
133
- : config.db.enableLogging === false
134
- ? []
135
- : (config.db.enableLogging ?? []),
136
- },
137
- graphql: {
138
- ...config.graphql,
139
- path: config.graphql?.path ?? '/api/graphql',
140
- playground: config.graphql?.playground ?? process.env.NODE_ENV !== 'production',
141
- schemaPath: config.graphql?.schemaPath ?? 'schema.graphql',
142
- extendGraphqlSchema: config.graphql?.extendGraphqlSchema ?? (s => s),
143
- },
144
- lists: listsWithDefaults(config, defaultIdField),
145
- server: {
146
- ...config.server,
147
- maxFileSize: config.server?.maxFileSize ?? 200 * 1024 * 1024, // 200 MiB
148
- extendExpressApp: config.server?.extendExpressApp ?? noop,
149
- extendHttpServer: config.server?.extendHttpServer ?? noop,
150
- cors,
151
- options: httpOptions,
152
- },
153
- session: config.session,
154
- email: config.email,
155
- jobs: config.jobs,
156
- cache: config.cache,
157
- audit: config.audit,
158
- webhooks: config.webhooks,
159
- rateLimit: config.rateLimit,
160
- health: config.health,
161
- telemetry: config.telemetry ?? true,
162
- ui: {
163
- ...config.ui,
164
- basePath: config.ui?.basePath ?? '',
165
- isAccessAllowed: config.ui?.isAccessAllowed ?? defaultIsAccessAllowed,
166
- isDisabled: config.ui?.isDisabled ?? false,
167
- getAdditionalFiles: config.ui?.getAdditionalFiles ?? (() => []),
168
- pageMiddleware: config.ui?.pageMiddleware ?? noop,
169
- publicPages: config.ui?.publicPages ?? [],
170
- },
171
- }
172
- }
173
-
174
- let i = 0
175
-
176
- export type GroupInfo<ListTypeInfo extends BaseListTypeInfo> = {
177
- fields: string[]
178
- label: string
179
- description: string
180
- ui: GroupUIConfig<ListTypeInfo> | undefined
181
- }
182
-
183
- type GroupUIConfig<ListTypeInfo extends BaseListTypeInfo> = {
184
- createView?: {
185
- defaultFieldMode?: MaybeSessionFunctionWithFilter<'hidden' | 'edit', 'hidden', ListTypeInfo>
186
- }
187
- itemView?: {
188
- defaultFieldMode?: MaybeItemFunctionWithFilter<
189
- 'edit' | 'hidden' | 'read',
190
- 'hidden' | 'read',
191
- ListTypeInfo
192
- >
193
- }
194
- listView?: {
195
- defaultFieldMode?: MaybeSessionFunction<'read' | 'hidden', ListTypeInfo>
196
- }
197
- }
198
-
199
- export function group<ListTypeInfo extends BaseListTypeInfo>(config: {
200
- label: string
201
- description?: string
202
- ui?: GroupUIConfig<ListTypeInfo>
203
- fields: BaseFields<ListTypeInfo>
204
- }) {
205
- const keys = Object.keys(config.fields)
206
- if (keys.some(key => key.startsWith('__group'))) {
207
- throw new Error('groups cannot be nested')
208
- }
209
-
210
- return {
211
- [`__group${i++}`]: {
212
- fields: keys,
213
- label: config.label,
214
- description: config.description ?? '',
215
- ui: config.ui,
216
- } satisfies GroupInfo<ListTypeInfo>,
217
- ...config.fields,
218
- } as BaseFields<ListTypeInfo> // TODO: FIXME, see initialise-lists.ts:getListsWithInitialisedFields
219
- }
220
-
221
- export function list<ListTypeInfo extends BaseListTypeInfo>(listConfig: ListConfig<ListTypeInfo>) {
222
- return { ...listConfig }
223
- }
224
-
225
- export function action<
226
- ListTypeInfo extends BaseListTypeInfo,
227
- Args extends ActionArgsConfig<ListTypeInfo> | undefined = undefined,
228
- >(action: Action<ListTypeInfo, Args>): DeclaredAction<ListTypeInfo> {
229
- return {
230
- ...action,
231
- ___defineActionsWithActionFunction: true,
232
- } as unknown as DeclaredAction<ListTypeInfo>
233
- }
1
+ import type { ListenOptions } from 'node:net'
2
+
3
+ import { idFieldType } from './lib/id-field'
4
+ import type {
5
+ Action,
6
+ ActionArgsConfig,
7
+ BaseFields,
8
+ BaseNixxieTypeInfo,
9
+ BaseListTypeInfo,
10
+ DeclaredAction,
11
+ IdFieldConfig,
12
+ NixxieConfig,
13
+ NixxieConfigPre,
14
+ NixxieContext,
15
+ ListConfig,
16
+ MaybeItemFunctionWithFilter,
17
+ MaybeSessionFunction,
18
+ MaybeSessionFunctionWithFilter,
19
+ } from './types'
20
+
21
+ function listsWithDefaults(config: NixxieConfigPre, defaultIdField: IdFieldConfig) {
22
+ // some error checking
23
+ for (const [listKey, list] of Object.entries(config.lists)) {
24
+ if (list.fields.id) {
25
+ throw new Error(
26
+ `"fields.id" is reserved by Nixxie, use "db.idField" for the "${listKey}" list`
27
+ )
28
+ }
29
+
30
+ if (list.isSingleton && list.db?.idField) {
31
+ throw new Error(`"db.idField" on the "${listKey}" list conflicts with singleton defaults`)
32
+ }
33
+ }
34
+
35
+ return Object.fromEntries([
36
+ ...(function* () {
37
+ for (const [listKey, list] of Object.entries(config.lists)) {
38
+ yield [
39
+ listKey,
40
+ {
41
+ listKey,
42
+ defaultIsFilterable: true, // TODO: move to access control?
43
+ defaultIsOrderable: true, // TODO: move to access control?
44
+ isSingleton: false,
45
+ ...list,
46
+ db: {
47
+ ...list.db,
48
+ },
49
+ fields: {
50
+ ...(list.isSingleton
51
+ ? {
52
+ id: idFieldType({ kind: 'number', type: 'Int' }),
53
+ ...list.fields,
54
+ }
55
+ : {
56
+ id: idFieldType(list.db?.idField ?? defaultIdField),
57
+ ...list.fields,
58
+ }),
59
+ },
60
+ actions: {
61
+ ...list.actions,
62
+ },
63
+ hooks: {
64
+ ...list.hooks,
65
+ },
66
+ graphql: {
67
+ ...list.graphql,
68
+ },
69
+ ui: {
70
+ ...list.ui,
71
+ },
72
+ } satisfies NixxieConfig['lists'][string],
73
+ ]
74
+ }
75
+ })(),
76
+ ]) satisfies NixxieConfig['lists']
77
+ }
78
+
79
+ function defaultIsAccessAllowed({ session, sessionStrategy }: NixxieContext) {
80
+ if (!sessionStrategy) return true
81
+ return session !== undefined
82
+ }
83
+
84
+ async function noop() {}
85
+ function identity<T>(x: T) {
86
+ return x
87
+ }
88
+
89
+ export function config<TypeInfo extends BaseNixxieTypeInfo>(
90
+ config: NixxieConfigPre<TypeInfo>
91
+ ): NixxieConfig<TypeInfo> {
92
+ if (!['postgresql', 'sqlite', 'mysql'].includes(config.db.provider)) {
93
+ throw new TypeError(`"db.provider" only supports "sqlite", "postgresql" or "mysql"`)
94
+ }
95
+
96
+ // WARNING: Typescript should prevent this, but any string is useful for Prisma errors
97
+ config.db.url ??= 'postgres://'
98
+
99
+ const defaultIdField = config.db.idField ?? { kind: 'cuid' }
100
+ const cors =
101
+ config.server?.cors === true
102
+ ? { origin: true, credentials: true }
103
+ : config.server?.cors === false
104
+ ? null
105
+ : (config.server?.cors ?? null)
106
+
107
+ const httpOptions: ListenOptions = { port: 3000 }
108
+ if (config?.server && 'port' in config.server) {
109
+ httpOptions.port = config.server.port
110
+ }
111
+
112
+ if (config?.server && 'options' in config.server && config.server.options) {
113
+ Object.assign(httpOptions, config.server.options)
114
+ }
115
+
116
+ return {
117
+ types: {
118
+ ...config.types,
119
+ path: config.types?.path ?? 'node_modules/.nixxie/types.ts',
120
+ },
121
+ db: {
122
+ ...config.db,
123
+ shadowDatabaseUrl: config.db?.shadowDatabaseUrl ?? '',
124
+ extendPrismaSchema: config.db?.extendPrismaSchema ?? identity,
125
+ extendPrismaClient: config.db?.extendPrismaClient ?? identity,
126
+ onConnect: config.db.onConnect ?? noop,
127
+ prismaClientPath: config.db?.prismaClientPath ?? '@prisma/client',
128
+ prismaSchemaPath: config.db?.prismaSchemaPath ?? 'schema.prisma',
129
+ idField: config.db?.idField ?? defaultIdField,
130
+ enableLogging:
131
+ config.db.enableLogging === true
132
+ ? ['query']
133
+ : config.db.enableLogging === false
134
+ ? []
135
+ : (config.db.enableLogging ?? []),
136
+ },
137
+ graphql: {
138
+ ...config.graphql,
139
+ path: config.graphql?.path ?? '/api/graphql',
140
+ playground: config.graphql?.playground ?? process.env.NODE_ENV !== 'production',
141
+ schemaPath: config.graphql?.schemaPath ?? 'schema.graphql',
142
+ extendGraphqlSchema: config.graphql?.extendGraphqlSchema ?? (s => s),
143
+ },
144
+ lists: listsWithDefaults(config, defaultIdField),
145
+ server: {
146
+ ...config.server,
147
+ maxFileSize: config.server?.maxFileSize ?? 200 * 1024 * 1024, // 200 MiB
148
+ extendExpressApp: config.server?.extendExpressApp ?? noop,
149
+ extendHttpServer: config.server?.extendHttpServer ?? noop,
150
+ cors,
151
+ options: httpOptions,
152
+ },
153
+ session: config.session,
154
+ email: config.email,
155
+ jobs: config.jobs,
156
+ cache: config.cache,
157
+ audit: config.audit,
158
+ webhooks: config.webhooks,
159
+ rateLimit: config.rateLimit,
160
+ health: config.health,
161
+ storage: config.storage,
162
+ search: config.search,
163
+ notifications: config.notifications,
164
+ ai: config.ai,
165
+ telemetry: config.telemetry ?? true,
166
+ ui: {
167
+ ...config.ui,
168
+ basePath: config.ui?.basePath ?? '',
169
+ isAccessAllowed: config.ui?.isAccessAllowed ?? defaultIsAccessAllowed,
170
+ isDisabled: config.ui?.isDisabled ?? false,
171
+ getAdditionalFiles: config.ui?.getAdditionalFiles ?? (() => []),
172
+ pageMiddleware: config.ui?.pageMiddleware ?? noop,
173
+ publicPages: config.ui?.publicPages ?? [],
174
+ },
175
+ }
176
+ }
177
+
178
+ let i = 0
179
+
180
+ export type GroupInfo<ListTypeInfo extends BaseListTypeInfo> = {
181
+ fields: string[]
182
+ label: string
183
+ description: string
184
+ ui: GroupUIConfig<ListTypeInfo> | undefined
185
+ }
186
+
187
+ type GroupUIConfig<ListTypeInfo extends BaseListTypeInfo> = {
188
+ createView?: {
189
+ defaultFieldMode?: MaybeSessionFunctionWithFilter<'hidden' | 'edit', 'hidden', ListTypeInfo>
190
+ }
191
+ itemView?: {
192
+ defaultFieldMode?: MaybeItemFunctionWithFilter<
193
+ 'edit' | 'hidden' | 'read',
194
+ 'hidden' | 'read',
195
+ ListTypeInfo
196
+ >
197
+ }
198
+ listView?: {
199
+ defaultFieldMode?: MaybeSessionFunction<'read' | 'hidden', ListTypeInfo>
200
+ }
201
+ }
202
+
203
+ export function group<ListTypeInfo extends BaseListTypeInfo>(config: {
204
+ label: string
205
+ description?: string
206
+ ui?: GroupUIConfig<ListTypeInfo>
207
+ fields: BaseFields<ListTypeInfo>
208
+ }) {
209
+ const keys = Object.keys(config.fields)
210
+ if (keys.some(key => key.startsWith('__group'))) {
211
+ throw new Error('groups cannot be nested')
212
+ }
213
+
214
+ return {
215
+ [`__group${i++}`]: {
216
+ fields: keys,
217
+ label: config.label,
218
+ description: config.description ?? '',
219
+ ui: config.ui,
220
+ } satisfies GroupInfo<ListTypeInfo>,
221
+ ...config.fields,
222
+ } as BaseFields<ListTypeInfo> // TODO: FIXME, see initialise-lists.ts:getListsWithInitialisedFields
223
+ }
224
+
225
+ export function list<ListTypeInfo extends BaseListTypeInfo>(listConfig: ListConfig<ListTypeInfo>) {
226
+ return { ...listConfig }
227
+ }
228
+
229
+ export function action<
230
+ ListTypeInfo extends BaseListTypeInfo,
231
+ Args extends ActionArgsConfig<ListTypeInfo> | undefined = undefined,
232
+ >(action: Action<ListTypeInfo, Args>): DeclaredAction<ListTypeInfo> {
233
+ return {
234
+ ...action,
235
+ ___defineActionsWithActionFunction: true,
236
+ } as unknown as DeclaredAction<ListTypeInfo>
237
+ }
@@ -18,7 +18,7 @@ export async function telemetry(_: string, command?: string) {
18
18
  status show if telemetry is enabled, disabled or uninitialised
19
19
  inform show an informed consent notice
20
20
 
21
- For more details visit: https://nixxiecms.com/telemetry
21
+ For more details visit: https://nixxieinternational.com/telemetry
22
22
  `
23
23
 
24
24
  if (command === 'disable') return disableTelemetry()