@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.
@@ -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, 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
+ 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 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))));
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
- else if (isObject(obj)) {
153
- 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;
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
- else if (isObject(obj)) {
162
- 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;
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 (!dayjs.isDayjs(date))
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
- return date.toISOString();
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 'numeric': return { ...acc, [key]: isNaN(Number(value)) ? null : Number(value) };
208
- case 'integer': return { ...acc, [key]: isNaN(Number(value)) ? null : Number(value) };
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
- function makeSubscription(query) {
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 queryName = `${this.tableName}_by_pk`;
343
- return lastValueFrom(this.hasura.getApolloClient()).then((client) => client.query({
344
- query: gql `query get($id: String!) {
345
- ${queryName}(id: $id) {
346
- ${this.updateColumns.join(' ')}
347
- }
348
- }`,
349
- variables: params,
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 client = await lastValueFrom(this.hasura.getApolloClient());
361
- return client.query({
362
- query: gql `${this.listQuery}`,
363
- }).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]));
364
645
  }
365
646
  listChanges() {
366
- return this.subscribe({
367
- query: gql `${this.listQuery}`,
368
- variables: {},
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 mutationName = `insert_${this.tableName}`;
373
- const mutation = gql `mutation create($object: ${this.tableName}_insert_input!) {
374
- ${mutationName}(objects: [$object]) {
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 mutationName = `insert_${this.tableName}`;
395
- const objects = data.map((item) => this.converter.toHasura(item));
396
- const mutation = gql `
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
- const mutation = gql `mutation update($id: String!, $object: ${this.tableName}_set_input!) {
416
- update_${this.tableName}(where: {id: {_eq: $id}}, _set: $object) { affected_rows }
417
- }`;
418
- const fields = Object.keys(data).map(snakeCase);
419
- const object = omitBy(omit(pick(this.converter.toHasura(data), fields), ['createdAt', 'updatedAt', 'created_at', 'updated_at']), value => typeof value === 'undefined');
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 mutationName = `update_${this.tableName}_many`;
435
- const objects = data.map((item) => {
436
- const fields = Object.keys(item).map(snakeCase);
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 saveMany(entities) {
492
- const query = gql `mutation upsert($objects: [${this.tableName}_insert_input!]!) {
493
- insert_${this.tableName}(
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 mutationName = `delete_${this.tableName}`;
515
- const mutation = gql `
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 client = await lastValueFrom(this.hasura.getApolloClient());
533
- return client.mutate({
534
- mutation: gql `mutation delete_all {
535
- delete_${this.tableName} (where: {}) { affected_rows }
536
- }`,
537
- variables: {},
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: [], 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 });
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, 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 };
552
707
  //# sourceMappingURL=nx-ddd-hasura.mjs.map