@nx-ddd/hasura 19.0.0-preview.23 → 19.0.0-preview.25
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/builders/index.d.ts +2 -0
- package/builders/parts/_meta/graphql-query-part.d.ts +12 -0
- package/builders/parts/mutations/create.builder.d.ts +13 -0
- package/builders/parts/mutations/delete.builder.d.ts +12 -0
- package/builders/parts/mutations/index.d.ts +5 -0
- package/builders/parts/mutations/mutations.builder.d.ts +14 -0
- package/builders/parts/mutations/save.builder.d.ts +21 -0
- package/builders/parts/mutations/update.builder.d.ts +13 -0
- package/builders/parts/parts.builder.d.ts +10 -0
- package/builders/parts/queries/get.builder.d.ts +9 -0
- package/builders/parts/queries/index.d.ts +2 -0
- package/builders/parts/queries/queries.builder.d.ts +16 -0
- package/builders/query-builder.d.ts +15 -0
- package/fesm2022/nx-ddd-hasura.mjs +377 -222
- package/fesm2022/nx-ddd-hasura.mjs.map +1 -1
- package/hasura.converter.d.ts +14 -3
- package/hasura.repository.d.ts +16 -19
- package/hasura.service.d.ts +13 -2
- package/index.d.ts +1 -0
- package/package.json +2 -2
|
@@ -1,17 +1,19 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
2
|
import { inject, Injectable, InjectionToken, importProvidersFrom } from '@angular/core';
|
|
3
|
-
import { Apollo, APOLLO_OPTIONS, ApolloModule } from 'apollo-angular';
|
|
3
|
+
import { Apollo, APOLLO_OPTIONS, ApolloModule, gql } from 'apollo-angular';
|
|
4
4
|
import { HttpLink } from 'apollo-angular/http';
|
|
5
5
|
import { InMemoryCache } from '@apollo/client/cache';
|
|
6
6
|
import { setContext } from '@apollo/client/link/context';
|
|
7
|
-
import { split, ApolloLink, HttpLink as HttpLink$1, InMemoryCache as InMemoryCache$1, gql } from '@apollo/client/core';
|
|
7
|
+
import { split, ApolloLink, HttpLink as HttpLink$1, InMemoryCache as InMemoryCache$1, gql as gql$1 } from '@apollo/client/core';
|
|
8
8
|
import { getMainDefinition } from '@apollo/client/utilities';
|
|
9
9
|
import { makeDI, makeDecoratorFactories, plainToInstanceWithValid } from '@nx-ddd/core';
|
|
10
10
|
import { WebSocketLink } from '@apollo/client/link/ws';
|
|
11
|
-
import { from, of, isObservable,
|
|
12
|
-
import { camelCase
|
|
11
|
+
import { from, of, isObservable, lastValueFrom, filter, take, distinctUntilChanged, tap, switchMap, map } from 'rxjs';
|
|
12
|
+
import { camelCase as camelCase$1, snakeCase, get, pick, omitBy } from 'lodash-es';
|
|
13
13
|
import { HTTP_INTERCEPTORS, HttpClient } from '@angular/common/http';
|
|
14
14
|
import dayjs from 'dayjs';
|
|
15
|
+
import { format } from 'date-fns';
|
|
16
|
+
import { Repository } from '@nx-ddd/common/domain';
|
|
15
17
|
export { TransformToDayjs } from '@nx-ddd/common/domain';
|
|
16
18
|
export { IsDayjs } from 'class-validator-extended';
|
|
17
19
|
|
|
@@ -20,7 +22,7 @@ function wrap(token) {
|
|
|
20
22
|
}
|
|
21
23
|
function resolve(getHeaders) {
|
|
22
24
|
const headers$ = wrap(getHeaders());
|
|
23
|
-
return
|
|
25
|
+
return lastValueFrom(headers$.pipe(filter((headers) => !!headers), take(1), distinctUntilChanged(), tap((headers) => console.debug('[resolve] headers:', headers))));
|
|
24
26
|
}
|
|
25
27
|
function buildWebsocketLink(endpoint, getHeaders) {
|
|
26
28
|
return new WebSocketLink({
|
|
@@ -75,7 +77,7 @@ const { createDecorator, getAnnotations, } = makeDecoratorFactories((type, field
|
|
|
75
77
|
function getFlattenFieldAnnotations(T, prefix = '') {
|
|
76
78
|
const annotations = Hasura.getAnnotations(T);
|
|
77
79
|
return (annotations ?? []).reduce((acc, annotation) => {
|
|
78
|
-
const currentKey = prefix ? camelCase(`${prefix}_${annotation.fieldName}`) : annotation.fieldName;
|
|
80
|
+
const currentKey = prefix ? camelCase$1(`${prefix}_${annotation.fieldName}`) : annotation.fieldName;
|
|
79
81
|
if (annotation.childType) {
|
|
80
82
|
return {
|
|
81
83
|
...acc,
|
|
@@ -93,7 +95,7 @@ function getFields(T, options = {
|
|
|
93
95
|
case: 'snake'
|
|
94
96
|
}) {
|
|
95
97
|
const annotations = Hasura.getAnnotations(T);
|
|
96
|
-
const changeCase = options?.case === 'snake' ? snakeCase : camelCase;
|
|
98
|
+
const changeCase = options?.case === 'snake' ? snakeCase : camelCase$1;
|
|
97
99
|
const fields = (annotations ?? []).flatMap((annotation) => {
|
|
98
100
|
const currentKey = changeCase(options?.prefix ? `${options?.prefix}_${annotation.fieldName}` : annotation.fieldName);
|
|
99
101
|
if (annotation.childType) {
|
|
@@ -146,20 +148,34 @@ function provideHasuraConfig(config) {
|
|
|
146
148
|
}
|
|
147
149
|
|
|
148
150
|
function deepCamelToSnakeCase(obj) {
|
|
149
|
-
if (Array.isArray(obj))
|
|
151
|
+
if (Array.isArray(obj))
|
|
150
152
|
return obj.map(deepCamelToSnakeCase);
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
153
|
+
if (obj instanceof Date)
|
|
154
|
+
return obj;
|
|
155
|
+
if (obj && typeof obj === "object") {
|
|
156
|
+
const result = {};
|
|
157
|
+
for (const key in obj) {
|
|
158
|
+
if (Object.prototype.hasOwnProperty.call(obj, key))
|
|
159
|
+
result[snakeCase(key)] = deepCamelToSnakeCase(obj[key]);
|
|
160
|
+
}
|
|
161
|
+
return result;
|
|
154
162
|
}
|
|
155
163
|
return obj;
|
|
156
164
|
}
|
|
165
|
+
function camelCase(str) {
|
|
166
|
+
return str.replace(/_([a-z])/g, (_, letter) => letter.toUpperCase());
|
|
167
|
+
}
|
|
157
168
|
function deepSnakeToCamelCase(obj) {
|
|
158
|
-
if (Array.isArray(obj))
|
|
169
|
+
if (Array.isArray(obj))
|
|
159
170
|
return obj.map(deepSnakeToCamelCase);
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
171
|
+
if (obj instanceof Date)
|
|
172
|
+
return obj;
|
|
173
|
+
if (obj && typeof obj === "object") {
|
|
174
|
+
const result = {};
|
|
175
|
+
for (const key in obj)
|
|
176
|
+
if (Object.prototype.hasOwnProperty.call(obj, key))
|
|
177
|
+
result[camelCase(key)] = deepSnakeToCamelCase(obj[key]);
|
|
178
|
+
return result;
|
|
163
179
|
}
|
|
164
180
|
return obj;
|
|
165
181
|
}
|
|
@@ -189,23 +205,54 @@ function getConverter(type) {
|
|
|
189
205
|
const makeConverter = getConverter;
|
|
190
206
|
class HasuraUtils {
|
|
191
207
|
static toTimestamp(date) {
|
|
192
|
-
if (
|
|
208
|
+
if (dayjs.isDayjs(date)) {
|
|
209
|
+
return date.toISOString();
|
|
210
|
+
}
|
|
211
|
+
else if (date instanceof Date) {
|
|
212
|
+
return format(date, 'yyyy-MM-dd HH:mm:ss');
|
|
213
|
+
}
|
|
214
|
+
else {
|
|
193
215
|
return null;
|
|
194
|
-
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
static toDate(date) {
|
|
219
|
+
if (typeof date === 'undefined') {
|
|
220
|
+
return undefined;
|
|
221
|
+
}
|
|
222
|
+
else if (dayjs.isDayjs(date)) {
|
|
223
|
+
return format(date.toDate(), 'yyyy-MM-dd');
|
|
224
|
+
}
|
|
225
|
+
else if (date instanceof Date) {
|
|
226
|
+
return format(date, 'yyyy-MM-dd');
|
|
227
|
+
}
|
|
228
|
+
else if (typeof date === 'string') {
|
|
229
|
+
return date;
|
|
230
|
+
}
|
|
231
|
+
else {
|
|
232
|
+
return null;
|
|
233
|
+
}
|
|
195
234
|
}
|
|
196
235
|
static fromHasura(_object, type) {
|
|
197
236
|
const object = deepSnakeToCamelCase(_object);
|
|
198
237
|
return plainToInstanceWithValid(type, object);
|
|
199
238
|
}
|
|
239
|
+
static toNumber(value) {
|
|
240
|
+
if (typeof value === 'undefined')
|
|
241
|
+
return undefined;
|
|
242
|
+
return isNaN(Number(value)) ? null : Number(value);
|
|
243
|
+
}
|
|
200
244
|
static toHasura(object, type, { extraFunc = deepCamelToSnakeCase } = {}) {
|
|
201
245
|
const fields = getFlattenFieldAnnotations(type);
|
|
202
246
|
const obj = Object.entries(fields).reduce((acc, [key, annotation]) => {
|
|
203
247
|
const value = get(object, annotation.fieldName);
|
|
248
|
+
if (typeof value === 'undefined')
|
|
249
|
+
return acc;
|
|
204
250
|
switch (annotation.type) {
|
|
205
251
|
case 'text': return { ...acc, [key]: value };
|
|
206
252
|
case 'timestamp': return { ...acc, [key]: this.toTimestamp(value) };
|
|
207
|
-
case '
|
|
208
|
-
case '
|
|
253
|
+
case 'date': return { ...acc, [key]: this.toDate(value) };
|
|
254
|
+
case 'numeric': return { ...acc, [key]: this.toNumber(value) };
|
|
255
|
+
case 'integer': return { ...acc, [key]: this.toNumber(value) };
|
|
209
256
|
case 'json': return { ...acc, [key]: value };
|
|
210
257
|
case 'map': return { ...acc };
|
|
211
258
|
default: return { ...acc, [key]: value };
|
|
@@ -275,6 +322,231 @@ function provideHasuraWithWebSocket(config) {
|
|
|
275
322
|
];
|
|
276
323
|
}
|
|
277
324
|
|
|
325
|
+
class GetQueryPartBuilder {
|
|
326
|
+
config;
|
|
327
|
+
constructor(config) {
|
|
328
|
+
this.config = config;
|
|
329
|
+
}
|
|
330
|
+
build(params) {
|
|
331
|
+
const queryName = `${this.config.tableName}_by_pk`;
|
|
332
|
+
const variableDefinitions = ['$id: String!'];
|
|
333
|
+
const queryPart = `${queryName}(id: $id) { ${this.config.columns.join(' ')} }`;
|
|
334
|
+
return { queryPart, variableDefinitions, variables: params, operationName: queryName };
|
|
335
|
+
}
|
|
336
|
+
buildMany() {
|
|
337
|
+
const queryName = this.config.tableName;
|
|
338
|
+
const queryPart = `${queryName} { ${this.config.columns.join(' ')} }`;
|
|
339
|
+
return { queryPart, variableDefinitions: [], variables: {}, operationName: queryName };
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
function makeSubscription(query) {
|
|
344
|
+
const { kind, definitions } = query;
|
|
345
|
+
const subscriptionDefinitions = definitions.map((definition) => {
|
|
346
|
+
if (definition.kind === 'OperationDefinition' && definition.operation === 'query') {
|
|
347
|
+
return {
|
|
348
|
+
...definition,
|
|
349
|
+
operation: 'subscription',
|
|
350
|
+
};
|
|
351
|
+
}
|
|
352
|
+
return definition;
|
|
353
|
+
});
|
|
354
|
+
return { kind, definitions: subscriptionDefinitions };
|
|
355
|
+
}
|
|
356
|
+
;
|
|
357
|
+
class QueriesBuilder {
|
|
358
|
+
get;
|
|
359
|
+
constructor(config) {
|
|
360
|
+
this.get = new GetQueryPartBuilder(config);
|
|
361
|
+
}
|
|
362
|
+
makeSubscription(query) {
|
|
363
|
+
return makeSubscription(query);
|
|
364
|
+
}
|
|
365
|
+
;
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
class CreateMutationBuilder {
|
|
369
|
+
config;
|
|
370
|
+
constructor(config) {
|
|
371
|
+
this.config = config;
|
|
372
|
+
}
|
|
373
|
+
build(data, alias = 'create') {
|
|
374
|
+
const object = this.convertToObject(data);
|
|
375
|
+
const mutationName = `insert_${this.config.tableName}`;
|
|
376
|
+
const variableDefinitions = [`$${alias}: ${this.config.tableName}_insert_input!`];
|
|
377
|
+
const queryPart = `${alias}: ${mutationName}(objects: [$${alias}]) { affected_rows returning { ${this.config.columns.join(' ')} } }`;
|
|
378
|
+
const variables = { [alias]: object };
|
|
379
|
+
return { queryPart, variableDefinitions, variables, operationName: mutationName, alias };
|
|
380
|
+
}
|
|
381
|
+
buildMany(data, alias = 'createMany') {
|
|
382
|
+
const objects = this.convertToObjects(data);
|
|
383
|
+
const mutationName = `insert_${this.config.tableName}`;
|
|
384
|
+
const variableDefinitions = [`$${alias}: [${this.config.tableName}_insert_input!]!`];
|
|
385
|
+
const queryPart = `${alias}: ${mutationName}(objects: $${alias}) { affected_rows returning { ${this.config.columns.join(' ')} } }`;
|
|
386
|
+
const variables = { [alias]: objects };
|
|
387
|
+
return { queryPart, variableDefinitions, variables, operationName: mutationName, alias };
|
|
388
|
+
}
|
|
389
|
+
convertToObject(item) {
|
|
390
|
+
const fields = Object.keys(item).map(snakeCase).filter((field) => !['created_at', 'updated_at'].includes(field));
|
|
391
|
+
const picked = pick(item, [...fields]);
|
|
392
|
+
return omitBy(picked, (value) => typeof value === 'undefined');
|
|
393
|
+
}
|
|
394
|
+
convertToObjects(items) {
|
|
395
|
+
return items.map((item) => this.convertToObject(item));
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
class DeleteMutationBuilder {
|
|
400
|
+
config;
|
|
401
|
+
constructor(config) {
|
|
402
|
+
this.config = config;
|
|
403
|
+
}
|
|
404
|
+
build({ id }) {
|
|
405
|
+
const operationName = `delete_${this.config.tableName}`;
|
|
406
|
+
const queryPart = `${operationName}(where: {id: {_eq: $id}}) { affected_rows }`;
|
|
407
|
+
const variableDefinitions = ['$id: String!'];
|
|
408
|
+
return { queryPart, variableDefinitions, variables: { id }, operationName };
|
|
409
|
+
}
|
|
410
|
+
buildMany(params, alias = 'deleteMany') {
|
|
411
|
+
const operationName = `delete_${this.config.tableName}`;
|
|
412
|
+
const variableDefinitions = [`$${alias}: [String!]!`];
|
|
413
|
+
const queryPart = `${alias}: ${operationName}(where: {id: {_in: $${alias}}}) { affected_rows }`;
|
|
414
|
+
const variables = { [alias]: params.map((p) => p.id) };
|
|
415
|
+
return { queryPart, variableDefinitions, variables, operationName, alias };
|
|
416
|
+
}
|
|
417
|
+
buildAll(alias = 'deleteAll') {
|
|
418
|
+
const operationName = `delete_${this.config.tableName}`;
|
|
419
|
+
const uniqueAlias = `${alias}_${this.config.tableName}`;
|
|
420
|
+
const variableDefinitions = [];
|
|
421
|
+
const queryPart = `${uniqueAlias}: ${operationName}(where: {}) { affected_rows }`;
|
|
422
|
+
const variables = {};
|
|
423
|
+
return { queryPart, variableDefinitions, variables, operationName, alias };
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
class SaveMutationBuilder {
|
|
428
|
+
config;
|
|
429
|
+
constructor(config) {
|
|
430
|
+
this.config = config;
|
|
431
|
+
}
|
|
432
|
+
build(data, { operationName = `insert_${this.config.tableName}`, constraint = this.config.pk, columns = this.config.columns, returningColumns = this.config.columns, alias = operationName, } = {}) {
|
|
433
|
+
const object = this.buildObject(data);
|
|
434
|
+
const onConflict = this.buildOnConflict(data, constraint, columns);
|
|
435
|
+
const variableDefinitions = [
|
|
436
|
+
`$${alias}Object: ${this.config.tableName}_insert_input!`,
|
|
437
|
+
`$${alias}OnConflict: ${this.config.tableName}_on_conflict!`
|
|
438
|
+
];
|
|
439
|
+
const queryPart = `${alias}: ${operationName}( objects: [$${alias}Object] on_conflict: $${alias}OnConflict) { affected_rows returning { ${returningColumns.join(', ')} } }`;
|
|
440
|
+
const variables = { [`${alias}Object`]: object, [`${alias}OnConflict`]: onConflict };
|
|
441
|
+
return { queryPart, variableDefinitions, variables, operationName, alias };
|
|
442
|
+
}
|
|
443
|
+
buildMany(entities, { operationName = `insert_${this.config.tableName}`, constraint = this.config.pk, columns = this.config.columns, returningColumns = this.config.columns, alias = 'save' } = {}) {
|
|
444
|
+
const objects = this.buildObjects(entities);
|
|
445
|
+
const onConflict = this.buildOnConflict(entities[0], constraint, columns);
|
|
446
|
+
const variableDefinitions = [
|
|
447
|
+
`$${alias}Objects: [${this.config.tableName}_insert_input!]!`,
|
|
448
|
+
`$${alias}OnConflict: ${this.config.tableName}_on_conflict!`
|
|
449
|
+
];
|
|
450
|
+
const queryPart = `${alias}: ${operationName}(objects: $${alias}Objects on_conflict: $${alias}OnConflict) {
|
|
451
|
+
affected_rows returning { ${returningColumns.join(', ')} }
|
|
452
|
+
}`;
|
|
453
|
+
const variables = { [`${alias}Objects`]: objects, [`${alias}OnConflict`]: onConflict };
|
|
454
|
+
return { queryPart, variableDefinitions, variables, operationName: operationName, alias };
|
|
455
|
+
}
|
|
456
|
+
buildObject(item) {
|
|
457
|
+
const fields = Object.keys(item).map(snakeCase).filter((field) => !['created_at', 'updated_at'].includes(field));
|
|
458
|
+
const picked = pick(item, [...fields]);
|
|
459
|
+
return omitBy(picked, (value) => typeof value === 'undefined');
|
|
460
|
+
}
|
|
461
|
+
buildObjects(items) {
|
|
462
|
+
return items.map((item) => this.buildObject(item));
|
|
463
|
+
}
|
|
464
|
+
buildOnConflict(data, constraint, columns) {
|
|
465
|
+
const fields = Object.keys(this.buildObject(data));
|
|
466
|
+
const updateColumns = fields.filter(column => columns.includes(column));
|
|
467
|
+
return { constraint, update_columns: updateColumns };
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
class UpdateMutationBuilder {
|
|
472
|
+
config;
|
|
473
|
+
constructor(config) {
|
|
474
|
+
this.config = config;
|
|
475
|
+
}
|
|
476
|
+
build(data, alias = 'update') {
|
|
477
|
+
const mutationName = `update_${this.config.tableName}`;
|
|
478
|
+
const object = this.buildObject(data);
|
|
479
|
+
const variableDefinitions = [`$${alias}Id: String!`, `$${alias}Object: ${this.config.tableName}_set_input!`];
|
|
480
|
+
const queryPart = `${alias}: ${mutationName}(where: {id: {_eq: $${alias}Id}} _set: $${alias}Object) { affected_rows returning { id } }`;
|
|
481
|
+
const variables = { [`${alias}Id`]: data.id, [`${alias}Object`]: object };
|
|
482
|
+
return { queryPart, variableDefinitions, variables, operationName: mutationName, alias };
|
|
483
|
+
}
|
|
484
|
+
buildMany(data, alias = 'updateMany') {
|
|
485
|
+
const mutationName = `update_${this.config.tableName}_many`;
|
|
486
|
+
const objects = this.buildObjects(data);
|
|
487
|
+
const variableDefinitions = [`$${alias}Object: [${this.config.tableName}_updates!]!`];
|
|
488
|
+
const queryPart = `${alias}: ${mutationName}(updates: $${alias}Objects) { affected_rows returning { id } }`;
|
|
489
|
+
const variables = { [`${alias}Objects`]: objects };
|
|
490
|
+
return { queryPart, variableDefinitions, variables, operationName: mutationName, alias };
|
|
491
|
+
}
|
|
492
|
+
buildObject(item) {
|
|
493
|
+
const fields = Object.keys(item).map(snakeCase).filter((field) => !['created_at', 'updated_at'].includes(field));
|
|
494
|
+
const picked = pick(item, fields);
|
|
495
|
+
return omitBy(picked, (value) => typeof value === 'undefined');
|
|
496
|
+
}
|
|
497
|
+
buildObjects(items) {
|
|
498
|
+
return items.map((item) => ({ where: { id: { _eq: item.id } }, _set: this.buildObject(item) }));
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
class HasuraMutationBuilder {
|
|
503
|
+
create;
|
|
504
|
+
update;
|
|
505
|
+
save;
|
|
506
|
+
delete_;
|
|
507
|
+
constructor(config) {
|
|
508
|
+
this.create = new CreateMutationBuilder(config);
|
|
509
|
+
this.update = new UpdateMutationBuilder(config);
|
|
510
|
+
this.save = new SaveMutationBuilder(config);
|
|
511
|
+
this.delete_ = new DeleteMutationBuilder(config);
|
|
512
|
+
}
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
class HasuraQueryPartsBuilder {
|
|
516
|
+
mutations;
|
|
517
|
+
queries;
|
|
518
|
+
constructor(config) {
|
|
519
|
+
this.mutations = new HasuraMutationBuilder(config);
|
|
520
|
+
this.queries = new QueriesBuilder(config);
|
|
521
|
+
}
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
class HasuraQueryBuilder {
|
|
525
|
+
parts;
|
|
526
|
+
constructor(config) {
|
|
527
|
+
this.parts = new HasuraQueryPartsBuilder(config);
|
|
528
|
+
}
|
|
529
|
+
buildQuery(part) {
|
|
530
|
+
const operationNameStr = part.operationName ? `${part.operationName} ` : '';
|
|
531
|
+
const variablesStr = part.variableDefinitions?.length ? `(${part.variableDefinitions.join(', ')}) ` : '';
|
|
532
|
+
return `query ${operationNameStr}${variablesStr}{ ${part.queryPart} }`;
|
|
533
|
+
}
|
|
534
|
+
static buildMutation(part) {
|
|
535
|
+
return `mutation ${part.operationName}(${part.variableDefinitions.join(', ')}) { ${part.queryPart} }`;
|
|
536
|
+
}
|
|
537
|
+
buildMutation(part) {
|
|
538
|
+
return HasuraQueryBuilder.buildMutation(part);
|
|
539
|
+
}
|
|
540
|
+
buildTransactionQuery(parts) {
|
|
541
|
+
const operationName = `Transaction`;
|
|
542
|
+
const variableDefinitions = parts.reduce((acc, m) => [...acc, ...m.variableDefinitions], []);
|
|
543
|
+
const mutationParts = parts.map(m => m.queryPart);
|
|
544
|
+
const query = `mutation ${operationName} (${variableDefinitions.join(', ')}) { ${mutationParts.join('\n')} }`;
|
|
545
|
+
const variables = parts.reduce((acc, m) => ({ ...acc, ...m.variables }), {});
|
|
546
|
+
return { query, variables };
|
|
547
|
+
}
|
|
548
|
+
}
|
|
549
|
+
|
|
278
550
|
class HasuraService {
|
|
279
551
|
http = inject(HttpClient);
|
|
280
552
|
apollo = inject(Apollo);
|
|
@@ -293,18 +565,51 @@ class HasuraService {
|
|
|
293
565
|
return of(clientOrObsOrPromise);
|
|
294
566
|
}
|
|
295
567
|
}
|
|
568
|
+
/** @deprecated */
|
|
296
569
|
graphql(args) {
|
|
297
570
|
return this.post('/v1/graphql', {
|
|
298
571
|
query: args.query,
|
|
299
572
|
variables: args.variables,
|
|
300
573
|
});
|
|
301
574
|
}
|
|
575
|
+
/** @deprecated */
|
|
302
576
|
post(endpoint, body) {
|
|
303
577
|
return this.http.post(`${this.config.url}${endpoint}`, body, {});
|
|
304
578
|
}
|
|
579
|
+
/** @deprecated */
|
|
305
580
|
delete(endpoint) {
|
|
306
581
|
return this.http.delete(`${this.config.url}${endpoint}`);
|
|
307
582
|
}
|
|
583
|
+
subscribe({ query, variables }) {
|
|
584
|
+
return this.getApolloClient().pipe(switchMap((client) => client.subscribe({
|
|
585
|
+
query: makeSubscription(query),
|
|
586
|
+
variables: variables,
|
|
587
|
+
fetchPolicy: 'network-only'
|
|
588
|
+
})));
|
|
589
|
+
}
|
|
590
|
+
async mutate(...args) {
|
|
591
|
+
const client = await lastValueFrom(this.getApolloClient());
|
|
592
|
+
return client.mutate(...args).catch((error) => {
|
|
593
|
+
console.error(error.graphQLErrors);
|
|
594
|
+
throw error;
|
|
595
|
+
});
|
|
596
|
+
}
|
|
597
|
+
async mutateByQueryPart(part) {
|
|
598
|
+
return this.mutate({
|
|
599
|
+
mutation: gql `${HasuraQueryBuilder.buildMutation(part)}`,
|
|
600
|
+
variables: part.variables,
|
|
601
|
+
}).then((res) => {
|
|
602
|
+
console.debug('[HasuraService] mutateByQueryPart:', res);
|
|
603
|
+
return res.data[part?.alias ?? part.operationName];
|
|
604
|
+
});
|
|
605
|
+
}
|
|
606
|
+
async query(...args) {
|
|
607
|
+
const client = await lastValueFrom(this.getApolloClient());
|
|
608
|
+
return client.query(...args).catch((error) => {
|
|
609
|
+
console.error(error.graphQLErrors);
|
|
610
|
+
throw error;
|
|
611
|
+
});
|
|
612
|
+
}
|
|
308
613
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.4", ngImport: i0, type: HasuraService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
309
614
|
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.1.4", ngImport: i0, type: HasuraService, providedIn: 'root' });
|
|
310
615
|
}
|
|
@@ -313,231 +618,81 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.4", ngImpor
|
|
|
313
618
|
args: [{ providedIn: 'root' }]
|
|
314
619
|
}] });
|
|
315
620
|
|
|
316
|
-
|
|
317
|
-
const { kind, definitions } = query;
|
|
318
|
-
const subscriptionDefinitions = definitions.map((definition) => {
|
|
319
|
-
if (definition.kind === 'OperationDefinition' && definition.operation === 'query') {
|
|
320
|
-
return {
|
|
321
|
-
...definition,
|
|
322
|
-
operation: 'subscription',
|
|
323
|
-
};
|
|
324
|
-
}
|
|
325
|
-
return definition;
|
|
326
|
-
});
|
|
327
|
-
return { kind, definitions: subscriptionDefinitions };
|
|
328
|
-
}
|
|
329
|
-
;
|
|
330
|
-
class HasuraRepository {
|
|
621
|
+
class HasuraRepository extends Repository {
|
|
331
622
|
hasura = inject(HasuraService);
|
|
332
|
-
subscribe({ query, variables }) {
|
|
333
|
-
return this.hasura.getApolloClient().pipe(switchMap((client) => client.subscribe({
|
|
334
|
-
query: makeSubscription(query),
|
|
335
|
-
variables: variables,
|
|
336
|
-
})));
|
|
337
|
-
}
|
|
338
623
|
get pkey() {
|
|
339
624
|
return `${this.tableName}_pkey`;
|
|
340
625
|
}
|
|
626
|
+
getQueryBuilder() {
|
|
627
|
+
return new HasuraQueryBuilder({ tableName: this.tableName, pk: this.pkey, columns: this.updateColumns });
|
|
628
|
+
}
|
|
341
629
|
async get(params) {
|
|
342
|
-
const
|
|
343
|
-
return
|
|
344
|
-
query: gql
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
}
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
})).then((res => res.data[queryName])).then(data => data ? this.converter.fromHasura(data) : data);
|
|
351
|
-
}
|
|
352
|
-
get listQuery() {
|
|
353
|
-
return `query list {
|
|
354
|
-
${this.tableName} {
|
|
355
|
-
${this.updateColumns.join(' ')}
|
|
356
|
-
}
|
|
357
|
-
}`;
|
|
630
|
+
const part = this.getQueryBuilder().parts.queries.get.build({ id: params.id });
|
|
631
|
+
return this.hasura.query({
|
|
632
|
+
query: gql$1 `${this.getQueryBuilder().buildQuery(part)}`,
|
|
633
|
+
variables: part.variables,
|
|
634
|
+
fetchPolicy: 'network-only',
|
|
635
|
+
})
|
|
636
|
+
.then((res) => this.converter.fromHasura(res.data[part.operationName]))
|
|
637
|
+
.then(data => data ? this.converter.fromHasura(data) : data);
|
|
358
638
|
}
|
|
359
639
|
async list() {
|
|
360
|
-
const
|
|
361
|
-
return
|
|
362
|
-
query: gql `${this.
|
|
363
|
-
|
|
640
|
+
const part = this.getQueryBuilder().parts.queries.get.buildMany();
|
|
641
|
+
return this.hasura.query({
|
|
642
|
+
query: gql$1 `${this.getQueryBuilder().buildQuery(part)}`,
|
|
643
|
+
fetchPolicy: 'network-only'
|
|
644
|
+
}).then(res => this.converter.fromHasuraMany(res.data[part.operationName]));
|
|
364
645
|
}
|
|
365
646
|
listChanges() {
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
}).pipe(map(res => this.converter.fromHasuraMany(res.data[this.tableName])));
|
|
647
|
+
const part = this.getQueryBuilder().parts.queries.get.buildMany();
|
|
648
|
+
const query = this.getQueryBuilder().buildQuery(part);
|
|
649
|
+
return this.hasura.subscribe({ query: gql$1 `${query}`, variables: {} }).pipe(map(res => this.converter.fromHasuraMany(res.data[part.operationName])));
|
|
370
650
|
}
|
|
371
651
|
async create(data) {
|
|
372
|
-
const
|
|
373
|
-
const
|
|
374
|
-
|
|
375
|
-
affected_rows
|
|
376
|
-
returning {
|
|
377
|
-
${this.updateColumns.join(' ')}
|
|
378
|
-
}
|
|
379
|
-
}
|
|
380
|
-
}`;
|
|
381
|
-
const object = omitBy(omit(this.converter.toHasura(data), ['createdAt', 'updatedAt', 'created_at', 'updated_at']), value => typeof value === 'undefined');
|
|
382
|
-
const client = await lastValueFrom(this.hasura.getApolloClient());
|
|
383
|
-
return client.mutate({
|
|
384
|
-
mutation,
|
|
385
|
-
variables: { object },
|
|
386
|
-
}).then(result => {
|
|
387
|
-
return this.converter.fromHasura(result.data[mutationName].returning[0]);
|
|
388
|
-
}).catch(error => {
|
|
389
|
-
console.error(error.graphQLErrors);
|
|
390
|
-
throw error;
|
|
391
|
-
});
|
|
652
|
+
const converted = this.converter.toHasura(data);
|
|
653
|
+
const part = this.getQueryBuilder().parts.mutations.create.build(converted);
|
|
654
|
+
return this.hasura.mutateByQueryPart(part).then(result => this.converter.fromHasura(result.returning[0]));
|
|
392
655
|
}
|
|
393
656
|
async createMany(data) {
|
|
394
|
-
const
|
|
395
|
-
const
|
|
396
|
-
|
|
397
|
-
mutation createMany($objects: [${this.tableName}_insert_input!]!) {
|
|
398
|
-
${mutationName}(objects: $objects) {
|
|
399
|
-
returning {
|
|
400
|
-
${this.updateColumns.join(" ")}
|
|
401
|
-
}
|
|
402
|
-
}
|
|
403
|
-
}
|
|
404
|
-
`;
|
|
405
|
-
const client = await lastValueFrom(this.hasura.getApolloClient());
|
|
406
|
-
return client.mutate({
|
|
407
|
-
mutation,
|
|
408
|
-
variables: { objects },
|
|
409
|
-
}).then((result) => this.converter.fromHasuraMany(result.data[mutationName].returning)).catch((error) => {
|
|
410
|
-
console.error(error.graphQLErrors);
|
|
411
|
-
throw error;
|
|
412
|
-
});
|
|
657
|
+
const items = this.converter.toHasuraMany(data);
|
|
658
|
+
const part = this.getQueryBuilder().parts.mutations.create.buildMany(items);
|
|
659
|
+
return this.hasura.mutateByQueryPart(part).then((result) => this.converter.fromHasuraMany(result.returning));
|
|
413
660
|
}
|
|
414
661
|
async update(data) {
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
const
|
|
419
|
-
|
|
420
|
-
const client = await lastValueFrom(this.hasura.getApolloClient());
|
|
421
|
-
console.debug('[Hasura Repository] update:', object);
|
|
422
|
-
return client.mutate({
|
|
423
|
-
mutation,
|
|
424
|
-
variables: {
|
|
425
|
-
id: data.id,
|
|
426
|
-
object,
|
|
427
|
-
},
|
|
428
|
-
}).catch(error => {
|
|
429
|
-
console.error(error.graphQLErrors);
|
|
430
|
-
throw error;
|
|
431
|
-
});
|
|
662
|
+
console.debug('data:', data);
|
|
663
|
+
const item = this.converter.toHasura(data);
|
|
664
|
+
console.debug('item:', item);
|
|
665
|
+
const part = this.getQueryBuilder().parts.mutations.update.build(item);
|
|
666
|
+
return this.hasura.mutateByQueryPart(part).then(() => { });
|
|
432
667
|
}
|
|
433
668
|
async updateMany(data) {
|
|
434
|
-
const
|
|
435
|
-
const
|
|
436
|
-
|
|
437
|
-
const object = pick(this.converter.toHasura(item), fields);
|
|
438
|
-
return { where: { id: { _eq: item.id } }, _set: object };
|
|
439
|
-
});
|
|
440
|
-
const mutation = gql `
|
|
441
|
-
mutation ${mutationName}($objects: [${this.tableName}_updates!]!) {
|
|
442
|
-
${mutationName}(updates: $objects) {
|
|
443
|
-
affected_rows
|
|
444
|
-
}
|
|
445
|
-
}
|
|
446
|
-
`;
|
|
447
|
-
const client = await lastValueFrom(this.hasura.getApolloClient());
|
|
448
|
-
return client
|
|
449
|
-
.mutate({ mutation, variables: { objects } })
|
|
450
|
-
.then((result) => result.data[mutationName].affected_rows)
|
|
451
|
-
.catch((error) => {
|
|
452
|
-
console.error(error.graphQLErrors);
|
|
453
|
-
throw error;
|
|
454
|
-
});
|
|
455
|
-
}
|
|
456
|
-
async delete(id) {
|
|
457
|
-
const client = await lastValueFrom(this.hasura.getApolloClient());
|
|
458
|
-
return client.mutate({
|
|
459
|
-
mutation: gql `mutation delete($id: String!) {
|
|
460
|
-
delete_${this.tableName}(where: {id: {_eq: $id}}) { affected_rows }
|
|
461
|
-
}`,
|
|
462
|
-
variables: { id },
|
|
463
|
-
}).catch(error => {
|
|
464
|
-
console.error(error.graphQLErrors);
|
|
465
|
-
throw error;
|
|
466
|
-
});
|
|
467
|
-
}
|
|
468
|
-
async save(data) {
|
|
469
|
-
const object = omit(this.converter.toHasura(data), ['createdAt', 'updatedAt']);
|
|
470
|
-
const query = gql `mutation upsert($object: [${this.tableName}_insert_input!]!) {
|
|
471
|
-
insert_${this.tableName}(
|
|
472
|
-
objects: $object,
|
|
473
|
-
on_conflict: {
|
|
474
|
-
constraint: ${this.pkey},
|
|
475
|
-
update_columns: [${this.updateColumns}]
|
|
476
|
-
}
|
|
477
|
-
) { affected_rows }
|
|
478
|
-
}`;
|
|
479
|
-
const client = await lastValueFrom(this.hasura.getApolloClient());
|
|
480
|
-
console.debug('[Hasura Repository] save:', client);
|
|
481
|
-
return client.mutate({
|
|
482
|
-
mutation: query,
|
|
483
|
-
variables: {
|
|
484
|
-
object: object,
|
|
485
|
-
},
|
|
486
|
-
}).catch(error => {
|
|
487
|
-
console.error(error.graphQLErrors);
|
|
488
|
-
throw error;
|
|
489
|
-
});
|
|
669
|
+
const items = this.converter.toHasuraMany(data);
|
|
670
|
+
const part = this.getQueryBuilder().parts.mutations.update.buildMany(items);
|
|
671
|
+
return this.hasura.mutateByQueryPart(part).then((result) => result.affected_rows).then(() => { });
|
|
490
672
|
}
|
|
491
|
-
async
|
|
492
|
-
const
|
|
493
|
-
|
|
494
|
-
objects: $objects,
|
|
495
|
-
on_conflict: {
|
|
496
|
-
constraint: ${this.pkey},
|
|
497
|
-
update_columns: [${this.updateColumns}]
|
|
498
|
-
}
|
|
499
|
-
) { affected_rows }
|
|
500
|
-
}`;
|
|
501
|
-
const objects = entities.map(entity => this.converter.toHasura(entity));
|
|
502
|
-
console.debug('[Hasura Repository] objects:', objects);
|
|
503
|
-
const client = await lastValueFrom(this.hasura.getApolloClient());
|
|
504
|
-
return client.mutate({
|
|
505
|
-
mutation: query,
|
|
506
|
-
variables: { objects },
|
|
507
|
-
}).catch(error => {
|
|
508
|
-
console.error(error);
|
|
509
|
-
// console.error(error.graphQLErrors?.[0]?.extensions?.internal);
|
|
510
|
-
throw error;
|
|
511
|
-
});
|
|
673
|
+
async delete(params) {
|
|
674
|
+
const part = this.getQueryBuilder().parts.mutations.delete_.build(params);
|
|
675
|
+
return this.hasura.mutateByQueryPart(part).then(() => { });
|
|
512
676
|
}
|
|
513
677
|
async deleteMany(params) {
|
|
514
|
-
const
|
|
515
|
-
|
|
516
|
-
mutation deleteMany($ids: [String!]!) {
|
|
517
|
-
${mutationName}(where: {id: {_in: $ids}}) {
|
|
518
|
-
affected_rows
|
|
519
|
-
}
|
|
520
|
-
}
|
|
521
|
-
`;
|
|
522
|
-
const client = await lastValueFrom(this.hasura.getApolloClient());
|
|
523
|
-
return client.mutate({
|
|
524
|
-
mutation,
|
|
525
|
-
variables: { ids: params.map(param => param.id) },
|
|
526
|
-
}).then((result) => result.data[mutationName].affected_rows).catch((error) => {
|
|
527
|
-
console.error(error.graphQLErrors);
|
|
528
|
-
throw error;
|
|
529
|
-
});
|
|
678
|
+
const part = this.getQueryBuilder().parts.mutations.delete_.buildMany(params);
|
|
679
|
+
return this.hasura.mutateByQueryPart(part).then((result) => result.affected_rows);
|
|
530
680
|
}
|
|
531
681
|
async deleteAll() {
|
|
532
|
-
const
|
|
533
|
-
return
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
682
|
+
const part = this.getQueryBuilder().parts.mutations.delete_.buildAll();
|
|
683
|
+
return this.hasura.mutateByQueryPart(part).then(() => { });
|
|
684
|
+
}
|
|
685
|
+
async save(data) {
|
|
686
|
+
const item = this.converter.toHasura(data);
|
|
687
|
+
const part = this.getQueryBuilder().parts.mutations.save.build(item);
|
|
688
|
+
return this.hasura.mutateByQueryPart(part).then((res) => res.returning[0]);
|
|
689
|
+
}
|
|
690
|
+
async saveMany(entities) {
|
|
691
|
+
const items = this.converter.toHasuraMany(entities);
|
|
692
|
+
const part = this.getQueryBuilder().parts.mutations.save.buildMany(items);
|
|
693
|
+
return this.hasura.mutateByQueryPart(part).then(() => { });
|
|
539
694
|
}
|
|
540
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.4", ngImport: i0, type: HasuraRepository, deps:
|
|
695
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.4", ngImport: i0, type: HasuraRepository, deps: null, target: i0.ɵɵFactoryTarget.Injectable });
|
|
541
696
|
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.1.4", ngImport: i0, type: HasuraRepository });
|
|
542
697
|
}
|
|
543
698
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.4", ngImport: i0, type: HasuraRepository, decorators: [{
|
|
@@ -548,5 +703,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.4", ngImpor
|
|
|
548
703
|
* Generated bundle index. Do not edit.
|
|
549
704
|
*/
|
|
550
705
|
|
|
551
|
-
export { ApolloMultiService, GET_APOLLO_CLIENT, HASURA_CONFIG, Hasura, HasuraInterceptor, HasuraRepository, HasuraService, HasuraUtils, deepCamelToSnakeCase, deepSnakeToCamelCase, fromHasura, getConverter, getFields, getFlattenFieldAnnotations, makeConverter,
|
|
706
|
+
export { ApolloMultiService, GET_APOLLO_CLIENT, HASURA_CONFIG, Hasura, HasuraInterceptor, HasuraQueryBuilder, HasuraRepository, HasuraService, HasuraUtils, deepCamelToSnakeCase, deepSnakeToCamelCase, fromHasura, getConverter, getFields, getFlattenFieldAnnotations, makeConverter, provideApolloOptions, provideGraphqlHeaders, provideHasura, provideHasuraAuthorization, provideHasuraConfig, provideHasuraWithWebSocket, provideHttpLink, provideWebsocketLink, toHasura };
|
|
552
707
|
//# sourceMappingURL=nx-ddd-hasura.mjs.map
|