@burojs/hasura 0.4.0 → 0.5.0
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/README.md +15 -16
- package/dist/index.cjs +125 -46
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +36 -17
- package/dist/index.d.ts +36 -17
- package/dist/index.js +125 -47
- package/dist/index.js.map +1 -1
- package/package.json +4 -3
package/dist/index.d.cts
CHANGED
|
@@ -28,22 +28,16 @@ interface HasuraDataProviderConfig {
|
|
|
28
28
|
* with a newly obtained token, while false preserves the original 401
|
|
29
29
|
* response.
|
|
30
30
|
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
* `recoverAuth` is
|
|
39
|
-
*
|
|
40
|
-
* `tests/fixture-fidelity.test.ts`'s `error-unauthorized` case.
|
|
41
|
-
*
|
|
42
|
-
* So this callback fires only for a deployment that really answers 401 (a
|
|
43
|
-
* proxy or gateway in front of Hasura, typically). Keying recovery on the
|
|
44
|
-
* error envelope instead is a product decision, deliberately not taken here;
|
|
45
|
-
* the existing 401 tests use a FABRICATED 401 and must not be read as proof
|
|
46
|
-
* that recovery works against Hasura itself.
|
|
31
|
+
* HTTP 401 is what a proxy or gateway in front of Hasura answers. Hasura
|
|
32
|
+
* itself rejects a credential with **HTTP 200** and an `invalid-jwt` errors
|
|
33
|
+
* envelope (`packages/mock-kit/fixtures/hasura/error-unauthorized.json`,
|
|
34
|
+
* captured from a live backend). This provider reports that envelope as
|
|
35
|
+
* `{ kind: 'auth', code: 'invalid-jwt' }`. When the app has an
|
|
36
|
+
* `authProvider`, the runtime hands it that error; if the provider chooses
|
|
37
|
+
* to refresh, a read is replayed once, and a mutation once when it is
|
|
38
|
+
* replay-safe. `recoverAuth` is
|
|
39
|
+
* not consulted for the envelope, so one rejection is never refreshed twice.
|
|
40
|
+
* Pinned by `tests/fixture-fidelity.test.ts`'s `error-unauthorized` case.
|
|
47
41
|
*/
|
|
48
42
|
recoverAuth?: () => Promise<boolean>;
|
|
49
43
|
/** Map our resource name → table + field selection. */
|
|
@@ -397,6 +391,31 @@ declare function flattenJsonbSpill(item: unknown, spill: JsonbSpillConfig): unkn
|
|
|
397
391
|
* stable symbol.
|
|
398
392
|
*/
|
|
399
393
|
declare const NOT_AUTHENTICATED_CODE = "not-authenticated";
|
|
394
|
+
/**
|
|
395
|
+
* The envelope codes with which Hasura reports a failure of work it ran OUTSIDE its own
|
|
396
|
+
* transaction — an Action's webhook or a remote schema — on a custom mutation. Such a side effect
|
|
397
|
+
* may have happened before the failure, so a custom mutation answered with one of them is
|
|
398
|
+
* `sent` (spec 4.7, P4-20). A table mutation keeps `protocol/graphql-error` for them: Hasura
|
|
399
|
+
* rolled its transaction back.
|
|
400
|
+
*
|
|
401
|
+
* Spellings confirmed against the Hasura GraphQL Engine v2 source, `instance ToJSON Code` in
|
|
402
|
+
* `server/lib/hasura-base/src/Hasura/Base/Error.hs` (hasura/graphql-engine@0a1dd53b):
|
|
403
|
+
* `Unexpected -> "unexpected"`, `RemoteSchemaError -> "remote-schema-error"`,
|
|
404
|
+
* `ParseFailed -> "parse-failed"`. Action failures are raised in
|
|
405
|
+
* `server/src-lib/Hasura/GraphQL/Execute/Action.hs`: an HTTP exception calling the webhook, a
|
|
406
|
+
* webhook 5xx, an unparsable webhook answer and a failed request or response transform are all
|
|
407
|
+
* `throw500…`, i.e. `unexpected`; a webhook that answered 2xx (its side effect done) with JSON
|
|
408
|
+
* that does not decode fails in `decodeValue` (`Action.hs:793`), which raises `ParseFailed`
|
|
409
|
+
* through `liftIResult` (`Error.hs:424`), i.e. `parse-failed`. Hasura has no
|
|
410
|
+
* `action-webhook-error` or `http-exception` code; a webhook's own 4xx answer carries the code
|
|
411
|
+
* the webhook chose (`ActionWebhookCode`), or `unexpected` when it chose none, and only that
|
|
412
|
+
* last case is caught here — a webhook-chosen code is the handler's own definite answer.
|
|
413
|
+
*
|
|
414
|
+
* Hasura gives no marker telling an Action-backed or remote-schema mutation apart from any
|
|
415
|
+
* other registered `operations` document, so every custom mutation is treated this way
|
|
416
|
+
* (fail-safe: a wrongly `sent` answer costs a "may have been applied" screen, never a duplicate).
|
|
417
|
+
*/
|
|
418
|
+
declare const HASURA_EXTERNAL_FAILURE_CODES: ReadonlySet<string>;
|
|
400
419
|
/**
|
|
401
420
|
* Refusal code for "this mapping declares a `localeField` but the descriptor
|
|
402
421
|
* carries no locale". Exported so an application can match a symbol rather
|
|
@@ -752,5 +771,5 @@ declare function hasuraWsUrl(endpoint: string): string;
|
|
|
752
771
|
*/
|
|
753
772
|
declare function createHasuraLiveProvider(config: HasuraLiveProviderConfig): DataLiveProvider;
|
|
754
773
|
//#endregion
|
|
755
|
-
export { type CursorOrderingColumn, DEFAULT_HASURA_ENDPOINT, type DataBodyConfig, FILTER_OPERATOR_UNSUPPORTED_CODE, HASURA_CURSOR_CODES, type HasuraCustomOperation, type HasuraDataProviderConfig, type HasuraLiveProviderConfig, type HasuraOperationRegistry, type JsonbSpillConfig, LOCALE_REQUIRED_CODE, NOT_AUTHENTICATED_CODE, type ResourceMapping, aggregateRoot, assertCursorLimit, assertCursorOrderable, byPkRoot, coerceInt64Filter, createHasuraDataProvider, createHasuraLiveProvider, decodeCursor, effectiveCursorOrdering, encodeCursor, filtersToWhere, flattenJsonbSpill, hasuraWsUrl, keysetWhere, localeWhere, mergeWhere, orderingSignature, partitionDataBody, partitionJsonbSpill, scopeToWhere };
|
|
774
|
+
export { type CursorOrderingColumn, DEFAULT_HASURA_ENDPOINT, type DataBodyConfig, FILTER_OPERATOR_UNSUPPORTED_CODE, HASURA_CURSOR_CODES, HASURA_EXTERNAL_FAILURE_CODES, type HasuraCustomOperation, type HasuraDataProviderConfig, type HasuraLiveProviderConfig, type HasuraOperationRegistry, type JsonbSpillConfig, LOCALE_REQUIRED_CODE, NOT_AUTHENTICATED_CODE, type ResourceMapping, aggregateRoot, assertCursorLimit, assertCursorOrderable, byPkRoot, coerceInt64Filter, createHasuraDataProvider, createHasuraLiveProvider, decodeCursor, effectiveCursorOrdering, encodeCursor, filtersToWhere, flattenJsonbSpill, hasuraWsUrl, keysetWhere, localeWhere, mergeWhere, orderingSignature, partitionDataBody, partitionJsonbSpill, scopeToWhere };
|
|
756
775
|
//# sourceMappingURL=index.d.cts.map
|
package/dist/index.d.ts
CHANGED
|
@@ -28,22 +28,16 @@ interface HasuraDataProviderConfig {
|
|
|
28
28
|
* with a newly obtained token, while false preserves the original 401
|
|
29
29
|
* response.
|
|
30
30
|
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
* `recoverAuth` is
|
|
39
|
-
*
|
|
40
|
-
* `tests/fixture-fidelity.test.ts`'s `error-unauthorized` case.
|
|
41
|
-
*
|
|
42
|
-
* So this callback fires only for a deployment that really answers 401 (a
|
|
43
|
-
* proxy or gateway in front of Hasura, typically). Keying recovery on the
|
|
44
|
-
* error envelope instead is a product decision, deliberately not taken here;
|
|
45
|
-
* the existing 401 tests use a FABRICATED 401 and must not be read as proof
|
|
46
|
-
* that recovery works against Hasura itself.
|
|
31
|
+
* HTTP 401 is what a proxy or gateway in front of Hasura answers. Hasura
|
|
32
|
+
* itself rejects a credential with **HTTP 200** and an `invalid-jwt` errors
|
|
33
|
+
* envelope (`packages/mock-kit/fixtures/hasura/error-unauthorized.json`,
|
|
34
|
+
* captured from a live backend). This provider reports that envelope as
|
|
35
|
+
* `{ kind: 'auth', code: 'invalid-jwt' }`. When the app has an
|
|
36
|
+
* `authProvider`, the runtime hands it that error; if the provider chooses
|
|
37
|
+
* to refresh, a read is replayed once, and a mutation once when it is
|
|
38
|
+
* replay-safe. `recoverAuth` is
|
|
39
|
+
* not consulted for the envelope, so one rejection is never refreshed twice.
|
|
40
|
+
* Pinned by `tests/fixture-fidelity.test.ts`'s `error-unauthorized` case.
|
|
47
41
|
*/
|
|
48
42
|
recoverAuth?: () => Promise<boolean>;
|
|
49
43
|
/** Map our resource name → table + field selection. */
|
|
@@ -397,6 +391,31 @@ declare function flattenJsonbSpill(item: unknown, spill: JsonbSpillConfig): unkn
|
|
|
397
391
|
* stable symbol.
|
|
398
392
|
*/
|
|
399
393
|
declare const NOT_AUTHENTICATED_CODE = "not-authenticated";
|
|
394
|
+
/**
|
|
395
|
+
* The envelope codes with which Hasura reports a failure of work it ran OUTSIDE its own
|
|
396
|
+
* transaction — an Action's webhook or a remote schema — on a custom mutation. Such a side effect
|
|
397
|
+
* may have happened before the failure, so a custom mutation answered with one of them is
|
|
398
|
+
* `sent` (spec 4.7, P4-20). A table mutation keeps `protocol/graphql-error` for them: Hasura
|
|
399
|
+
* rolled its transaction back.
|
|
400
|
+
*
|
|
401
|
+
* Spellings confirmed against the Hasura GraphQL Engine v2 source, `instance ToJSON Code` in
|
|
402
|
+
* `server/lib/hasura-base/src/Hasura/Base/Error.hs` (hasura/graphql-engine@0a1dd53b):
|
|
403
|
+
* `Unexpected -> "unexpected"`, `RemoteSchemaError -> "remote-schema-error"`,
|
|
404
|
+
* `ParseFailed -> "parse-failed"`. Action failures are raised in
|
|
405
|
+
* `server/src-lib/Hasura/GraphQL/Execute/Action.hs`: an HTTP exception calling the webhook, a
|
|
406
|
+
* webhook 5xx, an unparsable webhook answer and a failed request or response transform are all
|
|
407
|
+
* `throw500…`, i.e. `unexpected`; a webhook that answered 2xx (its side effect done) with JSON
|
|
408
|
+
* that does not decode fails in `decodeValue` (`Action.hs:793`), which raises `ParseFailed`
|
|
409
|
+
* through `liftIResult` (`Error.hs:424`), i.e. `parse-failed`. Hasura has no
|
|
410
|
+
* `action-webhook-error` or `http-exception` code; a webhook's own 4xx answer carries the code
|
|
411
|
+
* the webhook chose (`ActionWebhookCode`), or `unexpected` when it chose none, and only that
|
|
412
|
+
* last case is caught here — a webhook-chosen code is the handler's own definite answer.
|
|
413
|
+
*
|
|
414
|
+
* Hasura gives no marker telling an Action-backed or remote-schema mutation apart from any
|
|
415
|
+
* other registered `operations` document, so every custom mutation is treated this way
|
|
416
|
+
* (fail-safe: a wrongly `sent` answer costs a "may have been applied" screen, never a duplicate).
|
|
417
|
+
*/
|
|
418
|
+
declare const HASURA_EXTERNAL_FAILURE_CODES: ReadonlySet<string>;
|
|
400
419
|
/**
|
|
401
420
|
* Refusal code for "this mapping declares a `localeField` but the descriptor
|
|
402
421
|
* carries no locale". Exported so an application can match a symbol rather
|
|
@@ -752,5 +771,5 @@ declare function hasuraWsUrl(endpoint: string): string;
|
|
|
752
771
|
*/
|
|
753
772
|
declare function createHasuraLiveProvider(config: HasuraLiveProviderConfig): DataLiveProvider;
|
|
754
773
|
//#endregion
|
|
755
|
-
export { type CursorOrderingColumn, DEFAULT_HASURA_ENDPOINT, type DataBodyConfig, FILTER_OPERATOR_UNSUPPORTED_CODE, HASURA_CURSOR_CODES, type HasuraCustomOperation, type HasuraDataProviderConfig, type HasuraLiveProviderConfig, type HasuraOperationRegistry, type JsonbSpillConfig, LOCALE_REQUIRED_CODE, NOT_AUTHENTICATED_CODE, type ResourceMapping, aggregateRoot, assertCursorLimit, assertCursorOrderable, byPkRoot, coerceInt64Filter, createHasuraDataProvider, createHasuraLiveProvider, decodeCursor, effectiveCursorOrdering, encodeCursor, filtersToWhere, flattenJsonbSpill, hasuraWsUrl, keysetWhere, localeWhere, mergeWhere, orderingSignature, partitionDataBody, partitionJsonbSpill, scopeToWhere };
|
|
774
|
+
export { type CursorOrderingColumn, DEFAULT_HASURA_ENDPOINT, type DataBodyConfig, FILTER_OPERATOR_UNSUPPORTED_CODE, HASURA_CURSOR_CODES, HASURA_EXTERNAL_FAILURE_CODES, type HasuraCustomOperation, type HasuraDataProviderConfig, type HasuraLiveProviderConfig, type HasuraOperationRegistry, type JsonbSpillConfig, LOCALE_REQUIRED_CODE, NOT_AUTHENTICATED_CODE, type ResourceMapping, aggregateRoot, assertCursorLimit, assertCursorOrderable, byPkRoot, coerceInt64Filter, createHasuraDataProvider, createHasuraLiveProvider, decodeCursor, effectiveCursorOrdering, encodeCursor, filtersToWhere, flattenJsonbSpill, hasuraWsUrl, keysetWhere, localeWhere, mergeWhere, orderingSignature, partitionDataBody, partitionJsonbSpill, scopeToWhere };
|
|
756
775
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.js
CHANGED
|
@@ -342,6 +342,63 @@ function flattenJsonbSpill(item, spill) {
|
|
|
342
342
|
return out;
|
|
343
343
|
}
|
|
344
344
|
const NOT_AUTHENTICATED_CODE = "not-authenticated";
|
|
345
|
+
const FORBIDDEN_CODES = new Set(["access-denied", "permission-error"]);
|
|
346
|
+
const HASURA_EXTERNAL_FAILURE_CODES = new Set([
|
|
347
|
+
"unexpected",
|
|
348
|
+
"remote-schema-error",
|
|
349
|
+
"parse-failed"
|
|
350
|
+
]);
|
|
351
|
+
const MUTATION_REFUSAL_CODES = new Map([["constraint-violation", "conflict"], ["validation-failed", "validation"]]);
|
|
352
|
+
function graphqlError(errors, operation, external) {
|
|
353
|
+
const message = errors.map((e) => e.message).join("; ");
|
|
354
|
+
const codes = errors.flatMap((e) => typeof e.extensions?.code === "string" ? [e.extensions.code] : []);
|
|
355
|
+
if (codes.includes("invalid-jwt")) return {
|
|
356
|
+
kind: "auth",
|
|
357
|
+
code: "invalid-jwt",
|
|
358
|
+
message,
|
|
359
|
+
details: errors
|
|
360
|
+
};
|
|
361
|
+
const outside = operation === "mutation" && external ? codes.find((code) => HASURA_EXTERNAL_FAILURE_CODES.has(code) || MUTATION_REFUSAL_CODES.has(code) || FORBIDDEN_CODES.has(code)) : void 0;
|
|
362
|
+
if (outside !== void 0) return {
|
|
363
|
+
kind: "sent",
|
|
364
|
+
code: outside,
|
|
365
|
+
message,
|
|
366
|
+
retryable: false,
|
|
367
|
+
details: errors
|
|
368
|
+
};
|
|
369
|
+
const forbidden = codes.find((code) => FORBIDDEN_CODES.has(code));
|
|
370
|
+
if (forbidden !== void 0) return {
|
|
371
|
+
kind: "forbidden",
|
|
372
|
+
code: forbidden,
|
|
373
|
+
message,
|
|
374
|
+
details: errors
|
|
375
|
+
};
|
|
376
|
+
if (operation === "mutation") for (const code of codes) {
|
|
377
|
+
const kind = MUTATION_REFUSAL_CODES.get(code);
|
|
378
|
+
if (kind !== void 0) return {
|
|
379
|
+
kind,
|
|
380
|
+
code,
|
|
381
|
+
message,
|
|
382
|
+
details: errors
|
|
383
|
+
};
|
|
384
|
+
}
|
|
385
|
+
return {
|
|
386
|
+
kind: "protocol",
|
|
387
|
+
code: "graphql-error",
|
|
388
|
+
message,
|
|
389
|
+
details: errors
|
|
390
|
+
};
|
|
391
|
+
}
|
|
392
|
+
function answerLost(code, message, status, cause) {
|
|
393
|
+
return {
|
|
394
|
+
kind: "sent",
|
|
395
|
+
code,
|
|
396
|
+
message,
|
|
397
|
+
status,
|
|
398
|
+
retryable: false,
|
|
399
|
+
...cause === void 0 ? {} : { cause }
|
|
400
|
+
};
|
|
401
|
+
}
|
|
345
402
|
const LOCALE_REQUIRED_CODE = "locale-required";
|
|
346
403
|
function localeWhere(m, locale) {
|
|
347
404
|
if (m.localeField === void 0) return void 0;
|
|
@@ -498,8 +555,12 @@ function createHasuraDataProvider(config) {
|
|
|
498
555
|
const operations = snapshotOperationRegistry(config.operations);
|
|
499
556
|
const hasCustomQueries = hasRegisteredOperationKind(operations, "query");
|
|
500
557
|
const hasCustomMutations = hasRegisteredOperationKind(operations, "mutation");
|
|
501
|
-
async function gql(query, variables, role, signal) {
|
|
558
|
+
async function gql(query, variables, role, signal, operation, external = false) {
|
|
502
559
|
try {
|
|
560
|
+
const requestBody = JSON.stringify({
|
|
561
|
+
query,
|
|
562
|
+
variables
|
|
563
|
+
});
|
|
503
564
|
const request = async (token) => {
|
|
504
565
|
const headers = {
|
|
505
566
|
"Content-Type": "application/json",
|
|
@@ -507,15 +568,24 @@ function createHasuraDataProvider(config) {
|
|
|
507
568
|
};
|
|
508
569
|
const effectiveRole = role === void 0 ? defaultRole : normalizeRole(role);
|
|
509
570
|
if (effectiveRole !== null) headers["X-Hasura-Role"] = effectiveRole;
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
})
|
|
571
|
+
const fetchImpl = config.fetchImpl ?? fetch;
|
|
572
|
+
try {
|
|
573
|
+
return await fetchImpl(endpoint, {
|
|
574
|
+
method: "POST",
|
|
575
|
+
headers,
|
|
576
|
+
body: requestBody,
|
|
577
|
+
signal
|
|
578
|
+
});
|
|
579
|
+
} catch (cause) {
|
|
580
|
+
if (operation === "mutation" && !signal.aborted) throw {
|
|
581
|
+
kind: "sent",
|
|
582
|
+
code: "hasura-request-sent",
|
|
583
|
+
message: "Hasura did not answer a mutation; it may have been applied.",
|
|
584
|
+
retryable: false,
|
|
585
|
+
cause
|
|
586
|
+
};
|
|
587
|
+
throw cause;
|
|
588
|
+
}
|
|
519
589
|
};
|
|
520
590
|
let token = await config.getToken();
|
|
521
591
|
if (!token) throw {
|
|
@@ -533,24 +603,32 @@ function createHasuraDataProvider(config) {
|
|
|
533
603
|
};
|
|
534
604
|
res = await request(token);
|
|
535
605
|
}
|
|
536
|
-
if (!res.ok)
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
606
|
+
if (!res.ok) {
|
|
607
|
+
if (operation === "mutation" && res.status >= 500) throw answerLost("hasura-answer-lost", `GraphQL HTTP ${res.status} after a mutation was sent; it may have been applied.`, res.status);
|
|
608
|
+
throw {
|
|
609
|
+
kind: "transport",
|
|
610
|
+
code: "graphql-http-error",
|
|
611
|
+
message: `GraphQL HTTP ${res.status}`,
|
|
612
|
+
status: res.status
|
|
613
|
+
};
|
|
614
|
+
}
|
|
615
|
+
let body;
|
|
616
|
+
try {
|
|
617
|
+
body = await res.json();
|
|
618
|
+
if (body === null || typeof body !== "object") throw new TypeError("The GraphQL answer is not an object.");
|
|
619
|
+
} catch (cause) {
|
|
620
|
+
if (operation === "mutation" && !signal.aborted) throw answerLost("hasura-answer-unreadable", "Hasura answered a mutation with a body that could not be read; it may have been applied.", res.status, cause);
|
|
621
|
+
throw cause;
|
|
622
|
+
}
|
|
623
|
+
if (body.errors?.length) throw graphqlError(body.errors, operation, external);
|
|
624
|
+
if (body.data === void 0) {
|
|
625
|
+
if (operation === "mutation") throw answerLost("hasura-answer-unreadable", "Hasura answered a mutation without data or errors; it may have been applied.", res.status);
|
|
626
|
+
throw {
|
|
627
|
+
kind: "protocol",
|
|
628
|
+
code: "empty-graphql-response",
|
|
629
|
+
message: "Empty GraphQL response."
|
|
630
|
+
};
|
|
631
|
+
}
|
|
554
632
|
return body.data;
|
|
555
633
|
} catch (error) {
|
|
556
634
|
throw hasuraError(error, signal, "Hasura request failed.");
|
|
@@ -576,8 +654,8 @@ function createHasuraDataProvider(config) {
|
|
|
576
654
|
}
|
|
577
655
|
async function executeCustomOperation(resource, operationName, input, kind, signal) {
|
|
578
656
|
const operation = registeredOperation(resource, operationName, kind);
|
|
579
|
-
const result = await gql(operation.document, operation.variables(input), operation.role ?? config.resources[resource]?.role, signal);
|
|
580
|
-
return operation.mapResult
|
|
657
|
+
const result = await gql(operation.document, operation.variables(input), operation.role ?? config.resources[resource]?.role, signal, kind, kind === "mutation");
|
|
658
|
+
return operation.mapResult === void 0 ? result : operation.mapResult(result);
|
|
581
659
|
}
|
|
582
660
|
function composeListWhere(m, descriptor, context) {
|
|
583
661
|
const userWhere = filtersToWhere(coerceInt64Filter(descriptor.filter, m.int64Fields));
|
|
@@ -596,7 +674,7 @@ function createHasuraDataProvider(config) {
|
|
|
596
674
|
}`;
|
|
597
675
|
const aggVars = {};
|
|
598
676
|
if (where) aggVars.where = where;
|
|
599
|
-
return (await gql(metaQuery, where ? aggVars : void 0, m.role, signal)).meta.aggregate.count;
|
|
677
|
+
return (await gql(metaQuery, where ? aggVars : void 0, m.role, signal, "query")).meta.aggregate.count;
|
|
600
678
|
}
|
|
601
679
|
async function upsertDataBody(db, parentId, body, role, signal) {
|
|
602
680
|
await gql(`mutation UpsertDataBody($object: ${db.table}_insert_input!) {
|
|
@@ -607,11 +685,11 @@ function createHasuraDataProvider(config) {
|
|
|
607
685
|
}`, { object: {
|
|
608
686
|
[db.fk]: parentId,
|
|
609
687
|
[db.column]: body
|
|
610
|
-
} }, role, signal);
|
|
688
|
+
} }, role, signal, "mutation");
|
|
611
689
|
}
|
|
612
690
|
function mutationRecord(m, idField, item, resource, expectedId) {
|
|
613
691
|
if (item === null || typeof item !== "object" || Array.isArray(item)) throw {
|
|
614
|
-
kind: "
|
|
692
|
+
kind: "not-found",
|
|
615
693
|
code: "record-not-found",
|
|
616
694
|
message: `Not found: ${resource}`
|
|
617
695
|
};
|
|
@@ -642,11 +720,11 @@ function createHasuraDataProvider(config) {
|
|
|
642
720
|
const where = mergeWhere({ [pkField]: { _eq: id } }, m.fixedFilter);
|
|
643
721
|
return (await gql(`query One_${m.table}($where: ${m.table}_bool_exp) {
|
|
644
722
|
items: ${m.table}(where: $where, limit: 1) { ${fields} }
|
|
645
|
-
}`, { where }, m.role, signal)).items?.[0] ?? null;
|
|
723
|
+
}`, { where }, m.role, signal, "query")).items?.[0] ?? null;
|
|
646
724
|
}
|
|
647
725
|
return (await gql(`query One_${m.table}($id: ${pkType}!) {
|
|
648
726
|
item: ${root}(${pkField}: $id) { ${fields} }
|
|
649
|
-
}`, { id }, m.role, signal)).item;
|
|
727
|
+
}`, { id }, m.role, signal, "query")).item;
|
|
650
728
|
}
|
|
651
729
|
async function listByCursor(m, descriptor, pagination, context) {
|
|
652
730
|
if (pagination.before !== void 0) throw {
|
|
@@ -669,7 +747,7 @@ function createHasuraDataProvider(config) {
|
|
|
669
747
|
}`;
|
|
670
748
|
const itemsVars = { limit: pagination.limit + 1 };
|
|
671
749
|
if (where) itemsVars.where = where;
|
|
672
|
-
const fetched = (await gql(itemsQuery, itemsVars, m.role, context.signal)).items ?? [];
|
|
750
|
+
const fetched = (await gql(itemsQuery, itemsVars, m.role, context.signal, "query")).items ?? [];
|
|
673
751
|
const hasNextPage = fetched.length > pagination.limit;
|
|
674
752
|
const rows = hasNextPage ? fetched.slice(0, pagination.limit) : fetched;
|
|
675
753
|
let total;
|
|
@@ -714,7 +792,7 @@ function createHasuraDataProvider(config) {
|
|
|
714
792
|
offset
|
|
715
793
|
};
|
|
716
794
|
if (where) itemsVars.where = where;
|
|
717
|
-
const itemsData = await gql(itemsQuery, itemsVars, m.role, context.signal);
|
|
795
|
+
const itemsData = await gql(itemsQuery, itemsVars, m.role, context.signal, "query");
|
|
718
796
|
let total;
|
|
719
797
|
const listAggRoot = aggregateRoot(m);
|
|
720
798
|
if (!m.noAggregate && listAggRoot) try {
|
|
@@ -743,7 +821,7 @@ function createHasuraDataProvider(config) {
|
|
|
743
821
|
const fields = m.selectFields.join(" ");
|
|
744
822
|
const data = await gql(`query Many_${m.table}($where: ${m.table}_bool_exp) {
|
|
745
823
|
items: ${m.table}(where: $where) { ${fields} }
|
|
746
|
-
}`, { where }, m.role, context.signal);
|
|
824
|
+
}`, { where }, m.role, context.signal, "query");
|
|
747
825
|
const spill = m.jsonbSpill;
|
|
748
826
|
return { data: spill ? data.items.map((item) => flattenJsonbSpill(item, spill)) : data.items };
|
|
749
827
|
},
|
|
@@ -760,12 +838,12 @@ function createHasuraDataProvider(config) {
|
|
|
760
838
|
const where = mergeWhere(mergeWhere({ [pkField]: { _eq: descriptor.id } }, m.fixedFilter), localeSlice);
|
|
761
839
|
item = (await gql(`query One_${m.table}($where: ${m.table}_bool_exp) {
|
|
762
840
|
items: ${m.table}(where: $where, limit: 1) { ${fields} }
|
|
763
|
-
}`, { where }, m.role, context.signal)).items?.[0] ?? null;
|
|
841
|
+
}`, { where }, m.role, context.signal, "query")).items?.[0] ?? null;
|
|
764
842
|
} else item = (await gql(`query One_${m.table}($id: ${pkType}!) {
|
|
765
843
|
item: ${root}(${pkField}: $id) { ${fields} }
|
|
766
|
-
}`, { id: descriptor.id }, m.role, context.signal)).item;
|
|
844
|
+
}`, { id: descriptor.id }, m.role, context.signal, "query")).item;
|
|
767
845
|
if (item == null) throw {
|
|
768
|
-
kind: "
|
|
846
|
+
kind: "not-found",
|
|
769
847
|
code: "record-not-found",
|
|
770
848
|
message: `Not found: ${descriptor.resource}/${descriptor.id}`
|
|
771
849
|
};
|
|
@@ -801,7 +879,7 @@ function createHasuraDataProvider(config) {
|
|
|
801
879
|
const object = m.jsonbSpill ? partitionJsonbSpill(mainInput, m.jsonbSpill, m.selectFields) : mainInput;
|
|
802
880
|
const data = await gql(`mutation Create_${m.table}($object: ${m.table}_insert_input!) {
|
|
803
881
|
item: insert_${m.table}_one(object: $object) { ${fields} }
|
|
804
|
-
}`, { object }, m.role, context.signal);
|
|
882
|
+
}`, { object }, m.role, context.signal, "mutation");
|
|
805
883
|
const result = mutationRecord(m, descriptor.idField, data.item, descriptor.resource);
|
|
806
884
|
if (m.dataBody && dataBody) await upsertDataBody(m.dataBody, result.id, dataBody, m.role, context.signal);
|
|
807
885
|
return result;
|
|
@@ -830,7 +908,7 @@ function createHasuraDataProvider(config) {
|
|
|
830
908
|
}`, {
|
|
831
909
|
where,
|
|
832
910
|
set
|
|
833
|
-
}, m.role, context.signal);
|
|
911
|
+
}, m.role, context.signal, "mutation");
|
|
834
912
|
if (ifUpdatedAt != null && ((data.result.affected_rows ?? 0) === 0 || (data.result.returning?.length ?? 0) === 0)) throw {
|
|
835
913
|
kind: "conflict",
|
|
836
914
|
code: "stale-record",
|
|
@@ -844,7 +922,7 @@ function createHasuraDataProvider(config) {
|
|
|
844
922
|
}`, {
|
|
845
923
|
id: descriptor.id,
|
|
846
924
|
set
|
|
847
|
-
}, m.role, context.signal)).item;
|
|
925
|
+
}, m.role, context.signal, "mutation")).item;
|
|
848
926
|
}
|
|
849
927
|
const result = mutationRecord(m, descriptor.idField, item, descriptor.resource, descriptor.id);
|
|
850
928
|
if (m.dataBody && dataBody) await upsertDataBody(m.dataBody, result.id, dataBody, m.role, context.signal);
|
|
@@ -859,12 +937,12 @@ function createHasuraDataProvider(config) {
|
|
|
859
937
|
const where = mergeWhere({ [pkField]: { _eq: descriptor.id } }, m.fixedFilter);
|
|
860
938
|
item = (await gql(`mutation Delete_${m.table}($where: ${m.table}_bool_exp!) {
|
|
861
939
|
result: delete_${m.table}(where: $where) { affected_rows returning { ${fields} } }
|
|
862
|
-
}`, { where }, m.role, context.signal)).result.returning?.[0] ?? null;
|
|
940
|
+
}`, { where }, m.role, context.signal, "mutation")).result.returning?.[0] ?? null;
|
|
863
941
|
} else {
|
|
864
942
|
const pkType = m.pkType ?? "bigint";
|
|
865
943
|
item = (await gql(`mutation Delete_${m.table}($id: ${pkType}!) {
|
|
866
944
|
item: delete_${m.table}_by_pk(${pkField}: $id) { ${fields} }
|
|
867
|
-
}`, { id: descriptor.id }, m.role, context.signal)).item;
|
|
945
|
+
}`, { id: descriptor.id }, m.role, context.signal, "mutation")).item;
|
|
868
946
|
}
|
|
869
947
|
mutationRecord(m, descriptor.idField, item, descriptor.resource, descriptor.id);
|
|
870
948
|
return {
|
|
@@ -885,6 +963,6 @@ function createHasuraDataProvider(config) {
|
|
|
885
963
|
});
|
|
886
964
|
}
|
|
887
965
|
//#endregion
|
|
888
|
-
export { DEFAULT_HASURA_ENDPOINT, FILTER_OPERATOR_UNSUPPORTED_CODE, HASURA_CURSOR_CODES, LOCALE_REQUIRED_CODE, NOT_AUTHENTICATED_CODE, aggregateRoot, assertCursorLimit, assertCursorOrderable, byPkRoot, coerceInt64Filter, createHasuraDataProvider, createHasuraLiveProvider, decodeCursor, effectiveCursorOrdering, encodeCursor, filtersToWhere, flattenJsonbSpill, hasuraWsUrl, keysetWhere, localeWhere, mergeWhere, orderingSignature, partitionDataBody, partitionJsonbSpill, scopeToWhere };
|
|
966
|
+
export { DEFAULT_HASURA_ENDPOINT, FILTER_OPERATOR_UNSUPPORTED_CODE, HASURA_CURSOR_CODES, HASURA_EXTERNAL_FAILURE_CODES, LOCALE_REQUIRED_CODE, NOT_AUTHENTICATED_CODE, aggregateRoot, assertCursorLimit, assertCursorOrderable, byPkRoot, coerceInt64Filter, createHasuraDataProvider, createHasuraLiveProvider, decodeCursor, effectiveCursorOrdering, encodeCursor, filtersToWhere, flattenJsonbSpill, hasuraWsUrl, keysetWhere, localeWhere, mergeWhere, orderingSignature, partitionDataBody, partitionJsonbSpill, scopeToWhere };
|
|
889
967
|
|
|
890
968
|
//# sourceMappingURL=index.js.map
|