remult 0.22.7-exp.0 → 0.22.7

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 (249) hide show
  1. package/SseSubscriptionServer.d.ts +25 -25
  2. package/SseSubscriptionServer.js +145 -145
  3. package/ably.d.ts +13 -13
  4. package/ably.js +59 -59
  5. package/assign.d.ts +1 -1
  6. package/assign.js +9 -9
  7. package/classType.d.ts +3 -3
  8. package/classType.js +2 -2
  9. package/esm/SseSubscriptionServer.d.ts +25 -25
  10. package/esm/SseSubscriptionServer.js +107 -104
  11. package/esm/ably.d.ts +13 -13
  12. package/esm/ably.js +30 -28
  13. package/esm/assign.d.ts +1 -1
  14. package/esm/assign.js +5 -5
  15. package/esm/classType.d.ts +3 -3
  16. package/esm/classType.js +1 -1
  17. package/esm/graphql.d.ts +14 -14
  18. package/esm/graphql.js +785 -785
  19. package/esm/index.d.ts +31 -31
  20. package/esm/index.js +25 -25
  21. package/esm/inputTypes.d.ts +9 -9
  22. package/esm/inputTypes.js +9 -9
  23. package/esm/live-query/data-provider-live-query-storage.d.ts +23 -23
  24. package/esm/live-query/data-provider-live-query-storage.js +91 -93
  25. package/esm/myLog.d.ts +1 -1
  26. package/esm/myLog.js +5 -5
  27. package/esm/postgres/index.d.ts +2 -2
  28. package/esm/postgres/index.js +2 -2
  29. package/esm/postgres/postgres-data-provider.d.ts +36 -36
  30. package/esm/postgres/postgres-data-provider.js +126 -122
  31. package/esm/postgres/schema-builder.d.ts +19 -19
  32. package/esm/postgres/schema-builder.js +197 -196
  33. package/esm/remult-express.d.ts +9 -9
  34. package/esm/remult-express.js +26 -25
  35. package/esm/remult-fastify.d.ts +6 -6
  36. package/esm/remult-fastify.js +68 -68
  37. package/esm/remult-fresh.d.ts +17 -17
  38. package/esm/remult-fresh.js +26 -26
  39. package/esm/remult-knex/index.d.ts +30 -30
  40. package/esm/remult-knex/index.js +466 -460
  41. package/esm/remult-mongo.d.ts +24 -24
  42. package/esm/remult-mongo.js +269 -262
  43. package/esm/remult-next.d.ts +25 -25
  44. package/esm/remult-next.js +114 -114
  45. package/esm/remult-sveltekit.d.ts +4 -4
  46. package/esm/remult-sveltekit.js +71 -71
  47. package/esm/server/JsonEntityFileStorage.d.ts +11 -11
  48. package/esm/server/JsonEntityFileStorage.js +27 -26
  49. package/esm/server/core.d.ts +4 -4
  50. package/esm/server/core.js +4 -4
  51. package/esm/server/expressBridge.d.ts +128 -128
  52. package/esm/server/expressBridge.js +988 -971
  53. package/esm/server/index.d.ts +6 -6
  54. package/esm/server/index.js +12 -12
  55. package/esm/server/initAsyncHooks.d.ts +1 -1
  56. package/esm/server/initAsyncHooks.js +9 -9
  57. package/esm/server/initDataProvider.d.ts +2 -2
  58. package/esm/server/initDataProvider.js +14 -14
  59. package/esm/src/CompoundIdField.d.ts +27 -27
  60. package/esm/src/CompoundIdField.js +54 -41
  61. package/esm/src/__EntityValueProvider.d.ts +11 -11
  62. package/esm/src/__EntityValueProvider.js +1 -1
  63. package/esm/src/__RowsOfDataForTesting.d.ts +3 -3
  64. package/esm/src/__RowsOfDataForTesting.js +1 -1
  65. package/esm/src/buildRestDataProvider.d.ts +31 -31
  66. package/esm/src/buildRestDataProvider.js +121 -120
  67. package/esm/src/column-interfaces.d.ts +160 -160
  68. package/esm/src/column-interfaces.js +7 -7
  69. package/esm/src/column.d.ts +31 -31
  70. package/esm/src/column.js +108 -101
  71. package/esm/src/context.d.ts +134 -134
  72. package/esm/src/context.js +287 -282
  73. package/esm/src/data-api.d.ts +38 -38
  74. package/esm/src/data-api.js +281 -279
  75. package/esm/src/data-interfaces.d.ts +41 -41
  76. package/esm/src/data-interfaces.js +12 -12
  77. package/esm/src/data-providers/array-entity-data-provider.d.ts +22 -22
  78. package/esm/src/data-providers/array-entity-data-provider.js +252 -249
  79. package/esm/src/data-providers/in-memory-database.d.ts +9 -9
  80. package/esm/src/data-providers/in-memory-database.js +16 -18
  81. package/esm/src/data-providers/json-data-provider.d.ts +12 -12
  82. package/esm/src/data-providers/json-data-provider.js +55 -52
  83. package/esm/src/data-providers/rest-data-provider.d.ts +39 -39
  84. package/esm/src/data-providers/rest-data-provider.js +272 -267
  85. package/esm/src/data-providers/sql-database.d.ts +33 -33
  86. package/esm/src/data-providers/sql-database.js +401 -394
  87. package/esm/src/data-providers/web-sql-data-provider.d.ts +21 -21
  88. package/esm/src/data-providers/web-sql-data-provider.js +145 -137
  89. package/esm/src/entity.d.ts +95 -95
  90. package/esm/src/entity.js +1 -1
  91. package/esm/src/filter/filter-consumer-bridge-to-sql-request.d.ts +50 -50
  92. package/esm/src/filter/filter-consumer-bridge-to-sql-request.js +165 -162
  93. package/esm/src/filter/filter-interfaces.d.ts +86 -86
  94. package/esm/src/filter/filter-interfaces.js +524 -515
  95. package/esm/src/live-query/LiveQueryClient.d.ts +1 -1
  96. package/esm/src/live-query/LiveQueryClient.js +196 -192
  97. package/esm/src/live-query/SseSubscriptionClient.d.ts +5 -5
  98. package/esm/src/live-query/SseSubscriptionClient.js +86 -86
  99. package/esm/src/live-query/SubscriptionChannel.d.ts +41 -41
  100. package/esm/src/live-query/SubscriptionChannel.js +126 -121
  101. package/esm/src/live-query/SubscriptionServer.d.ts +38 -38
  102. package/esm/src/live-query/SubscriptionServer.js +114 -112
  103. package/esm/src/remult-proxy.d.ts +2 -2
  104. package/esm/src/remult-proxy.js +177 -178
  105. package/esm/src/remult3/DecoratorReplacer.d.ts +10 -10
  106. package/esm/src/remult3/DecoratorReplacer.js +20 -20
  107. package/esm/src/remult3/RepositoryImplementation.d.ts +332 -332
  108. package/esm/src/remult3/RepositoryImplementation.js +2122 -2051
  109. package/esm/src/remult3/__updateEntityBasedOnWhere.d.ts +2 -2
  110. package/esm/src/remult3/__updateEntityBasedOnWhere.js +24 -24
  111. package/esm/src/remult3/entity.d.ts +28 -28
  112. package/esm/src/remult3/entity.js +70 -70
  113. package/esm/src/remult3/getEntityRef.d.ts +9 -9
  114. package/esm/src/remult3/getEntityRef.js +27 -27
  115. package/esm/src/remult3/remult3.d.ts +397 -397
  116. package/esm/src/remult3/remult3.js +1 -1
  117. package/esm/src/resultCompoundIdFilter.d.ts +3 -3
  118. package/esm/src/resultCompoundIdFilter.js +16 -16
  119. package/esm/src/server-action-info.d.ts +10 -10
  120. package/esm/src/server-action-info.js +12 -12
  121. package/esm/src/server-action.d.ts +79 -79
  122. package/esm/src/server-action.js +397 -387
  123. package/esm/src/sort.d.ts +16 -16
  124. package/esm/src/sort.js +105 -104
  125. package/esm/src/sql-command.d.ts +19 -19
  126. package/esm/src/sql-command.js +1 -1
  127. package/esm/src/validators.d.ts +14 -14
  128. package/esm/src/validators.js +36 -36
  129. package/esm/src/valueConverters.d.ts +13 -13
  130. package/esm/src/valueConverters.js +210 -210
  131. package/esm/urlBuilder.d.ts +6 -6
  132. package/esm/urlBuilder.js +20 -19
  133. package/graphql.d.ts +14 -14
  134. package/graphql.js +953 -953
  135. package/index.d.ts +31 -31
  136. package/index.js +67 -67
  137. package/inputTypes.d.ts +9 -9
  138. package/inputTypes.js +16 -16
  139. package/live-query/data-provider-live-query-storage.d.ts +23 -23
  140. package/live-query/data-provider-live-query-storage.js +263 -263
  141. package/myLog.d.ts +1 -1
  142. package/myLog.js +20 -20
  143. package/package.json +1 -1
  144. package/postgres/index.d.ts +2 -2
  145. package/postgres/index.js +5 -5
  146. package/postgres/postgres-data-provider.d.ts +36 -36
  147. package/postgres/postgres-data-provider.js +191 -191
  148. package/postgres/schema-builder.d.ts +19 -19
  149. package/postgres/schema-builder.js +369 -369
  150. package/remult-express.d.ts +9 -9
  151. package/remult-express.js +34 -33
  152. package/remult-fastify.d.ts +6 -6
  153. package/remult-fastify.js +79 -79
  154. package/remult-fresh.d.ts +17 -17
  155. package/remult-fresh.js +41 -41
  156. package/remult-knex/index.d.ts +30 -30
  157. package/remult-knex/index.js +917 -915
  158. package/remult-mongo.d.ts +24 -24
  159. package/remult-mongo.js +515 -515
  160. package/remult-next.d.ts +25 -25
  161. package/remult-next.js +171 -171
  162. package/remult-sveltekit.d.ts +4 -4
  163. package/remult-sveltekit.js +110 -110
  164. package/server/JsonEntityFileStorage.d.ts +11 -11
  165. package/server/JsonEntityFileStorage.js +35 -35
  166. package/server/core.d.ts +4 -4
  167. package/server/core.js +12 -12
  168. package/server/expressBridge.d.ts +128 -128
  169. package/server/expressBridge.js +1401 -1402
  170. package/server/index.d.ts +6 -6
  171. package/server/index.js +24 -24
  172. package/server/initAsyncHooks.d.ts +1 -1
  173. package/server/initAsyncHooks.js +13 -13
  174. package/server/initDataProvider.d.ts +2 -2
  175. package/server/initDataProvider.js +26 -26
  176. package/src/CompoundIdField.d.ts +27 -27
  177. package/src/CompoundIdField.js +54 -54
  178. package/src/__EntityValueProvider.d.ts +11 -11
  179. package/src/__EntityValueProvider.js +2 -2
  180. package/src/__RowsOfDataForTesting.d.ts +3 -3
  181. package/src/__RowsOfDataForTesting.js +2 -2
  182. package/src/buildRestDataProvider.d.ts +31 -31
  183. package/src/buildRestDataProvider.js +177 -174
  184. package/src/column-interfaces.d.ts +160 -160
  185. package/src/column-interfaces.js +11 -11
  186. package/src/column.d.ts +31 -31
  187. package/src/column.js +132 -132
  188. package/src/context.d.ts +134 -134
  189. package/src/context.js +451 -451
  190. package/src/data-api.d.ts +38 -38
  191. package/src/data-api.js +524 -524
  192. package/src/data-interfaces.d.ts +41 -41
  193. package/src/data-interfaces.js +16 -16
  194. package/src/data-providers/array-entity-data-provider.d.ts +22 -22
  195. package/src/data-providers/array-entity-data-provider.js +364 -364
  196. package/src/data-providers/in-memory-database.d.ts +9 -9
  197. package/src/data-providers/in-memory-database.js +33 -33
  198. package/src/data-providers/json-data-provider.d.ts +12 -12
  199. package/src/data-providers/json-data-provider.js +106 -106
  200. package/src/data-providers/rest-data-provider.d.ts +39 -39
  201. package/src/data-providers/rest-data-provider.js +388 -388
  202. package/src/data-providers/sql-database.d.ts +33 -33
  203. package/src/data-providers/sql-database.js +653 -653
  204. package/src/data-providers/web-sql-data-provider.d.ts +21 -21
  205. package/src/data-providers/web-sql-data-provider.js +229 -229
  206. package/src/entity.d.ts +95 -95
  207. package/src/entity.js +2 -2
  208. package/src/filter/filter-consumer-bridge-to-sql-request.d.ts +50 -50
  209. package/src/filter/filter-consumer-bridge-to-sql-request.js +307 -307
  210. package/src/filter/filter-interfaces.d.ts +86 -86
  211. package/src/filter/filter-interfaces.js +693 -685
  212. package/src/live-query/LiveQueryClient.d.ts +1 -1
  213. package/src/live-query/LiveQueryClient.js +293 -293
  214. package/src/live-query/SseSubscriptionClient.d.ts +5 -5
  215. package/src/live-query/SseSubscriptionClient.js +154 -154
  216. package/src/live-query/SubscriptionChannel.d.ts +41 -41
  217. package/src/live-query/SubscriptionChannel.js +189 -189
  218. package/src/live-query/SubscriptionServer.d.ts +38 -38
  219. package/src/live-query/SubscriptionServer.js +264 -264
  220. package/src/remult-proxy.d.ts +2 -2
  221. package/src/remult-proxy.js +307 -307
  222. package/src/remult3/DecoratorReplacer.d.ts +10 -10
  223. package/src/remult3/DecoratorReplacer.js +24 -24
  224. package/src/remult3/RepositoryImplementation.d.ts +332 -332
  225. package/src/remult3/RepositoryImplementation.js +3391 -3373
  226. package/src/remult3/__updateEntityBasedOnWhere.d.ts +2 -2
  227. package/src/remult3/__updateEntityBasedOnWhere.js +28 -28
  228. package/src/remult3/entity.d.ts +28 -28
  229. package/src/remult3/entity.js +88 -88
  230. package/src/remult3/getEntityRef.d.ts +9 -9
  231. package/src/remult3/getEntityRef.js +35 -35
  232. package/src/remult3/remult3.d.ts +397 -397
  233. package/src/remult3/remult3.js +2 -2
  234. package/src/resultCompoundIdFilter.d.ts +3 -3
  235. package/src/resultCompoundIdFilter.js +20 -20
  236. package/src/server-action-info.d.ts +10 -10
  237. package/src/server-action-info.js +15 -15
  238. package/src/server-action.d.ts +79 -79
  239. package/src/server-action.js +632 -632
  240. package/src/sort.d.ts +16 -16
  241. package/src/sort.js +161 -161
  242. package/src/sql-command.d.ts +19 -19
  243. package/src/sql-command.js +2 -2
  244. package/src/validators.d.ts +14 -14
  245. package/src/validators.js +71 -69
  246. package/src/valueConverters.d.ts +13 -13
  247. package/src/valueConverters.js +213 -213
  248. package/urlBuilder.d.ts +6 -6
  249. package/urlBuilder.js +25 -25
