@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.
- 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 +354 -221
- package/fesm2022/nx-ddd-hasura.mjs.map +1 -1
- package/hasura.converter.d.ts +13 -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,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,
|
|
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
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
|
|
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
|
-
|
|
154
|
-
|
|
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
|
-
|
|
163
|
-
|
|
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 (
|
|
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]:
|
|
230
|
-
case 'integer': return { ...acc, [key]:
|
|
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
|
-
|
|
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
|
|
365
|
-
return
|
|
366
|
-
query: gql
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
}
|
|
370
|
-
|
|
371
|
-
|
|
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
|
|
383
|
-
return
|
|
384
|
-
query: gql `${this.
|
|
385
|
-
|
|
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
|
-
|
|
389
|
-
|
|
390
|
-
|
|
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
|
|
395
|
-
const
|
|
396
|
-
|
|
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
|
|
417
|
-
const
|
|
418
|
-
|
|
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
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
const
|
|
441
|
-
|
|
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
|
|
457
|
-
const
|
|
458
|
-
|
|
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
|
|
514
|
-
const
|
|
515
|
-
|
|
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
|
|
537
|
-
|
|
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
|
|
555
|
-
return
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
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:
|
|
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,
|
|
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
|