@nx-ddd/hasura 19.0.0-preview.24 → 19.0.0-preview.26

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.
@@ -1,18 +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, firstValueFrom, filter, distinctUntilChanged, tap, switchMap, lastValueFrom, map } from 'rxjs';
12
- import { camelCase, snakeCase, isObject, mapKeys, mapValues, get, omitBy, omit, pick } from 'lodash-es';
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
15
  import { format } from 'date-fns';
16
+ import { Repository } from '@nx-ddd/common/domain';
16
17
  export { TransformToDayjs } from '@nx-ddd/common/domain';
17
18
  export { IsDayjs } from 'class-validator-extended';
18
19
 
@@ -21,7 +22,7 @@ function wrap(token) {
21
22
  }
22
23
  function resolve(getHeaders) {
23
24
  const headers$ = wrap(getHeaders());
24
- return firstValueFrom(headers$.pipe(filter((headers) => !!headers), distinctUntilChanged(), tap((headers) => console.debug('[resolve] headers:', headers))));
25
+ return lastValueFrom(headers$.pipe(filter((headers) => !!headers), take(1), distinctUntilChanged(), tap((headers) => console.debug('[resolve] headers:', headers))));
25
26
  }
26
27
  function buildWebsocketLink(endpoint, getHeaders) {
27
28
  return new WebSocketLink({
@@ -76,7 +77,7 @@ const { createDecorator, getAnnotations, } = makeDecoratorFactories((type, field
76
77
  function getFlattenFieldAnnotations(T, prefix = '') {
77
78
  const annotations = Hasura.getAnnotations(T);
78
79
  return (annotations ?? []).reduce((acc, annotation) => {
79
- const currentKey = prefix ? camelCase(`${prefix}_${annotation.fieldName}`) : annotation.fieldName;
80
+ const currentKey = prefix ? camelCase$1(`${prefix}_${annotation.fieldName}`) : annotation.fieldName;
80
81
  if (annotation.childType) {
81
82
  return {
82
83
  ...acc,
@@ -94,7 +95,7 @@ function getFields(T, options = {
94
95
  case: 'snake'
95
96
  }) {
96
97
  const annotations = Hasura.getAnnotations(T);
97
- const changeCase = options?.case === 'snake' ? snakeCase : camelCase;
98
+ const changeCase = options?.case === 'snake' ? snakeCase : camelCase$1;
98
99
  const fields = (annotations ?? []).flatMap((annotation) => {
99
100
  const currentKey = changeCase(options?.prefix ? `${options?.prefix}_${annotation.fieldName}` : annotation.fieldName);
100
101
  if (annotation.childType) {
@@ -147,20 +148,34 @@ function provideHasuraConfig(config) {
147
148
  }
148
149
 
149
150
  function deepCamelToSnakeCase(obj) {
150
- if (Array.isArray(obj)) {
151
+ if (Array.isArray(obj))
151
152
  return obj.map(deepCamelToSnakeCase);
152
- }
153
- else if (isObject(obj)) {
154
- return mapKeys(mapValues(obj, deepCamelToSnakeCase), (_, key) => snakeCase(key));
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;
155
162
  }
156
163
  return obj;
157
164
  }
165
+ function camelCase(str) {
166
+ return str.replace(/_([a-z])/g, (_, letter) => letter.toUpperCase());
167
+ }
158
168
  function deepSnakeToCamelCase(obj) {
159
- if (Array.isArray(obj)) {
169
+ if (Array.isArray(obj))
160
170
  return obj.map(deepSnakeToCamelCase);
161
- }
162
- else if (isObject(obj)) {
163
- return mapKeys(mapValues(obj, deepSnakeToCamelCase), (_, key) => key.replace(/_([a-z])/g, (g) => g[1].toUpperCase()));
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;
164
179
  }
165
180
  return obj;
166
181
  }
@@ -201,7 +216,10 @@ class HasuraUtils {
201
216
  }
202
217
  }
203
218
  static toDate(date) {
204
- if (dayjs.isDayjs(date)) {
219
+ if (typeof date === 'undefined') {
220
+ return undefined;
221
+ }
222
+ else if (dayjs.isDayjs(date)) {
205
223
  return format(date.toDate(), 'yyyy-MM-dd');
206
224
  }
207
225
  else if (date instanceof Date) {
@@ -218,16 +236,23 @@ class HasuraUtils {
218
236
  const object = deepSnakeToCamelCase(_object);
219
237
  return plainToInstanceWithValid(type, object);
220
238
  }
239
+ static toNumber(value) {
240
+ if (typeof value === 'undefined')
241
+ return undefined;
242
+ return isNaN(Number(value)) ? null : Number(value);
243
+ }
221
244
  static toHasura(object, type, { extraFunc = deepCamelToSnakeCase } = {}) {
222
245
  const fields = getFlattenFieldAnnotations(type);
223
246
  const obj = Object.entries(fields).reduce((acc, [key, annotation]) => {
224
247
  const value = get(object, annotation.fieldName);
248
+ if (typeof value === 'undefined')
249
+ return acc;
225
250
  switch (annotation.type) {
226
251
  case 'text': return { ...acc, [key]: value };
227
252
  case 'timestamp': return { ...acc, [key]: this.toTimestamp(value) };
228
253
  case 'date': return { ...acc, [key]: this.toDate(value) };
229
- case 'numeric': return { ...acc, [key]: isNaN(Number(value)) ? null : Number(value) };
230
- case 'integer': return { ...acc, [key]: isNaN(Number(value)) ? null : Number(value) };
254
+ case 'numeric': return { ...acc, [key]: this.toNumber(value) };
255
+ case 'integer': return { ...acc, [key]: this.toNumber(value) };
231
256
  case 'json': return { ...acc, [key]: value };
232
257
  case 'map': return { ...acc };
233
258
  default: return { ...acc, [key]: value };
@@ -297,6 +322,231 @@ function provideHasuraWithWebSocket(config) {
297
322
  ];
298
323
  }
299
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
+
300
550
  class HasuraService {
301
551
  http = inject(HttpClient);
302
552
  apollo = inject(Apollo);
@@ -315,18 +565,51 @@ class HasuraService {
315
565
  return of(clientOrObsOrPromise);
316
566
  }
317
567
  }
568
+ /** @deprecated */
318
569
  graphql(args) {
319
570
  return this.post('/v1/graphql', {
320
571
  query: args.query,
321
572
  variables: args.variables,
322
573
  });
323
574
  }
575
+ /** @deprecated */
324
576
  post(endpoint, body) {
325
577
  return this.http.post(`${this.config.url}${endpoint}`, body, {});
326
578
  }
579
+ /** @deprecated */
327
580
  delete(endpoint) {
328
581
  return this.http.delete(`${this.config.url}${endpoint}`);
329
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
+ }
330
613
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.4", ngImport: i0, type: HasuraService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
331
614
  static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.1.4", ngImport: i0, type: HasuraService, providedIn: 'root' });
332
615
  }
@@ -335,231 +618,81 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.4", ngImpor
335
618
  args: [{ providedIn: 'root' }]
336
619
  }] });
337
620
 
338
- function makeSubscription(query) {
339
- const { kind, definitions } = query;
340
- const subscriptionDefinitions = definitions.map((definition) => {
341
- if (definition.kind === 'OperationDefinition' && definition.operation === 'query') {
342
- return {
343
- ...definition,
344
- operation: 'subscription',
345
- };
346
- }
347
- return definition;
348
- });
349
- return { kind, definitions: subscriptionDefinitions };
350
- }
351
- ;
352
- class HasuraRepository {
621
+ class HasuraRepository extends Repository {
353
622
  hasura = inject(HasuraService);
354
- subscribe({ query, variables }) {
355
- return this.hasura.getApolloClient().pipe(switchMap((client) => client.subscribe({
356
- query: makeSubscription(query),
357
- variables: variables,
358
- })));
359
- }
360
623
  get pkey() {
361
624
  return `${this.tableName}_pkey`;
362
625
  }
626
+ getQueryBuilder() {
627
+ return new HasuraQueryBuilder({ tableName: this.tableName, pk: this.pkey, columns: this.updateColumns });
628
+ }
363
629
  async get(params) {
364
- const queryName = `${this.tableName}_by_pk`;
365
- return lastValueFrom(this.hasura.getApolloClient()).then((client) => client.query({
366
- query: gql `query get($id: String!) {
367
- ${queryName}(id: $id) {
368
- ${this.updateColumns.join(' ')}
369
- }
370
- }`,
371
- variables: params,
372
- })).then((res => res.data[queryName])).then(data => data ? this.converter.fromHasura(data) : data);
373
- }
374
- get listQuery() {
375
- return `query list {
376
- ${this.tableName} {
377
- ${this.updateColumns.join(' ')}
378
- }
379
- }`;
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);
380
638
  }
381
639
  async list() {
382
- const client = await lastValueFrom(this.hasura.getApolloClient());
383
- return client.query({
384
- query: gql `${this.listQuery}`,
385
- }).then(res => this.converter.fromHasuraMany(res.data[this.tableName]));
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]));
386
645
  }
387
646
  listChanges() {
388
- return this.subscribe({
389
- query: gql `${this.listQuery}`,
390
- variables: {},
391
- }).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])));
392
650
  }
393
651
  async create(data) {
394
- const mutationName = `insert_${this.tableName}`;
395
- const mutation = gql `mutation create($object: ${this.tableName}_insert_input!) {
396
- ${mutationName}(objects: [$object]) {
397
- affected_rows
398
- returning {
399
- ${this.updateColumns.join(' ')}
400
- }
401
- }
402
- }`;
403
- const object = omitBy(omit(this.converter.toHasura(data), ['createdAt', 'updatedAt', 'created_at', 'updated_at']), value => typeof value === 'undefined');
404
- const client = await lastValueFrom(this.hasura.getApolloClient());
405
- return client.mutate({
406
- mutation,
407
- variables: { object },
408
- }).then(result => {
409
- return this.converter.fromHasura(result.data[mutationName].returning[0]);
410
- }).catch(error => {
411
- console.error(error.graphQLErrors);
412
- throw error;
413
- });
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]));
414
655
  }
415
656
  async createMany(data) {
416
- const mutationName = `insert_${this.tableName}`;
417
- const objects = data.map((item) => this.converter.toHasura(item));
418
- const mutation = gql `
419
- mutation createMany($objects: [${this.tableName}_insert_input!]!) {
420
- ${mutationName}(objects: $objects) {
421
- returning {
422
- ${this.updateColumns.join(" ")}
423
- }
424
- }
425
- }
426
- `;
427
- const client = await lastValueFrom(this.hasura.getApolloClient());
428
- return client.mutate({
429
- mutation,
430
- variables: { objects },
431
- }).then((result) => this.converter.fromHasuraMany(result.data[mutationName].returning)).catch((error) => {
432
- console.error(error.graphQLErrors);
433
- throw error;
434
- });
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));
435
660
  }
436
661
  async update(data) {
437
- const mutation = gql `mutation update($id: String!, $object: ${this.tableName}_set_input!) {
438
- update_${this.tableName}(where: {id: {_eq: $id}}, _set: $object) { affected_rows }
439
- }`;
440
- const fields = Object.keys(data).map(snakeCase);
441
- const object = omitBy(omit(pick(this.converter.toHasura(data), fields), ['createdAt', 'updatedAt', 'created_at', 'updated_at']), value => typeof value === 'undefined');
442
- const client = await lastValueFrom(this.hasura.getApolloClient());
443
- console.debug('[Hasura Repository] update:', object);
444
- return client.mutate({
445
- mutation,
446
- variables: {
447
- id: data.id,
448
- object,
449
- },
450
- }).catch(error => {
451
- console.error(error.graphQLErrors);
452
- throw error;
453
- });
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(() => { });
454
667
  }
455
668
  async updateMany(data) {
456
- const mutationName = `update_${this.tableName}_many`;
457
- const objects = data.map((item) => {
458
- const fields = Object.keys(item).map(snakeCase);
459
- const object = pick(this.converter.toHasura(item), fields);
460
- return { where: { id: { _eq: item.id } }, _set: object };
461
- });
462
- const mutation = gql `
463
- mutation ${mutationName}($objects: [${this.tableName}_updates!]!) {
464
- ${mutationName}(updates: $objects) {
465
- affected_rows
466
- }
467
- }
468
- `;
469
- const client = await lastValueFrom(this.hasura.getApolloClient());
470
- return client
471
- .mutate({ mutation, variables: { objects } })
472
- .then((result) => result.data[mutationName].affected_rows)
473
- .catch((error) => {
474
- console.error(error.graphQLErrors);
475
- throw error;
476
- });
477
- }
478
- async delete(id) {
479
- const client = await lastValueFrom(this.hasura.getApolloClient());
480
- return client.mutate({
481
- mutation: gql `mutation delete($id: String!) {
482
- delete_${this.tableName}(where: {id: {_eq: $id}}) { affected_rows }
483
- }`,
484
- variables: { id },
485
- }).catch(error => {
486
- console.error(error.graphQLErrors);
487
- throw error;
488
- });
489
- }
490
- async save(data) {
491
- const object = omit(this.converter.toHasura(data), ['createdAt', 'updatedAt']);
492
- const query = gql `mutation upsert($object: [${this.tableName}_insert_input!]!) {
493
- insert_${this.tableName}(
494
- objects: $object,
495
- on_conflict: {
496
- constraint: ${this.pkey},
497
- update_columns: [${this.updateColumns}]
498
- }
499
- ) { affected_rows }
500
- }`;
501
- const client = await lastValueFrom(this.hasura.getApolloClient());
502
- console.debug('[Hasura Repository] save:', client);
503
- return client.mutate({
504
- mutation: query,
505
- variables: {
506
- object: object,
507
- },
508
- }).catch(error => {
509
- console.error(error.graphQLErrors);
510
- throw error;
511
- });
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(() => { });
512
672
  }
513
- async saveMany(entities) {
514
- const query = gql `mutation upsert($objects: [${this.tableName}_insert_input!]!) {
515
- insert_${this.tableName}(
516
- objects: $objects,
517
- on_conflict: {
518
- constraint: ${this.pkey},
519
- update_columns: [${this.updateColumns}]
520
- }
521
- ) { affected_rows }
522
- }`;
523
- const objects = entities.map(entity => this.converter.toHasura(entity));
524
- console.debug('[Hasura Repository] objects:', objects);
525
- const client = await lastValueFrom(this.hasura.getApolloClient());
526
- return client.mutate({
527
- mutation: query,
528
- variables: { objects },
529
- }).catch(error => {
530
- console.error(error);
531
- // console.error(error.graphQLErrors?.[0]?.extensions?.internal);
532
- throw error;
533
- });
673
+ async delete(params) {
674
+ const part = this.getQueryBuilder().parts.mutations.delete_.build(params);
675
+ return this.hasura.mutateByQueryPart(part).then(() => { });
534
676
  }
535
677
  async deleteMany(params) {
536
- const mutationName = `delete_${this.tableName}`;
537
- const mutation = gql `
538
- mutation deleteMany($ids: [String!]!) {
539
- ${mutationName}(where: {id: {_in: $ids}}) {
540
- affected_rows
541
- }
542
- }
543
- `;
544
- const client = await lastValueFrom(this.hasura.getApolloClient());
545
- return client.mutate({
546
- mutation,
547
- variables: { ids: params.map(param => param.id) },
548
- }).then((result) => result.data[mutationName].affected_rows).catch((error) => {
549
- console.error(error.graphQLErrors);
550
- throw error;
551
- });
678
+ const part = this.getQueryBuilder().parts.mutations.delete_.buildMany(params);
679
+ return this.hasura.mutateByQueryPart(part).then((result) => result.affected_rows);
552
680
  }
553
681
  async deleteAll() {
554
- const client = await lastValueFrom(this.hasura.getApolloClient());
555
- return client.mutate({
556
- mutation: gql `mutation delete_all {
557
- delete_${this.tableName} (where: {}) { affected_rows }
558
- }`,
559
- variables: {},
560
- });
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(() => { });
561
694
  }
562
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.4", ngImport: i0, type: HasuraRepository, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
695
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.4", ngImport: i0, type: HasuraRepository, deps: null, target: i0.ɵɵFactoryTarget.Injectable });
563
696
  static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.1.4", ngImport: i0, type: HasuraRepository });
564
697
  }
565
698
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.4", ngImport: i0, type: HasuraRepository, decorators: [{
@@ -570,5 +703,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.4", ngImpor
570
703
  * Generated bundle index. Do not edit.
571
704
  */
572
705
 
573
- export { ApolloMultiService, GET_APOLLO_CLIENT, HASURA_CONFIG, Hasura, HasuraInterceptor, HasuraRepository, HasuraService, HasuraUtils, deepCamelToSnakeCase, deepSnakeToCamelCase, fromHasura, getConverter, getFields, getFlattenFieldAnnotations, makeConverter, makeSubscription, provideApolloOptions, provideGraphqlHeaders, provideHasura, provideHasuraAuthorization, provideHasuraConfig, provideHasuraWithWebSocket, provideHttpLink, provideWebsocketLink, toHasura };
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 };
574
707
  //# sourceMappingURL=nx-ddd-hasura.mjs.map