package/esm/graphql.js CHANGED
@@ -1,812 +1,812 @@
1
- import { Remult, remult } from './index';
2
- import { DataApi } from './src/data-api';
3
- const v2ConnectionAndPagination = false;
4
- const andImplementation = false;
5
- let _removeComments = false;
6
- export function remultGraphql(options) {
7
- if (!options.getRemultFromRequest) {
8
- options.getRemultFromRequest = () => remult;
9
- }
10
- const { removeComments } = {
11
- removeComments: false,
12
- ...options,
13
- };
14
- if (removeComments) {
15
- _removeComments = true;
16
- }
17
- const entities = (() => {
18
- const remult = new Remult();
19
- return options.entities?.map((x) => remult.repo(x).metadata) || [];
20
- })();
21
- const types = [];
22
- const root = {};
23
- const resolversQuery = {};
24
- const resolversMutation = {};
25
- const resolvers = { Query: resolversQuery, Mutation: resolversMutation };
26
- function upsertTypes(key, kind = 'type', order = 0) {
27
- let t = types.find((t) => t.key === key);
28
- if (!t) {
29
- types.push((t = {
30
- key,
31
- kind,
32
- fields: [],
33
- query: {
34
- orderBy: [],
35
- whereType: [],
36
- whereTypeSubFields: [],
37
- resultProcessors: [],
38
- },
39
- mutation: {
40
- create: {},
41
- update: {},
42
- delete: {},
43
- },
44
- order,
45
- }));
46
- if (kind === 'type_impl_node') {
47
- t.fields.push({ ...argNodeId, order: 111 });
48
- }
49
- }
50
- return t;
51
- }
52
- function upsertUnion(key, values, order) {
53
- const u = upsertTypes(key, 'union', order);
54
- u.fields = values.map((value) => {
55
- return { key: value, value: { Union: true } };
56
- });
57
- return u;
58
- }
59
- // Where - GraphQL primitives
60
- for (const whereType of ['String', 'Int', 'Float', 'Boolean', 'ID']) {
61
- const currentWhere = upsertTypes(`Where${whereType}`, 'input', 20);
62
- const currentWhereNullable = upsertTypes(`Where${whereType}Nullable`, 'input', 20);
63
- // For everyone
64
- const operatorType = ['eq', 'ne'];
65
- const operatorTypeArray = ['in', 'nin'];
66
- for (const operator of [...operatorType, ...operatorTypeArray]) {
67
- const field = {
68
- key: operator,
69
- value: operatorTypeArray.includes(operator)
70
- ? `[${whereType}!]`
71
- : whereType,
72
- };
73
- currentWhere.fields.push(field);
74
- currentWhereNullable.fields.push(field);
75
- }
76
- // only for specific types
77
- if (whereType === 'String' ||
78
- whereType === 'Int' ||
79
- whereType === 'Float') {
80
- for (const operator of ['gt', 'gte', 'lt', 'lte']) {
81
- const field = {
82
- key: operator,
83
- value: whereType,
84
- };
85
- currentWhere.fields.push(field);
86
- currentWhereNullable.fields.push(field);
87
- }
88
- }
89
- if (whereType === 'String') {
90
- for (const operator of ['contains']) {
91
- const field = {
92
- key: operator,
93
- value: whereType,
94
- };
95
- currentWhere.fields.push(field);
96
- currentWhereNullable.fields.push(field);
97
- }
98
- }
99
- // add only for nullable
100
- currentWhereNullable.fields.push({
101
- key: 'null',
102
- value: 'Boolean',
103
- });
104
- }
105
- const root_query = upsertTypes('Query', 'type', -10);
106
- root_query.comment = `Represents all Remult entities.`;
107
- const argId = { key: `id`, value: `ID!` };
108
- const nodeIdKey = 'nodeId';
109
- const argNodeId = {
110
- key: nodeIdKey,
111
- value: `ID!`,
112
- comment: `The globally unique \`ID\` _(_typename:id)_`,
113
- };
114
- const argClientMutationId = { key: 'clientMutationId', value: `String` };
115
- const argErrorDetail = { key: 'error', value: `ErrorDetail` };
116
- for (const meta of entities) {
117
- const orderByFields = [];
118
- const key = meta.key;
119
- const currentType = upsertTypes(getMetaType(meta), 'type_impl_node');
120
- if (key) {
121
- const createResultPromise = (work) => {
122
- return async (arg1, req) => {
123
- return new Promise((res, error) => {
124
- let result;
125
- let err;
126
- const response = {
127
- success: (x) => {
128
- err = 'success not handled';
129
- },
130
- created: () => {
131
- err = 'created not handled';
132
- },
133
- deleted: () => {
134
- err = 'deleted not handled';
135
- },
136
- error: (x) => (err = x),
137
- forbidden: () => (err = 'forbidden'),
138
- notFound: () => (err = 'not found'),
139
- progress: () => { },
140
- };
141
- work(response, (x) => (result = x), arg1, req)
142
- .then(() => {
143
- if (err) {
144
- error(err);
145
- return;
146
- }
147
- res(result);
148
- })
149
- .catch((err) => error(err));
150
- });
151
- };
152
- };
153
- const handleRequestWithDataApiContext = (work) => {
154
- return createResultPromise(async (response, setResult, arg1, req) => {
155
- const remult = options.getRemultFromRequest(req);
156
- const repo = remult.repo(meta.entityType);
157
- const dApi = new DataApi(repo, remult);
158
- await work(dApi, response, setResult, arg1, meta);
159
- });
160
- };
161
- const handleMutationWithErrors = (work) => {
162
- return handleRequestWithDataApiContext(async (dApi, response, origSetResult, arg1, req) => {
163
- const setResult = (item) => {
164
- origSetResult({
165
- clientMutationId: arg1.clientMutationId,
166
- ...item,
167
- });
168
- };
169
- return work(dApi, {
170
- ...response,
171
- forbidden: () => {
172
- setResult({
173
- error: {
174
- __typename: 'ForbiddenError',
175
- message: 'forbidden',
176
- },
177
- });
178
- },
179
- notFound: () => {
180
- setResult({
181
- error: {
182
- __typename: 'NotFoundError',
183
- message: 'not found',
184
- },
185
- });
186
- },
187
- error: (err) => {
188
- const modelState = [];
189
- if (err.modelState)
190
- for (const key in err.modelState) {
191
- modelState.push({
192
- field: key,
193
- message: err.modelState[key],
194
- });
195
- }
196
- setResult({
197
- error: {
198
- __typename: 'ValidationError',
199
- message: err.message,
200
- modelState,
201
- },
202
- });
203
- },
204
- }, setResult, arg1, req);
205
- });
206
- };
207
- const queryArgsConnection = [
208
- {
209
- key: 'limit',
210
- value: 'Int',
1
+ import { Remult, remult } from './index';
2
+ import { DataApi } from './src/data-api';
3
+ const v2ConnectionAndPagination = false;
4
+ const andImplementation = false;
5
+ let _removeComments = false;
6
+ export function remultGraphql(options) {
7
+ if (!options.getRemultFromRequest) {
8
+ options.getRemultFromRequest = () => remult;
9
+ }
10
+ const { removeComments } = {
11
+ removeComments: false,
12
+ ...options,
13
+ };
14
+ if (removeComments) {
15
+ _removeComments = true;
16
+ }
17
+ const entities = (() => {
18
+ const remult = new Remult();
19
+ return options.entities?.map((x) => remult.repo(x).metadata) || [];
20
+ })();
21
+ const types = [];
22
+ const root = {};
23
+ const resolversQuery = {};
24
+ const resolversMutation = {};
25
+ const resolvers = { Query: resolversQuery, Mutation: resolversMutation };
26
+ function upsertTypes(key, kind = 'type', order = 0) {
27
+ let t = types.find((t) => t.key === key);
28
+ if (!t) {
29
+ types.push((t = {
30
+ key,
31
+ kind,
32
+ fields: [],
33
+ query: {
34
+ orderBy: [],
35
+ whereType: [],
36
+ whereTypeSubFields: [],
37
+ resultProcessors: [],
38
+ },
39
+ mutation: {
40
+ create: {},
41
+ update: {},
42
+ delete: {},
43
+ },
44
+ order,
45
+ }));
46
+ if (kind === 'type_impl_node') {
47
+ t.fields.push({ ...argNodeId, order: 111 });
48
+ }
49
+ }
50
+ return t;
51
+ }
52
+ function upsertUnion(key, values, order) {
53
+ const u = upsertTypes(key, 'union', order);
54
+ u.fields = values.map((value) => {
55
+ return { key: value, value: { Union: true } };
56
+ });
57
+ return u;
58
+ }
59
+ // Where - GraphQL primitives
60
+ for (const whereType of ['String', 'Int', 'Float', 'Boolean', 'ID']) {
61
+ const currentWhere = upsertTypes(`Where${whereType}`, 'input', 20);
62
+ const currentWhereNullable = upsertTypes(`Where${whereType}Nullable`, 'input', 20);
63
+ // For everyone
64
+ const operatorType = ['eq', 'ne'];
65
+ const operatorTypeArray = ['in', 'nin'];
66
+ for (const operator of [...operatorType, ...operatorTypeArray]) {
67
+ const field = {
68
+ key: operator,
69
+ value: operatorTypeArray.includes(operator)
70
+ ? `[${whereType}!]`
71
+ : whereType,
72
+ };
73
+ currentWhere.fields.push(field);
74
+ currentWhereNullable.fields.push(field);
75
+ }
76
+ // only for specific types
77
+ if (whereType === 'String' ||
78
+ whereType === 'Int' ||
79
+ whereType === 'Float') {
80
+ for (const operator of ['gt', 'gte', 'lt', 'lte']) {
81
+ const field = {
82
+ key: operator,
83
+ value: whereType,
84
+ };
85
+ currentWhere.fields.push(field);
86
+ currentWhereNullable.fields.push(field);
87
+ }
88
+ }
89
+ if (whereType === 'String') {
90
+ for (const operator of ['contains']) {
91
+ const field = {
92
+ key: operator,
93
+ value: whereType,
94
+ };
95
+ currentWhere.fields.push(field);
96
+ currentWhereNullable.fields.push(field);
97
+ }
98
+ }
99
+ // add only for nullable
100
+ currentWhereNullable.fields.push({
101
+ key: 'null',
102
+ value: 'Boolean',
103
+ });
104
+ }
105
+ const root_query = upsertTypes('Query', 'type', -10);
106
+ root_query.comment = `Represents all Remult entities.`;
107
+ const argId = { key: `id`, value: `ID!` };
108
+ const nodeIdKey = 'nodeId';
109
+ const argNodeId = {
110
+ key: nodeIdKey,
111
+ value: `ID!`,
112
+ comment: `The globally unique \`ID\` _(_typename:id)_`,
113
+ };
114
+ const argClientMutationId = { key: 'clientMutationId', value: `String` };
115
+ const argErrorDetail = { key: 'error', value: `ErrorDetail` };
116
+ for (const meta of entities) {
117
+ const orderByFields = [];
118
+ const key = meta.key;
119
+ const currentType = upsertTypes(getMetaType(meta), 'type_impl_node');
120
+ if (key) {
121
+ const createResultPromise = (work) => {
122
+ return async (arg1, req) => {
123
+ return new Promise((res, error) => {
124
+ let result;
125
+ let err;
126
+ const response = {
127
+ success: (x) => {
128
+ err = 'success not handled';
129
+ },
130
+ created: () => {
131
+ err = 'created not handled';
132
+ },
133
+ deleted: () => {
134
+ err = 'deleted not handled';
135
+ },
136
+ error: (x) => (err = x),
137
+ forbidden: () => (err = 'forbidden'),
138
+ notFound: () => (err = 'not found'),
139
+ progress: () => { },
140
+ };
141
+ work(response, (x) => (result = x), arg1, req)
142
+ .then(() => {
143
+ if (err) {
144
+ error(err);
145
+ return;
146
+ }
147
+ res(result);
148
+ })
149
+ .catch((err) => error(err));
150
+ });
151
+ };
152
+ };
153
+ const handleRequestWithDataApiContext = (work) => {
154
+ return createResultPromise(async (response, setResult, arg1, req) => {
155
+ const remult = options.getRemultFromRequest(req);
156
+ const repo = remult.repo(meta.entityType);
157
+ const dApi = new DataApi(repo, remult);
158
+ await work(dApi, response, setResult, arg1, meta);
159
+ });
160
+ };
161
+ const handleMutationWithErrors = (work) => {
162
+ return handleRequestWithDataApiContext(async (dApi, response, origSetResult, arg1, req) => {
163
+ const setResult = (item) => {
164
+ origSetResult({
165
+ clientMutationId: arg1.clientMutationId,
166
+ ...item,
167
+ });
168
+ };
169
+ return work(dApi, {
170
+ ...response,
171
+ forbidden: () => {
172
+ setResult({
173
+ error: {
174
+ __typename: 'ForbiddenError',
175
+ message: 'forbidden',
176
+ },
177
+ });
178
+ },
179
+ notFound: () => {
180
+ setResult({
181
+ error: {
182
+ __typename: 'NotFoundError',
183
+ message: 'not found',
184
+ },
185
+ });
186
+ },
187
+ error: (err) => {
188
+ const modelState = [];
189
+ if (err.modelState)
190
+ for (const key in err.modelState) {
191
+ modelState.push({
192
+ field: key,
193
+ message: err.modelState[key],
194
+ });
195
+ }
196
+ setResult({
197
+ error: {
198
+ __typename: 'ValidationError',
199
+ message: err.message,
200
+ modelState,
201
+ },
202
+ });
203
+ },
204
+ }, setResult, arg1, req);
205
+ });
206
+ };
207
+ const queryArgsConnection = [
208
+ {
209
+ key: 'limit',
210
+ value: 'Int',
211
211
  comment: `
212
212
  For **page by page** pagination.
213
213
  Limit the number of result.
214
- _Side note: \`Math.ceil(totalCount / limit)\` to determine how many pages there are._`,
215
- },
216
- {
217
- key: 'page',
218
- value: 'Int',
214
+ _Side note: \`Math.ceil(totalCount / limit)\` to determine how many pages there are._`,
215
+ },
216
+ {
217
+ key: 'page',
218
+ value: 'Int',
219
219
  comment: `
220
220
  For **page by page** pagination.
221
- Select a dedicated page.`,
222
- },
223
- {
224
- key: 'orderBy',
225
- value: `${key}OrderBy`,
226
- comment: `Remult sorting options`,
227
- },
228
- {
229
- key: 'where',
230
- value: `${key}Where`,
231
- comment: `Remult filtering options`,
232
- },
233
- ];
234
- if (v2ConnectionAndPagination) {
235
- queryArgsConnection.push({
236
- key: 'first',
237
- value: 'Int',
221
+ Select a dedicated page.`,
222
+ },
223
+ {
224
+ key: 'orderBy',
225
+ value: `${key}OrderBy`,
226
+ comment: `Remult sorting options`,
227
+ },
228
+ {
229
+ key: 'where',
230
+ value: `${key}Where`,
231
+ comment: `Remult filtering options`,
232
+ },
233
+ ];
234
+ if (v2ConnectionAndPagination) {
235
+ queryArgsConnection.push({
236
+ key: 'first',
237
+ value: 'Int',
238
238
  comment: `
239
239
  For **forward cursor** pagination
240
- Takes the \`first\`: \`n\` elements from the list.`,
241
- }, {
242
- key: 'after',
243
- value: 'String',
240
+ Takes the \`first\`: \`n\` elements from the list.`,
241
+ }, {
242
+ key: 'after',
243
+ value: 'String',
244
244
  comment: `
245
245
  For **forward cursor** pagination
246
- \`after\` this \`cursor\`.`,
247
- }, {
248
- key: 'last',
249
- value: 'Int',
246
+ \`after\` this \`cursor\`.`,
247
+ }, {
248
+ key: 'last',
249
+ value: 'Int',
250
250
  comment: `
251
251
  For **backward cursor** pagination
252
- Takes the \`last\`: \`n\` elements from the list.`,
253
- }, {
254
- key: 'before',
255
- value: 'String',
252
+ Takes the \`last\`: \`n\` elements from the list.`,
253
+ }, {
254
+ key: 'before',
255
+ value: 'String',
256
256
  comment: `
257
257
  For **backward cursor** pagination
258
- \`before\` this \`cursor\`.`,
259
- });
260
- }
261
- const getSingleEntityKey = toCamelCase(getMetaType(meta));
262
- root_query.fields.push({
263
- key: getSingleEntityKey,
264
- args: [argId],
265
- value: `${getMetaType(meta)}`,
266
- comment: `Get \`${getMetaType(meta)}\` entity`,
267
- });
268
- root[getSingleEntityKey] = handleRequestWithDataApiContext(async (dApi, response, setResult, arg1, req) => {
269
- await dApi.get({
270
- ...response,
271
- success: (y) => {
272
- currentType.query.resultProcessors.forEach((z) => z(y));
273
- setResult(y);
274
- },
275
- }, arg1.id);
276
- });
277
- resolversQuery[getSingleEntityKey] = (origItem, args, req, gqlInfo) => root[getSingleEntityKey](args, req, gqlInfo);
278
- // Connection (v1 items, v2 edges)
279
- const connectionKey = `${getMetaType(meta)}Connection`;
280
- root_query.fields.push({
281
- key,
282
- args: queryArgsConnection,
283
- value: connectionKey,
284
- comment: `List all \`${getMetaType(meta)}\` entity (with pagination, sorting and filtering)`,
285
- });
286
- const connection = upsertTypes(connectionKey, 'type');
287
- const totalCountKey = 'totalCount';
288
- connection.fields.push({
289
- key: totalCountKey,
290
- value: 'Int!',
291
- });
292
- if (v2ConnectionAndPagination) {
293
- connection.fields.push({
294
- key: 'edges',
295
- value: `[${getMetaType(meta)}Edge!]!`,
296
- });
297
- }
298
- const itemsKey = 'items';
299
- connection.fields.push({
300
- key: itemsKey,
301
- value: `[${getMetaType(meta)}!]!`,
302
- });
303
- if (v2ConnectionAndPagination) {
304
- connection.fields.push({
305
- key: 'pageInfo',
306
- value: `PageInfo!`,
307
- });
308
- }
309
- if (v2ConnectionAndPagination) {
310
- const edge = upsertTypes(`${getMetaType(meta)}Edge`, 'type');
311
- edge.fields.push({
312
- key: 'node',
313
- value: `${getMetaType(meta)}!`,
314
- });
315
- const cursorKey = 'cursor';
316
- edge.fields.push({
317
- key: cursorKey,
318
- value: `String!`,
319
- });
320
- }
321
- root[key] = handleRequestWithDataApiContext(async (dApi, response, setResult, arg1, meta) => {
322
- setResult({
323
- [itemsKey]: createResultPromise(async (response, setResult) => {
324
- await dApi.getArray({
325
- ...response,
326
- success: (x) => {
327
- setResult(x.map((y) => {
328
- currentType.query.resultProcessors.forEach((z) => z(y));
329
- return y;
330
- }));
331
- },
332
- }, {
333
- get: bridgeQueryOptionsToDataApiGet(arg1),
334
- }, translateWhereToRestBody(meta.fields, arg1));
335
- }),
336
- [totalCountKey]: createResultPromise(async (response, setResult) => {
337
- await dApi.count({
338
- ...response,
339
- success: (x) => setResult(x.count),
340
- }, {
341
- get: bridgeQueryOptionsToDataApiGet(arg1),
342
- }, translateWhereToRestBody(meta.fields, arg1));
343
- }),
344
- });
345
- });
346
- resolversQuery[key] = (origItem, args, req, gqlInfo) => {
347
- return root[key](args, req, gqlInfo);
348
- };
349
- // Mutation
350
- const root_mutation = upsertTypes('Mutation', 'type', -9);
351
- const checkCanExist = (rule) => rule !== false &&
352
- !(rule === undefined &&
353
- (meta.options.allowApiCrud === false ||
354
- meta.options.allowApiCrud === undefined));
355
- if (checkCanExist(meta.options.allowApiInsert)) {
356
- // create
357
- const createResolverKey = `create${getMetaType(meta)}`;
358
- const createInput = `Create${getMetaType(meta)}Input`;
359
- const createPayload = `Create${getMetaType(meta)}Payload`;
360
- root_mutation.fields.push({
361
- key: createResolverKey,
362
- args: [
363
- { key: 'input', value: `${createInput}!` },
364
- argClientMutationId,
365
- ],
366
- value: `${createPayload}`,
367
- comment: `Create a new \`${getMetaType(meta)}\``,
368
- });
369
- currentType.mutation.create.input = upsertTypes(createInput, 'input');
370
- currentType.mutation.create.payload = upsertTypes(createPayload);
371
- currentType.mutation.create.payload.fields.push({
372
- key: `${toCamelCase(getMetaType(meta))}`,
373
- value: getMetaType(meta),
374
- }, argErrorDetail, argClientMutationId);
375
- root[createResolverKey] = handleMutationWithErrors(async (dApi, response, setResult, arg1, req) => {
376
- await dApi.post({
377
- ...response,
378
- created: (y) => {
379
- currentType.query.resultProcessors.forEach((z) => z(y));
380
- setResult({
381
- [toCamelCase(getMetaType(meta))]: y,
382
- });
383
- },
384
- }, arg1.input);
385
- });
386
- resolversMutation[createResolverKey] = (origItem, args, req, gqlInfo) => root[createResolverKey](args, req, gqlInfo);
387
- }
388
- if (checkCanExist(meta.options.allowApiUpdate)) {
389
- // update
390
- const updateInput = `Update${getMetaType(meta)}Input`;
391
- const updatePayload = `Update${getMetaType(meta)}Payload`;
392
- const updateResolverKey = `update${getMetaType(meta)}`;
393
- root_mutation.fields.push({
394
- key: updateResolverKey,
395
- args: [
396
- argId,
397
- { key: 'patch', value: `${updateInput}!` },
398
- argClientMutationId,
399
- ],
400
- value: `${updatePayload}`,
401
- comment: `Update a \`${getMetaType(meta)}\``,
402
- });
403
- currentType.mutation.update.input = upsertTypes(updateInput, 'input');
404
- currentType.mutation.update.payload = upsertTypes(updatePayload);
405
- currentType.mutation.update.payload.fields.push({
406
- key: `${toCamelCase(getMetaType(meta))}`,
407
- value: `${getMetaType(meta)}`,
408
- }, argErrorDetail, argClientMutationId);
409
- root[updateResolverKey] = handleMutationWithErrors(async (dApi, response, setResult, arg1, req) => {
410
- await dApi.put({
411
- ...response,
412
- success: (y) => {
413
- currentType.query.resultProcessors.forEach((z) => z(y));
414
- setResult({
415
- [toCamelCase(getMetaType(meta))]: y,
416
- });
417
- },
418
- }, arg1.id, arg1.patch);
419
- });
420
- resolversMutation[updateResolverKey] = (origItem, args, req, gqlInfo) => root[updateResolverKey](args, req, gqlInfo);
421
- }
422
- if (checkCanExist(meta.options.allowApiDelete)) {
423
- // delete
424
- const deletePayload = `Delete${getMetaType(meta)}Payload`;
425
- const deleteResolverKey = `delete${getMetaType(meta)}`;
426
- root_mutation.fields.push({
427
- key: deleteResolverKey,
428
- args: [argId, argClientMutationId],
429
- value: `${deletePayload}`,
430
- comment: `Delete a \`${getMetaType(meta)}\``,
431
- });
432
- currentType.mutation.delete.payload = upsertTypes(deletePayload);
433
- const deletedResultKey = `id`;
434
- currentType.mutation.delete.payload.fields.push({
435
- key: deletedResultKey,
436
- value: 'ID',
437
- }, argErrorDetail, argClientMutationId);
438
- root[deleteResolverKey] = handleMutationWithErrors(async (dApi, response, setResult, arg1, req) => {
439
- await dApi.delete({
440
- ...response,
441
- deleted: () => {
442
- setResult({ [deletedResultKey]: arg1.id });
443
- },
444
- }, arg1.id);
445
- });
446
- resolversMutation[deleteResolverKey] = (origItem, args, req, gqlInfo) => root[deleteResolverKey](args, req, gqlInfo);
447
- }
448
- const whereTypeFields = [];
449
- for (const f of meta.fields) {
450
- if (f.options.includeInApi === false)
451
- continue;
452
- let type = 'String';
453
- switch (f.valueType) {
454
- case Boolean:
455
- type = 'Boolean';
456
- break;
457
- case Number:
458
- {
459
- if (f.valueConverter?.fieldTypeInDb === 'integer' ||
460
- f.valueConverter?.fieldTypeInDb === 'autoincrement')
461
- type = 'Int';
462
- else
463
- type = 'Float';
464
- }
465
- break;
466
- }
467
- const ref = entities.find((i) => i.entityType === f.valueType);
468
- currentType.query.resultProcessors.push((r) => {
469
- r[nodeIdKey] = () => getMetaType(meta) + ':' + meta.idMetadata.getId(r);
470
- });
471
- if (ref !== undefined) {
472
- // will do: Task.category
473
- currentType.fields.push({
474
- key: f.key,
475
- value: `${getMetaType(ref)}${f.allowNull ? '' : '!'}`,
476
- comment: f.caption,
477
- });
478
- const refKey = ref.key;
479
- currentType.query.resultProcessors.push((r) => {
480
- const val = r[f.key];
481
- if (val === null || val === undefined)
482
- return null;
483
- r[f.key] = async (args, req, gqlInfo) => {
484
- const queryResult = await (await root[refKey]({
485
- ...args.where,
486
- where: { id: { eq: val } },
487
- options: { limit: 1 },
488
- }, req, gqlInfo)).items();
489
- if (queryResult.length > 0)
490
- return queryResult[0];
491
- return null;
492
- };
493
- });
494
- // will do: Category.tasks (actually: Category.tasksOfcategory & tasksOfcategory2)
495
- const refT = upsertTypes(getMetaType(ref), 'type_impl_node');
496
- const keyOf = key + 'Of' + f.key;
497
- refT.fields.push({
498
- key: keyOf,
499
- args: queryArgsConnection,
500
- value: connectionKey,
501
- order: 10,
502
- comment: `List all \`${getMetaType(meta)}\` of \`${refKey}\``,
503
- });
504
- refT.query.resultProcessors.push((r) => {
505
- const val = r.id;
506
- r[keyOf] = async (args, req, gqlInfo) => {
507
- return await root[key]({
508
- where: { ...args.where, [f.key]: { eq: val } },
509
- options: { ...args.limit, ...args.page, ...args.orderBy },
510
- }, req, gqlInfo);
511
- };
512
- });
513
- }
514
- else {
515
- currentType.fields.push({
516
- key: f.key,
517
- value: `${type}${f.allowNull ? '' : '!'}`,
518
- comment: f.caption,
519
- });
520
- }
521
- // sorting
522
- if (!f.isServerExpression)
523
- orderByFields.push(`${f.key}: OrderByDirection`);
524
- // helper
525
- const it_is_not_at_ref = ref === undefined;
526
- // where
527
- if (it_is_not_at_ref && !f.isServerExpression) {
528
- whereTypeFields.push(`${f.key}: Where${type}${f.allowNull ? 'Nullable' : ''}`);
529
- }
530
- const includeInUpdateOrInsert = f.options.allowApiUpdate !== false;
531
- const updateType = it_is_not_at_ref ? type : 'ID';
532
- if (includeInUpdateOrInsert) {
533
- // create
534
- if (currentType.mutation.create.input)
535
- currentType.mutation.create.input.fields.push({
536
- key: f.key,
537
- value: updateType,
538
- });
539
- // update
540
- if (currentType.mutation.update.input)
541
- currentType.mutation.update.input.fields.push({
542
- key: f.key,
543
- value: updateType,
544
- });
545
- }
546
- }
547
- currentType.query.orderBy.push(blockFormat({
548
- prefix: `input ${key}OrderBy`,
549
- data: orderByFields,
550
- comment: `OrderBy options for \`${key}\``,
551
- }));
552
- whereTypeFields.push(`OR: [${key}Where!]`);
553
- if (andImplementation)
554
- whereTypeFields.push(`AND: [${key}Where!]`);
555
- currentType.query.whereType.push(blockFormat({
556
- prefix: `input ${key}Where`,
557
- data: whereTypeFields,
558
- comment: `Where options for \`${key}\``,
559
- }));
560
- }
561
- }
562
- // Add the node interface at the end
563
- const nodeKey = 'node';
564
- root_query.fields.push({
565
- key: nodeKey,
566
- args: [argNodeId],
567
- value: `Node`,
568
- comment: `Grab any Remult entity given it's globally unique \`ID\``,
569
- });
570
- if (v2ConnectionAndPagination) {
571
- const pageInfo = upsertTypes('PageInfo', 'type', 30);
572
- pageInfo.fields.push({ key: 'endCursor', value: 'String!' });
573
- pageInfo.fields.push({ key: 'hasNextPage', value: 'Boolean!' });
574
- pageInfo.fields.push({ key: 'hasPreviousPage', value: 'Boolean!' });
575
- pageInfo.fields.push({ key: 'startCursor', value: 'String!' });
576
- }
577
- resolversQuery[nodeKey] = (origItem, args, req, gqlInfo) => root[nodeKey](args, req, gqlInfo);
578
- root[nodeKey] = async (args, req, gqlInfo) => {
579
- const nodeId = args.nodeId;
580
- const sp = nodeId.split(':');
581
- const r = await root[toCamelCase(sp[0])]({
582
- id: sp[1],
583
- }, req, gqlInfo);
584
- r.__typename = sp[0];
585
- return r;
586
- };
587
- const orderByDirection = upsertTypes('OrderByDirection', 'enum', 30);
588
- orderByDirection.comment = `Determines the order of returned elements`;
589
- orderByDirection.fields.push({
590
- key: 'ASC',
591
- value: { Enum: true },
592
- comment: 'Sort data in ascending order',
593
- });
594
- orderByDirection.fields.push({
595
- key: 'DESC',
596
- value: { Enum: true },
597
- comment: 'Sort data in descending order',
598
- });
599
- const nodeInterface = upsertTypes('Node', 'interface', 31);
600
- nodeInterface.comment = `Node interface of remult entities (eg: nodeId: \`Task:1\` so \`__typename:id\`)`;
601
- nodeInterface.fields.push(argNodeId);
602
- upsertUnion(argErrorDetail.value, ['ValidationError', 'ForbiddenError', 'NotFoundError'], 32);
603
- const errorInterface = upsertTypes('Error', 'interface', 33);
604
- errorInterface.comment = `Error interface of remult entities`;
605
- errorInterface.fields.push({
606
- key: 'message',
607
- value: 'String!',
608
- });
609
- const validationErrorInterface = upsertTypes('ValidationError', 'type_impl_error', 34);
610
- validationErrorInterface.comment = `Validation Error`;
611
- validationErrorInterface.fields.push({
612
- key: 'message',
613
- value: 'String!',
614
- });
615
- validationErrorInterface.fields.push({
616
- key: 'modelState',
617
- value: '[ValidationErrorModelState!]!',
618
- });
619
- const validationErrorModelStateInterface = upsertTypes('ValidationErrorModelState', 'type', 34);
620
- validationErrorModelStateInterface.comment = `Validation Error Model State`;
621
- validationErrorModelStateInterface.fields.push({
622
- key: 'field',
623
- value: 'String!',
624
- });
625
- validationErrorModelStateInterface.fields.push({
626
- key: 'message',
627
- value: 'String!',
628
- });
629
- // progress: () => { },
630
- const forbiddenErrorInterface = upsertTypes('ForbiddenError', 'type_impl_error', 34);
631
- forbiddenErrorInterface.comment = `Forbidden Error`;
632
- forbiddenErrorInterface.fields.push({
633
- key: 'message',
634
- value: 'String!',
635
- });
636
- const notFoundErrorInterface = upsertTypes('NotFoundError', 'type_impl_error', 34);
637
- notFoundErrorInterface.comment = `Not Found Error`;
638
- notFoundErrorInterface.fields.push({
639
- key: 'message',
640
- value: 'String!',
641
- });
642
- return {
643
- resolvers,
644
- rootValue: root,
645
- typeDefs: `${types
646
- .sort((a, b) => (a.order ? a.order : 0) - (b.order ? b.order : 0))
647
- .map(({ key, kind, fields, query, comment }) => {
648
- const { orderBy, whereType, whereTypeSubFields } = query;
649
- let prefix = `${kind} ${key}`;
650
- if (kind === 'type_impl_node') {
651
- prefix = `type ${key} implements Node`;
652
- }
653
- if (kind === 'type_impl_error') {
654
- prefix = `type ${key} implements Error`;
655
- }
656
- const type = kind === 'union'
657
- ? `union ${key} = ${fields.map((field) => field.key).join(' | ')}`
658
- : blockFormat({
659
- prefix,
660
- data: fields
661
- .sort((a, b) => (a.order ? a.order : 0) - (b.order ? b.order : 0))
662
- .map((field) => fieldFormat(field)),
663
- comment: comment ?? `The ${kind} for \`${key}\``,
664
- });
665
- const orderByStr = orderBy.length > 0 ? `\n\n${orderBy.join('\n\n')}` : ``;
666
- const whereTypeStr = whereType.length > 0 ? `\n\n${whereType.join('\n\n')}` : ``;
667
- const whereTypeSubFieldsStr = whereTypeSubFields.length > 0
668
- ? `\n\n${whereTypeSubFields.join('\n\n')}`
669
- : ``;
670
- return `${type}${orderByStr}${whereTypeStr}${whereTypeSubFieldsStr}`;
671
- })
258
+ \`before\` this \`cursor\`.`,
259
+ });
260
+ }
261
+ const getSingleEntityKey = toCamelCase(getMetaType(meta));
262
+ root_query.fields.push({
263
+ key: getSingleEntityKey,
264
+ args: [argId],
265
+ value: `${getMetaType(meta)}`,
266
+ comment: `Get \`${getMetaType(meta)}\` entity`,
267
+ });
268
+ root[getSingleEntityKey] = handleRequestWithDataApiContext(async (dApi, response, setResult, arg1, req) => {
269
+ await dApi.get({
270
+ ...response,
271
+ success: (y) => {
272
+ currentType.query.resultProcessors.forEach((z) => z(y));
273
+ setResult(y);
274
+ },
275
+ }, arg1.id);
276
+ });
277
+ resolversQuery[getSingleEntityKey] = (origItem, args, req, gqlInfo) => root[getSingleEntityKey](args, req, gqlInfo);
278
+ // Connection (v1 items, v2 edges)
279
+ const connectionKey = `${getMetaType(meta)}Connection`;
280
+ root_query.fields.push({
281
+ key,
282
+ args: queryArgsConnection,
283
+ value: connectionKey,
284
+ comment: `List all \`${getMetaType(meta)}\` entity (with pagination, sorting and filtering)`,
285
+ });
286
+ const connection = upsertTypes(connectionKey, 'type');
287
+ const totalCountKey = 'totalCount';
288
+ connection.fields.push({
289
+ key: totalCountKey,
290
+ value: 'Int!',
291
+ });
292
+ if (v2ConnectionAndPagination) {
293
+ connection.fields.push({
294
+ key: 'edges',
295
+ value: `[${getMetaType(meta)}Edge!]!`,
296
+ });
297
+ }
298
+ const itemsKey = 'items';
299
+ connection.fields.push({
300
+ key: itemsKey,
301
+ value: `[${getMetaType(meta)}!]!`,
302
+ });
303
+ if (v2ConnectionAndPagination) {
304
+ connection.fields.push({
305
+ key: 'pageInfo',
306
+ value: `PageInfo!`,
307
+ });
308
+ }
309
+ if (v2ConnectionAndPagination) {
310
+ const edge = upsertTypes(`${getMetaType(meta)}Edge`, 'type');
311
+ edge.fields.push({
312
+ key: 'node',
313
+ value: `${getMetaType(meta)}!`,
314
+ });
315
+ const cursorKey = 'cursor';
316
+ edge.fields.push({
317
+ key: cursorKey,
318
+ value: `String!`,
319
+ });
320
+ }
321
+ root[key] = handleRequestWithDataApiContext(async (dApi, response, setResult, arg1, meta) => {
322
+ setResult({
323
+ [itemsKey]: createResultPromise(async (response, setResult) => {
324
+ await dApi.getArray({
325
+ ...response,
326
+ success: (x) => {
327
+ setResult(x.map((y) => {
328
+ currentType.query.resultProcessors.forEach((z) => z(y));
329
+ return y;
330
+ }));
331
+ },
332
+ }, {
333
+ get: bridgeQueryOptionsToDataApiGet(arg1),
334
+ }, translateWhereToRestBody(meta.fields, arg1));
335
+ }),
336
+ [totalCountKey]: createResultPromise(async (response, setResult) => {
337
+ await dApi.count({
338
+ ...response,
339
+ success: (x) => setResult(x.count),
340
+ }, {
341
+ get: bridgeQueryOptionsToDataApiGet(arg1),
342
+ }, translateWhereToRestBody(meta.fields, arg1));
343
+ }),
344
+ });
345
+ });
346
+ resolversQuery[key] = (origItem, args, req, gqlInfo) => {
347
+ return root[key](args, req, gqlInfo);
348
+ };
349
+ // Mutation
350
+ const root_mutation = upsertTypes('Mutation', 'type', -9);
351
+ const checkCanExist = (rule) => rule !== false &&
352
+ !(rule === undefined &&
353
+ (meta.options.allowApiCrud === false ||
354
+ meta.options.allowApiCrud === undefined));
355
+ if (checkCanExist(meta.options.allowApiInsert)) {
356
+ // create
357
+ const createResolverKey = `create${getMetaType(meta)}`;
358
+ const createInput = `Create${getMetaType(meta)}Input`;
359
+ const createPayload = `Create${getMetaType(meta)}Payload`;
360
+ root_mutation.fields.push({
361
+ key: createResolverKey,
362
+ args: [
363
+ { key: 'input', value: `${createInput}!` },
364
+ argClientMutationId,
365
+ ],
366
+ value: `${createPayload}`,
367
+ comment: `Create a new \`${getMetaType(meta)}\``,
368
+ });
369
+ currentType.mutation.create.input = upsertTypes(createInput, 'input');
370
+ currentType.mutation.create.payload = upsertTypes(createPayload);
371
+ currentType.mutation.create.payload.fields.push({
372
+ key: `${toCamelCase(getMetaType(meta))}`,
373
+ value: getMetaType(meta),
374
+ }, argErrorDetail, argClientMutationId);
375
+ root[createResolverKey] = handleMutationWithErrors(async (dApi, response, setResult, arg1, req) => {
376
+ await dApi.post({
377
+ ...response,
378
+ created: (y) => {
379
+ currentType.query.resultProcessors.forEach((z) => z(y));
380
+ setResult({
381
+ [toCamelCase(getMetaType(meta))]: y,
382
+ });
383
+ },
384
+ }, arg1.input);
385
+ });
386
+ resolversMutation[createResolverKey] = (origItem, args, req, gqlInfo) => root[createResolverKey](args, req, gqlInfo);
387
+ }
388
+ if (checkCanExist(meta.options.allowApiUpdate)) {
389
+ // update
390
+ const updateInput = `Update${getMetaType(meta)}Input`;
391
+ const updatePayload = `Update${getMetaType(meta)}Payload`;
392
+ const updateResolverKey = `update${getMetaType(meta)}`;
393
+ root_mutation.fields.push({
394
+ key: updateResolverKey,
395
+ args: [
396
+ argId,
397
+ { key: 'patch', value: `${updateInput}!` },
398
+ argClientMutationId,
399
+ ],
400
+ value: `${updatePayload}`,
401
+ comment: `Update a \`${getMetaType(meta)}\``,
402
+ });
403
+ currentType.mutation.update.input = upsertTypes(updateInput, 'input');
404
+ currentType.mutation.update.payload = upsertTypes(updatePayload);
405
+ currentType.mutation.update.payload.fields.push({
406
+ key: `${toCamelCase(getMetaType(meta))}`,
407
+ value: `${getMetaType(meta)}`,
408
+ }, argErrorDetail, argClientMutationId);
409
+ root[updateResolverKey] = handleMutationWithErrors(async (dApi, response, setResult, arg1, req) => {
410
+ await dApi.put({
411
+ ...response,
412
+ success: (y) => {
413
+ currentType.query.resultProcessors.forEach((z) => z(y));
414
+ setResult({
415
+ [toCamelCase(getMetaType(meta))]: y,
416
+ });
417
+ },
418
+ }, arg1.id, arg1.patch);
419
+ });
420
+ resolversMutation[updateResolverKey] = (origItem, args, req, gqlInfo) => root[updateResolverKey](args, req, gqlInfo);
421
+ }
422
+ if (checkCanExist(meta.options.allowApiDelete)) {
423
+ // delete
424
+ const deletePayload = `Delete${getMetaType(meta)}Payload`;
425
+ const deleteResolverKey = `delete${getMetaType(meta)}`;
426
+ root_mutation.fields.push({
427
+ key: deleteResolverKey,
428
+ args: [argId, argClientMutationId],
429
+ value: `${deletePayload}`,
430
+ comment: `Delete a \`${getMetaType(meta)}\``,
431
+ });
432
+ currentType.mutation.delete.payload = upsertTypes(deletePayload);
433
+ const deletedResultKey = `id`;
434
+ currentType.mutation.delete.payload.fields.push({
435
+ key: deletedResultKey,
436
+ value: 'ID',
437
+ }, argErrorDetail, argClientMutationId);
438
+ root[deleteResolverKey] = handleMutationWithErrors(async (dApi, response, setResult, arg1, req) => {
439
+ await dApi.delete({
440
+ ...response,
441
+ deleted: () => {
442
+ setResult({ [deletedResultKey]: arg1.id });
443
+ },
444
+ }, arg1.id);
445
+ });
446
+ resolversMutation[deleteResolverKey] = (origItem, args, req, gqlInfo) => root[deleteResolverKey](args, req, gqlInfo);
447
+ }
448
+ const whereTypeFields = [];
449
+ for (const f of meta.fields) {
450
+ if (f.options.includeInApi === false)
451
+ continue;
452
+ let type = 'String';
453
+ switch (f.valueType) {
454
+ case Boolean:
455
+ type = 'Boolean';
456
+ break;
457
+ case Number:
458
+ {
459
+ if (f.valueConverter?.fieldTypeInDb === 'integer' ||
460
+ f.valueConverter?.fieldTypeInDb === 'autoincrement')
461
+ type = 'Int';
462
+ else
463
+ type = 'Float';
464
+ }
465
+ break;
466
+ }
467
+ const ref = entities.find((i) => i.entityType === f.valueType);
468
+ currentType.query.resultProcessors.push((r) => {
469
+ r[nodeIdKey] = () => getMetaType(meta) + ':' + meta.idMetadata.getId(r);
470
+ });
471
+ if (ref !== undefined) {
472
+ // will do: Task.category
473
+ currentType.fields.push({
474
+ key: f.key,
475
+ value: `${getMetaType(ref)}${f.allowNull ? '' : '!'}`,
476
+ comment: f.caption,
477
+ });
478
+ const refKey = ref.key;
479
+ currentType.query.resultProcessors.push((r) => {
480
+ const val = r[f.key];
481
+ if (val === null || val === undefined)
482
+ return null;
483
+ r[f.key] = async (args, req, gqlInfo) => {
484
+ const queryResult = await (await root[refKey]({
485
+ ...args.where,
486
+ where: { id: { eq: val } },
487
+ options: { limit: 1 },
488
+ }, req, gqlInfo)).items();
489
+ if (queryResult.length > 0)
490
+ return queryResult[0];
491
+ return null;
492
+ };
493
+ });
494
+ // will do: Category.tasks (actually: Category.tasksOfcategory & tasksOfcategory2)
495
+ const refT = upsertTypes(getMetaType(ref), 'type_impl_node');
496
+ const keyOf = key + 'Of' + f.key;
497
+ refT.fields.push({
498
+ key: keyOf,
499
+ args: queryArgsConnection,
500
+ value: connectionKey,
501
+ order: 10,
502
+ comment: `List all \`${getMetaType(meta)}\` of \`${refKey}\``,
503
+ });
504
+ refT.query.resultProcessors.push((r) => {
505
+ const val = r.id;
506
+ r[keyOf] = async (args, req, gqlInfo) => {
507
+ return await root[key]({
508
+ where: { ...args.where, [f.key]: { eq: val } },
509
+ options: { ...args.limit, ...args.page, ...args.orderBy },
510
+ }, req, gqlInfo);
511
+ };
512
+ });
513
+ }
514
+ else {
515
+ currentType.fields.push({
516
+ key: f.key,
517
+ value: `${type}${f.allowNull ? '' : '!'}`,
518
+ comment: f.caption,
519
+ });
520
+ }
521
+ // sorting
522
+ if (!f.isServerExpression)
523
+ orderByFields.push(`${f.key}: OrderByDirection`);
524
+ // helper
525
+ const it_is_not_at_ref = ref === undefined;
526
+ // where
527
+ if (it_is_not_at_ref && !f.isServerExpression) {
528
+ whereTypeFields.push(`${f.key}: Where${type}${f.allowNull ? 'Nullable' : ''}`);
529
+ }
530
+ const includeInUpdateOrInsert = f.options.allowApiUpdate !== false;
531
+ const updateType = it_is_not_at_ref ? type : 'ID';
532
+ if (includeInUpdateOrInsert) {
533
+ // create
534
+ if (currentType.mutation.create.input)
535
+ currentType.mutation.create.input.fields.push({
536
+ key: f.key,
537
+ value: updateType,
538
+ });
539
+ // update
540
+ if (currentType.mutation.update.input)
541
+ currentType.mutation.update.input.fields.push({
542
+ key: f.key,
543
+ value: updateType,
544
+ });
545
+ }
546
+ }
547
+ currentType.query.orderBy.push(blockFormat({
548
+ prefix: `input ${key}OrderBy`,
549
+ data: orderByFields,
550
+ comment: `OrderBy options for \`${key}\``,
551
+ }));
552
+ whereTypeFields.push(`OR: [${key}Where!]`);
553
+ if (andImplementation)
554
+ whereTypeFields.push(`AND: [${key}Where!]`);
555
+ currentType.query.whereType.push(blockFormat({
556
+ prefix: `input ${key}Where`,
557
+ data: whereTypeFields,
558
+ comment: `Where options for \`${key}\``,
559
+ }));
560
+ }
561
+ }
562
+ // Add the node interface at the end
563
+ const nodeKey = 'node';
564
+ root_query.fields.push({
565
+ key: nodeKey,
566
+ args: [argNodeId],
567
+ value: `Node`,
568
+ comment: `Grab any Remult entity given it's globally unique \`ID\``,
569
+ });
570
+ if (v2ConnectionAndPagination) {
571
+ const pageInfo = upsertTypes('PageInfo', 'type', 30);
572
+ pageInfo.fields.push({ key: 'endCursor', value: 'String!' });
573
+ pageInfo.fields.push({ key: 'hasNextPage', value: 'Boolean!' });
574
+ pageInfo.fields.push({ key: 'hasPreviousPage', value: 'Boolean!' });
575
+ pageInfo.fields.push({ key: 'startCursor', value: 'String!' });
576
+ }
577
+ resolversQuery[nodeKey] = (origItem, args, req, gqlInfo) => root[nodeKey](args, req, gqlInfo);
578
+ root[nodeKey] = async (args, req, gqlInfo) => {
579
+ const nodeId = args.nodeId;
580
+ const sp = nodeId.split(':');
581
+ const r = await root[toCamelCase(sp[0])]({
582
+ id: sp[1],
583
+ }, req, gqlInfo);
584
+ r.__typename = sp[0];
585
+ return r;
586
+ };
587
+ const orderByDirection = upsertTypes('OrderByDirection', 'enum', 30);
588
+ orderByDirection.comment = `Determines the order of returned elements`;
589
+ orderByDirection.fields.push({
590
+ key: 'ASC',
591
+ value: { Enum: true },
592
+ comment: 'Sort data in ascending order',
593
+ });
594
+ orderByDirection.fields.push({
595
+ key: 'DESC',
596
+ value: { Enum: true },
597
+ comment: 'Sort data in descending order',
598
+ });
599
+ const nodeInterface = upsertTypes('Node', 'interface', 31);
600
+ nodeInterface.comment = `Node interface of remult entities (eg: nodeId: \`Task:1\` so \`__typename:id\`)`;
601
+ nodeInterface.fields.push(argNodeId);
602
+ upsertUnion(argErrorDetail.value, ['ValidationError', 'ForbiddenError', 'NotFoundError'], 32);
603
+ const errorInterface = upsertTypes('Error', 'interface', 33);
604
+ errorInterface.comment = `Error interface of remult entities`;
605
+ errorInterface.fields.push({
606
+ key: 'message',
607
+ value: 'String!',
608
+ });
609
+ const validationErrorInterface = upsertTypes('ValidationError', 'type_impl_error', 34);
610
+ validationErrorInterface.comment = `Validation Error`;
611
+ validationErrorInterface.fields.push({
612
+ key: 'message',
613
+ value: 'String!',
614
+ });
615
+ validationErrorInterface.fields.push({
616
+ key: 'modelState',
617
+ value: '[ValidationErrorModelState!]!',
618
+ });
619
+ const validationErrorModelStateInterface = upsertTypes('ValidationErrorModelState', 'type', 34);
620
+ validationErrorModelStateInterface.comment = `Validation Error Model State`;
621
+ validationErrorModelStateInterface.fields.push({
622
+ key: 'field',
623
+ value: 'String!',
624
+ });
625
+ validationErrorModelStateInterface.fields.push({
626
+ key: 'message',
627
+ value: 'String!',
628
+ });
629
+ // progress: () => { },
630
+ const forbiddenErrorInterface = upsertTypes('ForbiddenError', 'type_impl_error', 34);
631
+ forbiddenErrorInterface.comment = `Forbidden Error`;
632
+ forbiddenErrorInterface.fields.push({
633
+ key: 'message',
634
+ value: 'String!',
635
+ });
636
+ const notFoundErrorInterface = upsertTypes('NotFoundError', 'type_impl_error', 34);
637
+ notFoundErrorInterface.comment = `Not Found Error`;
638
+ notFoundErrorInterface.fields.push({
639
+ key: 'message',
640
+ value: 'String!',
641
+ });
642
+ return {
643
+ resolvers,
644
+ rootValue: root,
645
+ typeDefs: `${types
646
+ .sort((a, b) => (a.order ? a.order : 0) - (b.order ? b.order : 0))
647
+ .map(({ key, kind, fields, query, comment }) => {
648
+ const { orderBy, whereType, whereTypeSubFields } = query;
649
+ let prefix = `${kind} ${key}`;
650
+ if (kind === 'type_impl_node') {
651
+ prefix = `type ${key} implements Node`;
652
+ }
653
+ if (kind === 'type_impl_error') {
654
+ prefix = `type ${key} implements Error`;
655
+ }
656
+ const type = kind === 'union'
657
+ ? `union ${key} = ${fields.map((field) => field.key).join(' | ')}`
658
+ : blockFormat({
659
+ prefix,
660
+ data: fields
661
+ .sort((a, b) => (a.order ? a.order : 0) - (b.order ? b.order : 0))
662
+ .map((field) => fieldFormat(field)),
663
+ comment: comment ?? `The ${kind} for \`${key}\``,
664
+ });
665
+ const orderByStr = orderBy.length > 0 ? `\n\n${orderBy.join('\n\n')}` : ``;
666
+ const whereTypeStr = whereType.length > 0 ? `\n\n${whereType.join('\n\n')}` : ``;
667
+ const whereTypeSubFieldsStr = whereTypeSubFields.length > 0
668
+ ? `\n\n${whereTypeSubFields.join('\n\n')}`
669
+ : ``;
670
+ return `${type}${orderByStr}${whereTypeStr}${whereTypeSubFieldsStr}`;
671
+ })
672
672
  .join(`\n\n`)}
