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.
- package/SseSubscriptionServer.d.ts +25 -25
- package/SseSubscriptionServer.js +145 -145
- package/ably.d.ts +13 -13
- package/ably.js +59 -59
- package/assign.d.ts +1 -1
- package/assign.js +9 -9
- package/classType.d.ts +3 -3
- package/classType.js +2 -2
- package/esm/SseSubscriptionServer.d.ts +25 -25
- package/esm/SseSubscriptionServer.js +107 -104
- package/esm/ably.d.ts +13 -13
- package/esm/ably.js +30 -28
- package/esm/assign.d.ts +1 -1
- package/esm/assign.js +5 -5
- package/esm/classType.d.ts +3 -3
- package/esm/classType.js +1 -1
- package/esm/graphql.d.ts +14 -14
- package/esm/graphql.js +785 -785
- package/esm/index.d.ts +31 -31
- package/esm/index.js +25 -25
- package/esm/inputTypes.d.ts +9 -9
- package/esm/inputTypes.js +9 -9
- package/esm/live-query/data-provider-live-query-storage.d.ts +23 -23
- package/esm/live-query/data-provider-live-query-storage.js +91 -93
- package/esm/myLog.d.ts +1 -1
- package/esm/myLog.js +5 -5
- package/esm/postgres/index.d.ts +2 -2
- package/esm/postgres/index.js +2 -2
- package/esm/postgres/postgres-data-provider.d.ts +36 -36
- package/esm/postgres/postgres-data-provider.js +126 -122
- package/esm/postgres/schema-builder.d.ts +19 -19
- package/esm/postgres/schema-builder.js +197 -196
- package/esm/remult-express.d.ts +9 -9
- package/esm/remult-express.js +26 -25
- package/esm/remult-fastify.d.ts +6 -6
- package/esm/remult-fastify.js +68 -68
- package/esm/remult-fresh.d.ts +17 -17
- package/esm/remult-fresh.js +26 -26
- package/esm/remult-knex/index.d.ts +30 -30
- package/esm/remult-knex/index.js +466 -460
- package/esm/remult-mongo.d.ts +24 -24
- package/esm/remult-mongo.js +269 -262
- package/esm/remult-next.d.ts +25 -25
- package/esm/remult-next.js +114 -114
- package/esm/remult-sveltekit.d.ts +4 -4
- package/esm/remult-sveltekit.js +71 -71
- package/esm/server/JsonEntityFileStorage.d.ts +11 -11
- package/esm/server/JsonEntityFileStorage.js +27 -26
- package/esm/server/core.d.ts +4 -4
- package/esm/server/core.js +4 -4
- package/esm/server/expressBridge.d.ts +128 -128
- package/esm/server/expressBridge.js +988 -971
- package/esm/server/index.d.ts +6 -6
- package/esm/server/index.js +12 -12
- package/esm/server/initAsyncHooks.d.ts +1 -1
- package/esm/server/initAsyncHooks.js +9 -9
- package/esm/server/initDataProvider.d.ts +2 -2
- package/esm/server/initDataProvider.js +14 -14
- package/esm/src/CompoundIdField.d.ts +27 -27
- package/esm/src/CompoundIdField.js +54 -41
- package/esm/src/__EntityValueProvider.d.ts +11 -11
- package/esm/src/__EntityValueProvider.js +1 -1
- package/esm/src/__RowsOfDataForTesting.d.ts +3 -3
- package/esm/src/__RowsOfDataForTesting.js +1 -1
- package/esm/src/buildRestDataProvider.d.ts +31 -31
- package/esm/src/buildRestDataProvider.js +121 -120
- package/esm/src/column-interfaces.d.ts +160 -160
- package/esm/src/column-interfaces.js +7 -7
- package/esm/src/column.d.ts +31 -31
- package/esm/src/column.js +108 -101
- package/esm/src/context.d.ts +134 -134
- package/esm/src/context.js +287 -282
- package/esm/src/data-api.d.ts +38 -38
- package/esm/src/data-api.js +281 -279
- package/esm/src/data-interfaces.d.ts +41 -41
- package/esm/src/data-interfaces.js +12 -12
- package/esm/src/data-providers/array-entity-data-provider.d.ts +22 -22
- package/esm/src/data-providers/array-entity-data-provider.js +252 -249
- package/esm/src/data-providers/in-memory-database.d.ts +9 -9
- package/esm/src/data-providers/in-memory-database.js +16 -18
- package/esm/src/data-providers/json-data-provider.d.ts +12 -12
- package/esm/src/data-providers/json-data-provider.js +55 -52
- package/esm/src/data-providers/rest-data-provider.d.ts +39 -39
- package/esm/src/data-providers/rest-data-provider.js +272 -267
- package/esm/src/data-providers/sql-database.d.ts +33 -33
- package/esm/src/data-providers/sql-database.js +401 -394
- package/esm/src/data-providers/web-sql-data-provider.d.ts +21 -21
- package/esm/src/data-providers/web-sql-data-provider.js +145 -137
- package/esm/src/entity.d.ts +95 -95
- package/esm/src/entity.js +1 -1
- package/esm/src/filter/filter-consumer-bridge-to-sql-request.d.ts +50 -50
- package/esm/src/filter/filter-consumer-bridge-to-sql-request.js +165 -162
- package/esm/src/filter/filter-interfaces.d.ts +86 -86
- package/esm/src/filter/filter-interfaces.js +524 -515
- package/esm/src/live-query/LiveQueryClient.d.ts +1 -1
- package/esm/src/live-query/LiveQueryClient.js +196 -192
- package/esm/src/live-query/SseSubscriptionClient.d.ts +5 -5
- package/esm/src/live-query/SseSubscriptionClient.js +86 -86
- package/esm/src/live-query/SubscriptionChannel.d.ts +41 -41
- package/esm/src/live-query/SubscriptionChannel.js +126 -121
- package/esm/src/live-query/SubscriptionServer.d.ts +38 -38
- package/esm/src/live-query/SubscriptionServer.js +114 -112
- package/esm/src/remult-proxy.d.ts +2 -2
- package/esm/src/remult-proxy.js +177 -178
- package/esm/src/remult3/DecoratorReplacer.d.ts +10 -10
- package/esm/src/remult3/DecoratorReplacer.js +20 -20
- package/esm/src/remult3/RepositoryImplementation.d.ts +332 -332
- package/esm/src/remult3/RepositoryImplementation.js +2122 -2051
- package/esm/src/remult3/__updateEntityBasedOnWhere.d.ts +2 -2
- package/esm/src/remult3/__updateEntityBasedOnWhere.js +24 -24
- package/esm/src/remult3/entity.d.ts +28 -28
- package/esm/src/remult3/entity.js +70 -70
- package/esm/src/remult3/getEntityRef.d.ts +9 -9
- package/esm/src/remult3/getEntityRef.js +27 -27
- package/esm/src/remult3/remult3.d.ts +397 -397
- package/esm/src/remult3/remult3.js +1 -1
- package/esm/src/resultCompoundIdFilter.d.ts +3 -3
- package/esm/src/resultCompoundIdFilter.js +16 -16
- package/esm/src/server-action-info.d.ts +10 -10
- package/esm/src/server-action-info.js +12 -12
- package/esm/src/server-action.d.ts +79 -79
- package/esm/src/server-action.js +397 -387
- package/esm/src/sort.d.ts +16 -16
- package/esm/src/sort.js +105 -104
- package/esm/src/sql-command.d.ts +19 -19
- package/esm/src/sql-command.js +1 -1
- package/esm/src/validators.d.ts +14 -14
- package/esm/src/validators.js +36 -36
- package/esm/src/valueConverters.d.ts +13 -13
- package/esm/src/valueConverters.js +210 -210
- package/esm/urlBuilder.d.ts +6 -6
- package/esm/urlBuilder.js +20 -19
- package/graphql.d.ts +14 -14
- package/graphql.js +953 -953
- package/index.d.ts +31 -31
- package/index.js +67 -67
- package/inputTypes.d.ts +9 -9
- package/inputTypes.js +16 -16
- package/live-query/data-provider-live-query-storage.d.ts +23 -23
- package/live-query/data-provider-live-query-storage.js +263 -263
- package/myLog.d.ts +1 -1
- package/myLog.js +20 -20
- package/package.json +1 -1
- package/postgres/index.d.ts +2 -2
- package/postgres/index.js +5 -5
- package/postgres/postgres-data-provider.d.ts +36 -36
- package/postgres/postgres-data-provider.js +191 -191
- package/postgres/schema-builder.d.ts +19 -19
- package/postgres/schema-builder.js +369 -369
- package/remult-express.d.ts +9 -9
- package/remult-express.js +34 -33
- package/remult-fastify.d.ts +6 -6
- package/remult-fastify.js +79 -79
- package/remult-fresh.d.ts +17 -17
- package/remult-fresh.js +41 -41
- package/remult-knex/index.d.ts +30 -30
- package/remult-knex/index.js +917 -915
- package/remult-mongo.d.ts +24 -24
- package/remult-mongo.js +515 -515
- package/remult-next.d.ts +25 -25
- package/remult-next.js +171 -171
- package/remult-sveltekit.d.ts +4 -4
- package/remult-sveltekit.js +110 -110
- package/server/JsonEntityFileStorage.d.ts +11 -11
- package/server/JsonEntityFileStorage.js +35 -35
- package/server/core.d.ts +4 -4
- package/server/core.js +12 -12
- package/server/expressBridge.d.ts +128 -128
- package/server/expressBridge.js +1401 -1402
- package/server/index.d.ts +6 -6
- package/server/index.js +24 -24
- package/server/initAsyncHooks.d.ts +1 -1
- package/server/initAsyncHooks.js +13 -13
- package/server/initDataProvider.d.ts +2 -2
- package/server/initDataProvider.js +26 -26
- package/src/CompoundIdField.d.ts +27 -27
- package/src/CompoundIdField.js +54 -54
- package/src/__EntityValueProvider.d.ts +11 -11
- package/src/__EntityValueProvider.js +2 -2
- package/src/__RowsOfDataForTesting.d.ts +3 -3
- package/src/__RowsOfDataForTesting.js +2 -2
- package/src/buildRestDataProvider.d.ts +31 -31
- package/src/buildRestDataProvider.js +177 -174
- package/src/column-interfaces.d.ts +160 -160
- package/src/column-interfaces.js +11 -11
- package/src/column.d.ts +31 -31
- package/src/column.js +132 -132
- package/src/context.d.ts +134 -134
- package/src/context.js +451 -451
- package/src/data-api.d.ts +38 -38
- package/src/data-api.js +524 -524
- package/src/data-interfaces.d.ts +41 -41
- package/src/data-interfaces.js +16 -16
- package/src/data-providers/array-entity-data-provider.d.ts +22 -22
- package/src/data-providers/array-entity-data-provider.js +364 -364
- package/src/data-providers/in-memory-database.d.ts +9 -9
- package/src/data-providers/in-memory-database.js +33 -33
- package/src/data-providers/json-data-provider.d.ts +12 -12
- package/src/data-providers/json-data-provider.js +106 -106
- package/src/data-providers/rest-data-provider.d.ts +39 -39
- package/src/data-providers/rest-data-provider.js +388 -388
- package/src/data-providers/sql-database.d.ts +33 -33
- package/src/data-providers/sql-database.js +653 -653
- package/src/data-providers/web-sql-data-provider.d.ts +21 -21
- package/src/data-providers/web-sql-data-provider.js +229 -229
- package/src/entity.d.ts +95 -95
- package/src/entity.js +2 -2
- package/src/filter/filter-consumer-bridge-to-sql-request.d.ts +50 -50
- package/src/filter/filter-consumer-bridge-to-sql-request.js +307 -307
- package/src/filter/filter-interfaces.d.ts +86 -86
- package/src/filter/filter-interfaces.js +693 -685
- package/src/live-query/LiveQueryClient.d.ts +1 -1
- package/src/live-query/LiveQueryClient.js +293 -293
- package/src/live-query/SseSubscriptionClient.d.ts +5 -5
- package/src/live-query/SseSubscriptionClient.js +154 -154
- package/src/live-query/SubscriptionChannel.d.ts +41 -41
- package/src/live-query/SubscriptionChannel.js +189 -189
- package/src/live-query/SubscriptionServer.d.ts +38 -38
- package/src/live-query/SubscriptionServer.js +264 -264
- package/src/remult-proxy.d.ts +2 -2
- package/src/remult-proxy.js +307 -307
- package/src/remult3/DecoratorReplacer.d.ts +10 -10
- package/src/remult3/DecoratorReplacer.js +24 -24
- package/src/remult3/RepositoryImplementation.d.ts +332 -332
- package/src/remult3/RepositoryImplementation.js +3391 -3373
- package/src/remult3/__updateEntityBasedOnWhere.d.ts +2 -2
- package/src/remult3/__updateEntityBasedOnWhere.js +28 -28
- package/src/remult3/entity.d.ts +28 -28
- package/src/remult3/entity.js +88 -88
- package/src/remult3/getEntityRef.d.ts +9 -9
- package/src/remult3/getEntityRef.js +35 -35
- package/src/remult3/remult3.d.ts +397 -397
- package/src/remult3/remult3.js +2 -2
- package/src/resultCompoundIdFilter.d.ts +3 -3
- package/src/resultCompoundIdFilter.js +20 -20
- package/src/server-action-info.d.ts +10 -10
- package/src/server-action-info.js +15 -15
- package/src/server-action.d.ts +79 -79
- package/src/server-action.js +632 -632
- package/src/sort.d.ts +16 -16
- package/src/sort.js +161 -161
- package/src/sql-command.d.ts +19 -19
- package/src/sql-command.js +2 -2
- package/src/validators.d.ts +14 -14
- package/src/validators.js +71 -69
- package/src/valueConverters.d.ts +13 -13
- package/src/valueConverters.js +213 -213
- package/urlBuilder.d.ts +6 -6
- 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
|
+
}
|