673
- `,
674
- };
675
- }
676
- // For cursor pagination (v2)
677
- // function checkPaginationArgs(args: any) {
678
- // let paginationPage = !!args.limit ? 1 : 0
679
- // paginationPage += !!args.page ? 1 : 0
680
- // let paginationCursor = !!args.first ? 1 : 0
681
- // paginationCursor += !!args.after ? 1 : 0
682
- // paginationCursor += !!args.last ? 1 : 0
683
- // paginationCursor += !!args.before ? 1 : 0
684
- // if (paginationPage > 0 && paginationCursor > 0) {
685
- // throw new GraphQLError(
686
- // `You can't use \`limit,page\` and \`first,after,last,before\` at the same time. Choose your pagination style.`,
687
- // )
688
- // }
689
- // }
690
- function blockFormat(obj) {
691
- if (obj.data.length === 0) {
692
- return ``;
693
- }
673
+ `,
674
+ };
675
+ }
676
+ // For cursor pagination (v2)
677
+ // function checkPaginationArgs(args: any) {
678
+ // let paginationPage = !!args.limit ? 1 : 0
679
+ // paginationPage += !!args.page ? 1 : 0
680
+ // let paginationCursor = !!args.first ? 1 : 0
681
+ // paginationCursor += !!args.after ? 1 : 0
682
+ // paginationCursor += !!args.last ? 1 : 0
683
+ // paginationCursor += !!args.before ? 1 : 0
684
+ // if (paginationPage > 0 && paginationCursor > 0) {
685
+ // throw new GraphQLError(
686
+ // `You can't use \`limit,page\` and \`first,after,last,before\` at the same time. Choose your pagination style.`,
687
+ // )
688
+ // }
689
+ // }
690
+ function blockFormat(obj) {
691
+ if (obj.data.length === 0) {
692
+ return ``;
693
+ }
694
694
  const str = `${obj.prefix} {
695
695
  ${obj.data.join('\n ')}
696
- }`;
696
+ }`;
697
697
  let commentsStr = `"""
698
698
  ${obj.comment}
699
699
  """
700
- `;
701
- if (_removeComments) {
702
- commentsStr = ``;
703
- }
704
- return `${commentsStr}${str}`;
705
- }
706
- function argsFormat(args) {
707
- if (args) {
708
- return `(${args
709
- .map((arg) => {
700
+ `;
701
+ if (_removeComments) {
702
+ commentsStr = ``;
703
+ }
704
+ return `${commentsStr}${str}`;
705
+ }
706
+ function argsFormat(args) {
707
+ if (args) {
708
+ return `(${args
709
+ .map((arg) => {
710
710
  let strComment = `
711
711
  """
712
712
  ${arg.comment}
713
713
  """
714
- `;
715
- if (_removeComments || !arg.comment) {
716
- strComment = ``;
717
- }
718
- if (strComment) {
714
+ `;
715
+ if (_removeComments || !arg.comment) {
716
+ strComment = ``;
717
+ }
718
+ if (strComment) {
719
719
  return `${strComment} ${arg.key}: ${arg.value}
720
- `;
721
- }
722
- return `${arg.key}: ${arg.value}`;
723
- })
724
- .join(', ')})`;
725
- }
726
- return ``;
727
- }
728
- function fieldFormat(field) {
729
- // First, the comment
720
+ `;
721
+ }
722
+ return `${arg.key}: ${arg.value}`;
723
+ })
724
+ .join(', ')})`;
725
+ }
726
+ return ``;
727
+ }
728
+ function fieldFormat(field) {
729
+ // First, the comment
730
730
  let strComment = `"""
731
731
  ${field.comment}
732
732
  """
733
- `;
734
- if (_removeComments || !field.comment) {
735
- strComment = ``;
736
- }
737
- let key_value = `${field.key}${field.args ? `${argsFormat(field.args)}` : ``}: ${field.value}`;
738
- // It's an enum
739
- if (typeof field.value === 'object') {
740
- key_value = `${field.key}`;
741
- }
742
- return `${strComment} ${key_value}`;
743
- }
744
- function getMetaType(entityMeta) {
745
- return entityMeta.entityType.name;
746
- }
747
- function toCamelCase(str) {
748
- return str
749
- .split('')
750
- .map((c, i) => (i === 0 ? c.toLowerCase() : c))
751
- .join('');
752
- }
753
- function bridgeQueryOptionsToDataApiGet(arg1) {
754
- const { limit, page, orderBy, where } = arg1;
755
- return (key) => {
756
- if (limit && key === '_limit') {
757
- return limit;
758
- }
759
- if (page && key === '_page') {
760
- return page;
761
- }
762
- if (orderBy) {
763
- if (key === '_sort') {
764
- const sort_keys = [];
765
- Object.keys(orderBy).forEach((sort_key) => {
766
- sort_keys.push(sort_key);
767
- });
768
- if (sort_keys.length > 0) {
769
- return sort_keys.join(',');
770
- }
771
- }
772
- else if (key === '_order') {
773
- const sort_directions = [];
774
- Object.keys(orderBy).forEach((sort_key) => {
775
- const direction = orderBy[sort_key].toLowerCase();
776
- sort_directions.push(direction);
777
- });
778
- if (sort_directions.length > 0) {
779
- return sort_directions.join(',');
780
- }
781
- }
782
- }
783
- };
784
- }
785
- //@internal
786
- export function translateWhereToRestBody(fields, { where }) {
787
- if (!where)
788
- return undefined;
789
- const result = {};
790
- for (const field of fields) {
791
- if (field.includedInApi === false)
792
- continue;
793
- const condition = where[field.key];
794
- if (condition) {
795
- const tr = (key, what) => {
796
- const val = condition[key];
797
- if (val != undefined)
798
- what(val);
799
- };
800
- for (const op of ['gt', 'gte', 'lt', 'lte', 'ne', 'in']) {
801
- tr(op, (val) => (result[field.key + '.' + op] = val));
802
- }
803
- tr('nin', (x) => (result[field.key + '.ne'] = x));
804
- tr('eq', (x) => (result[field.key] = x));
805
- tr('contains', (x) => (result[field.key + '.contains'] = x));
806
- }
807
- }
808
- if (where.OR) {
809
- result.OR = where.OR.map((where) => translateWhereToRestBody(fields, { where }));
810
- }
811
- return result;
812
- }
733
+ `;
734
+ if (_removeComments || !field.comment) {
735
+ strComment = ``;
736
+ }
737
+ let key_value = `${field.key}${field.args ? `${argsFormat(field.args)}` : ``}: ${field.value}`;
738
+ // It's an enum
739
+ if (typeof field.value === 'object') {
740
+ key_value = `${field.key}`;
741
+ }
742
+ return `${strComment} ${key_value}`;
743
+ }
744
+ function getMetaType(entityMeta) {
745
+ return entityMeta.entityType.name;
746
+ }
747
+ function toCamelCase(str) {
748
+ return str
749
+ .split('')
750
+ .map((c, i) => (i === 0 ? c.toLowerCase() : c))
751
+ .join('');
752
+ }
753
+ function bridgeQueryOptionsToDataApiGet(arg1) {
754
+ const { limit, page, orderBy, where } = arg1;
755
+ return (key) => {
756
+ if (limit && key === '_limit') {
757
+ return limit;
758
+ }
759
+ if (page && key === '_page') {
760
+ return page;
761
+ }
762
+ if (orderBy) {
763
+ if (key === '_sort') {
764
+ const sort_keys = [];
765
+ Object.keys(orderBy).forEach((sort_key) => {
766
+ sort_keys.push(sort_key);
767
+ });
768
+ if (sort_keys.length > 0) {
769
+ return sort_keys.join(',');
770
+ }
771
+ }
772
+ else if (key === '_order') {
773
+ const sort_directions = [];
774
+ Object.keys(orderBy).forEach((sort_key) => {
775
+ const direction = orderBy[sort_key].toLowerCase();
776
+ sort_directions.push(direction);
777
+ });
778
+ if (sort_directions.length > 0) {
779
+ return sort_directions.join(',');
780
+ }
781
+ }
782
+ }
783
+ };
784
+ }
785
+ //@internal
786
+ export function translateWhereToRestBody(fields, { where }) {
787
+ if (!where)
788
+ return undefined;
789
+ const result = {};
790
+ for (const field of fields) {
791
+ if (field.includedInApi === false)
792
+ continue;
793
+ const condition = where[field.key];
794
+ if (condition) {
795
+ const tr = (key, what) => {
796
+ const val = condition[key];
797
+ if (val != undefined)
798
+ what(val);
799
+ };
800
+ for (const op of ['gt', 'gte', 'lt', 'lte', 'ne', 'in']) {
801
+ tr(op, (val) => (result[field.key + '.' + op] = val));
802
+ }
803
+ tr('nin', (x) => (result[field.key + '.ne'] = x));
804
+ tr('eq', (x) => (result[field.key] = x));
805
+ tr('contains', (x) => (result[field.key + '.contains'] = x));
806
+ }
807
+ }
808
+ if (where.OR) {
809
+ result.OR = where.OR.map((where) => translateWhereToRestBody(fields, { where }));
810
+ }
811
+ return result;
812
+ }