@vrplatform/graphql 1.0.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.
Files changed (75) hide show
  1. package/LICENSE +3 -0
  2. package/build/main/constants.d.ts +2 -0
  3. package/build/main/constants.js +5 -0
  4. package/build/main/create-client-v2.d.ts +11 -0
  5. package/build/main/create-client-v2.js +79 -0
  6. package/build/main/create-client.d.ts +11 -0
  7. package/build/main/create-client.js +122 -0
  8. package/build/main/dotenv.d.ts +1 -0
  9. package/build/main/dotenv.js +6 -0
  10. package/build/main/gqty/index.d.ts +1 -0
  11. package/build/main/gqty/index.js +17 -0
  12. package/build/main/gqty/schema.generated.d.ts +117383 -0
  13. package/build/main/gqty/schema.generated.js +47182 -0
  14. package/build/main/index.d.ts +4 -0
  15. package/build/main/index.js +24 -0
  16. package/build/main/src/constants.d.ts +2 -0
  17. package/build/main/src/constants.js +5 -0
  18. package/build/main/src/create-client.d.ts +7 -0
  19. package/build/main/src/create-client.js +109 -0
  20. package/build/main/src/gqty/index.d.ts +1 -0
  21. package/build/main/src/gqty/index.js +17 -0
  22. package/build/main/src/gqty/schema.generated.d.ts +147429 -0
  23. package/build/main/src/gqty/schema.generated.js +47182 -0
  24. package/build/main/src/index.d.ts +14 -0
  25. package/build/main/src/index.js +93 -0
  26. package/build/main/src/index.spec.d.ts +1 -0
  27. package/build/main/src/index.spec.js +12 -0
  28. package/build/main/src/types.d.ts +16 -0
  29. package/build/main/src/types.js +2 -0
  30. package/build/main/tsconfig.main.tsbuildinfo +1 -0
  31. package/build/main/types.d.ts +18 -0
  32. package/build/main/types.js +2 -0
  33. package/build/main/wrap.d.ts +10 -0
  34. package/build/main/wrap.js +70 -0
  35. package/build/module/constants.d.ts +2 -0
  36. package/build/module/constants.js +2 -0
  37. package/build/module/create-client-v2.d.ts +11 -0
  38. package/build/module/create-client-v2.js +72 -0
  39. package/build/module/create-client.d.ts +11 -0
  40. package/build/module/create-client.js +116 -0
  41. package/build/module/dotenv.d.ts +1 -0
  42. package/build/module/dotenv.js +3 -0
  43. package/build/module/gqty/index.d.ts +1 -0
  44. package/build/module/gqty/index.js +1 -0
  45. package/build/module/gqty/schema.generated.d.ts +117383 -0
  46. package/build/module/gqty/schema.generated.js +47179 -0
  47. package/build/module/index.d.ts +4 -0
  48. package/build/module/index.js +4 -0
  49. package/build/module/src/constants.d.ts +2 -0
  50. package/build/module/src/constants.js +2 -0
  51. package/build/module/src/create-client.d.ts +7 -0
  52. package/build/module/src/create-client.js +103 -0
  53. package/build/module/src/gqty/index.d.ts +1 -0
  54. package/build/module/src/gqty/index.js +1 -0
  55. package/build/module/src/gqty/schema.generated.d.ts +147429 -0
  56. package/build/module/src/gqty/schema.generated.js +47179 -0
  57. package/build/module/src/index.d.ts +14 -0
  58. package/build/module/src/index.js +73 -0
  59. package/build/module/src/index.spec.d.ts +1 -0
  60. package/build/module/src/index.spec.js +10 -0
  61. package/build/module/src/types.d.ts +16 -0
  62. package/build/module/src/types.js +1 -0
  63. package/build/module/tsconfig.esm.tsbuildinfo +1 -0
  64. package/build/module/types.d.ts +18 -0
  65. package/build/module/types.js +1 -0
  66. package/build/module/wrap.d.ts +10 -0
  67. package/build/module/wrap.js +67 -0
  68. package/package.json +66 -0
  69. package/src/constants.ts +2 -0
  70. package/src/create-client.ts +121 -0
  71. package/src/gqty/index.ts +1 -0
  72. package/src/gqty/schema.generated.d.ts +117383 -0
  73. package/src/gqty/schema.generated.js +47255 -0
  74. package/src/index.ts +93 -0
  75. package/src/types.ts +18 -0
@@ -0,0 +1,14 @@
1
+ export { type HasuraClient, useHasuraClientInner } from './create-client';
2
+ export * from './gqty';
3
+ export { GQtyError } from 'gqty';
4
+ import type { LegacyResolveOptions } from 'gqty';
5
+ import type { Mutation, Query, Subscription } from './gqty';
6
+ import type { GqlAuthParam } from './types';
7
+ export type ResolveOptionsWithSession<T> = LegacyResolveOptions<T>;
8
+ export declare function useHasuraClient(args?: GqlAuthParam): {
9
+ client: import("gqty").GQtyClient<import("./gqty").GeneratedSchema>;
10
+ subscriptionsClient: import("gqty").LegacySubscriptionsClient;
11
+ mutate<T = unknown>(resolved: (sub: Mutation) => T, options?: ResolveOptionsWithSession<T>): Promise<T>;
12
+ query<T = unknown>(resolved: (sub: Query) => T, options?: ResolveOptionsWithSession<T>): Promise<T>;
13
+ subscribe<T = unknown>(resolved: (sub: Subscription) => T, onData: (data: T, unsubscribeFn: () => Promise<void>) => void, onError?: (err: Error, unsubscribeFn: () => Promise<void>) => void): () => Promise<void>;
14
+ };
@@ -0,0 +1,73 @@
1
+ import { useHasuraClientInner } from './create-client';
2
+ export { useHasuraClientInner } from './create-client';
3
+ export * from './gqty';
4
+ export { GQtyError } from 'gqty';
5
+ export function useHasuraClient(args) {
6
+ const { client, subscriptionsClient } = useHasuraClientInner(args);
7
+ const retries = args.retries || 3;
8
+ return {
9
+ client,
10
+ subscriptionsClient,
11
+ async mutate(resolved, options) {
12
+ if (!options)
13
+ options = {};
14
+ if (options.noCache === undefined)
15
+ options.noCache = true;
16
+ let err;
17
+ for (let tries = 1; tries <= retries; tries++) {
18
+ try {
19
+ const result = await client.resolve(({ mutation }) => resolved(mutation), options);
20
+ return result;
21
+ }
22
+ catch (error) {
23
+ err = error;
24
+ if (error.message !== 'database query error')
25
+ break;
26
+ await new Promise((resolve) => setTimeout(resolve, 1_000 * tries + 1_000));
27
+ }
28
+ }
29
+ if (args.onError)
30
+ throw args.onError(err) || err;
31
+ throw err;
32
+ },
33
+ async query(resolved, options) {
34
+ let err;
35
+ for (let tries = 1; tries <= retries; tries++) {
36
+ try {
37
+ const result = await client.resolve(({ query }) => resolved(query), options);
38
+ return result;
39
+ }
40
+ catch (error) {
41
+ err = error;
42
+ if (error.message !== 'database query error')
43
+ break;
44
+ await new Promise((resolve) => setTimeout(resolve, 1_000 * tries + 1_000));
45
+ }
46
+ }
47
+ if (args.onError)
48
+ throw args.onError(err) || err;
49
+ throw err;
50
+ },
51
+ subscribe(resolved, onData, onError) {
52
+ if (!subscriptionsClient)
53
+ throw new Error('Subscriptions not enabled');
54
+ let unsub;
55
+ const stop = async () => {
56
+ if (!unsub)
57
+ return;
58
+ await unsub().catch(() => undefined);
59
+ };
60
+ client.resolved(() => resolved(client.subscription), {
61
+ onSubscription(event) {
62
+ if (event.unsubscribe)
63
+ unsub = event.unsubscribe;
64
+ if (event.type === 'data')
65
+ onData(event.data, stop);
66
+ else if (event.type === 'with-errors' && onError)
67
+ onError(event.error, stop);
68
+ },
69
+ });
70
+ return stop;
71
+ },
72
+ };
73
+ }
@@ -0,0 +1 @@
1
+ import '../dotenv';
@@ -0,0 +1,10 @@
1
+ import '../dotenv';
2
+ import { expect, test } from 'bun:test';
3
+ import { useHasuraClient } from './index';
4
+ test('test', async () => {
5
+ const client = useHasuraClient({
6
+ secret: process.env.HASURA_GRAPHQL_ADMIN_SECRET,
7
+ });
8
+ const user = await client.query((q) => q.user({ limit: 5 }).map((x) => x.id));
9
+ expect(user.length).toBeTruthy();
10
+ });
@@ -0,0 +1,16 @@
1
+ export type Headers = {
2
+ [s: string]: string;
3
+ };
4
+ export type GqlAuthParam = {
5
+ accessToken?: string;
6
+ secret?: string;
7
+ headers?: {
8
+ [s: string]: string;
9
+ } | (() => Headers) | (() => Promise<Headers>);
10
+ fetch?: any;
11
+ subscriptions?: boolean;
12
+ uri?: string;
13
+ onError?: (err: Error) => any;
14
+ retries?: number;
15
+ auditUserId?: string;
16
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ {"root":["../../src/constants.ts","../../src/create-client.ts","../../src/index.spec.ts","../../src/index.ts","../../src/types.ts","../../src/gqty/index.ts","../../src/gqty/schema.generated.d.ts","../../src/gqty/schema.generated.js"],"version":"5.6.3"}
@@ -0,0 +1,18 @@
1
+ export type Headers = {
2
+ [s: string]: string;
3
+ };
4
+ export type GqlAuthParam = {
5
+ accessToken?: string;
6
+ secret?: string;
7
+ headers?: {
8
+ [s: string]: string;
9
+ } | (() => Headers) | (() => Promise<Headers>);
10
+ fetch?: any;
11
+ normalization?: boolean;
12
+ subscriptions?: boolean;
13
+ uri?: string;
14
+ cache?: boolean;
15
+ onError?: (err: Error) => any;
16
+ retries?: number;
17
+ auditUserId?: string;
18
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,10 @@
1
+ import type { GQtyClient, LegacyResolveOptions, LegacySubscriptionsClient } from 'gqty';
2
+ import type { GeneratedSchema, Mutation, Query, Subscription } from './gqty';
3
+ export type ResolveOptionsWithSession<T> = LegacyResolveOptions<T>;
4
+ export declare function wrapGraphQLClient(client: GQtyClient<GeneratedSchema>, subscriptionsClient?: LegacySubscriptionsClient, onError?: (err: Error) => any, retries?: number): {
5
+ client: GQtyClient<GeneratedSchema>;
6
+ subscriptionsClient: LegacySubscriptionsClient;
7
+ mutate<T = unknown>(resolved: (sub: Mutation) => T, options?: ResolveOptionsWithSession<T>): Promise<T>;
8
+ query<T = unknown>(resolved: (sub: Query) => T, options?: ResolveOptionsWithSession<T>): Promise<T>;
9
+ subscribe<T = unknown>(resolved: (sub: Subscription) => T, onData: (data: T, unsubscribeFn: () => Promise<void>) => void, onError?: (err: Error, unsubscribeFn: () => Promise<void>) => void): () => Promise<void>;
10
+ };
@@ -0,0 +1,67 @@
1
+ export function wrapGraphQLClient(client, subscriptionsClient, onError, retries = 3) {
2
+ return {
3
+ client,
4
+ subscriptionsClient,
5
+ async mutate(resolved, options) {
6
+ if (!options)
7
+ options = {};
8
+ if (options.noCache === undefined)
9
+ options.noCache = true;
10
+ let err;
11
+ for (let tries = 1; tries <= retries; tries++) {
12
+ try {
13
+ const result = await client.resolve(({ mutation }) => resolved(mutation), options);
14
+ return result;
15
+ }
16
+ catch (error) {
17
+ err = error;
18
+ if (error.message !== 'database query error')
19
+ break;
20
+ await new Promise((resolve) => setTimeout(resolve, 1_000 * tries + 1_000));
21
+ }
22
+ }
23
+ if (onError)
24
+ throw onError(err) || err;
25
+ throw err;
26
+ },
27
+ async query(resolved, options) {
28
+ let err;
29
+ for (let tries = 1; tries <= retries; tries++) {
30
+ try {
31
+ const result = await client.resolve(({ query }) => resolved(query), options);
32
+ return result;
33
+ }
34
+ catch (error) {
35
+ err = error;
36
+ if (error.message !== 'database query error')
37
+ break;
38
+ await new Promise((resolve) => setTimeout(resolve, 1_000 * tries + 1_000));
39
+ }
40
+ }
41
+ if (onError)
42
+ throw onError(err) || err;
43
+ throw err;
44
+ },
45
+ subscribe(resolved, onData, onError) {
46
+ if (!subscriptionsClient)
47
+ throw new Error('Subscriptions not enabled');
48
+ let unsub;
49
+ const stop = async () => {
50
+ if (!unsub)
51
+ return;
52
+ await unsub().catch(() => undefined);
53
+ };
54
+ client.resolved(() => resolved(client.subscription), {
55
+ onSubscription(event) {
56
+ if (event.unsubscribe)
57
+ unsub = event.unsubscribe;
58
+ if (event.type === 'data')
59
+ onData(event.data, stop);
60
+ else if (event.type === 'with-errors' && onError)
61
+ onError(event.error, stop);
62
+ },
63
+ });
64
+ return stop;
65
+ },
66
+ };
67
+ }
package/package.json ADDED
@@ -0,0 +1,66 @@
1
+ {
2
+ "name": "@vrplatform/graphql",
3
+ "publishConfig": {
4
+ "access": "public"
5
+ },
6
+ "files": [
7
+ "build/main",
8
+ "build/module",
9
+ "src",
10
+ "!**/*.spec.*",
11
+ "LICENSE"
12
+ ],
13
+ "version": "1.0.0",
14
+ "description": "Finalytic graphql",
15
+ "main": "build/main/index.js",
16
+ "module": "build/module/index.js",
17
+ "typings": "build/module/index.d.ts",
18
+ "repository": "https://github.com/finalytic/core",
19
+ "license": "UNLICENSED",
20
+ "keywords": [],
21
+ "trustedDependencies": [
22
+ "@biomejs/biome"
23
+ ],
24
+ "overrides": {
25
+ "graphql": "^16.9.0"
26
+ },
27
+ "dependencies": {
28
+ "@types/bun": "^1.1.13",
29
+ "concurrently": "^9.1.0",
30
+ "gqty": "^3.2.1",
31
+ "graphql": "^16.9.0",
32
+ "graphql-ws": "^5.16.0",
33
+ "hasura-camelize": "^2.0.2"
34
+ },
35
+ "devDependencies": {
36
+ "@types/node": "22.9.0",
37
+ "@gqty/cli": "^4.2.0",
38
+ "dotenv": "^16.4.5",
39
+ "typescript": "^5.6.3",
40
+ "@biomejs/biome": "^1.9.4",
41
+ "npm-run-all": "^4.1.5"
42
+ },
43
+ "scripts": {
44
+ "postinstall": "bun scripts/download-hasura.ts",
45
+ "lint": "biome check --diagnostic-level=warn .",
46
+ "lint:fix": "biome check --apply-unsafe --skip-errors .",
47
+ "pre-push": "bun lint && bun typecheck",
48
+ "test": "echo \"Error: no test specified\"",
49
+ "up": "bunx npm-check-updates -i",
50
+ "pub": "npm run generate && npm run build && pnpm version patch --no-commit-hooks --no-git-tag-version && pnpm publish --no-git-checks",
51
+ "typecheck": "tsc --noEmit",
52
+ "build": "run-p build:* && run-p buildcp:*",
53
+ "build:main": "tsc -b tsconfig.main.json",
54
+ "build:module": "tsc -b tsconfig.esm.json",
55
+ "buildcp:copy1": "cp ./src/gqty/schema.generated.d.ts ./build/module/gqty/schema.generated.d.ts",
56
+ "buildcp:copy2": "cp ./src/gqty/schema.generated.d.ts ./build/main/gqty/schema.generated.d.ts",
57
+ "console": "bunx hasura console --project ./hasura --envfile ../.env --no-browser",
58
+ "pull": "bunx hasura metadata pull --project ./hasura --envfile ../.env",
59
+ "apply": "bunx hasura metadata apply --project ./hasura --envfile ../.env",
60
+ "pull:eu": "bunx hasura metadata pull --project ./hasura --envfile ../.env --endpoint http://100.106.134.38:8080",
61
+ "apply:eu": "bunx hasura metadata apply --project ./hasura --envfile ../.env --endpoint http://100.106.134.38:8080",
62
+ "generate": "gqty generate && sleep 1 && npm run post-generate && npm run post-generate2 && rm src/gqty/index.js",
63
+ "post-generate": "sed -i '' 's/export type Maybe<T> = T | null/export type Maybe<T> = T/g' ./src/gqty/schema.generated.d.ts",
64
+ "post-generate2": "sed -i '' 's/InputMaybe<T> = Maybe<T>/InputMaybe<T> = Maybe<T> | null/g' ./src/gqty/schema.generated.d.ts"
65
+ }
66
+ }
@@ -0,0 +1,2 @@
1
+ export const hasuraGraphqlUri = 'https://finalytic.hasura.app/v1/graphql'; // 'https://hasura.vrplatform.app/v1/graphql';
2
+ export const hasuraQueryTypeHeader = 'x-hasura-query-type';
@@ -0,0 +1,121 @@
1
+ import { createSubscriptionsClient } from '@gqty/subscriptions';
2
+ // import fetch from 'cross-fetch';
3
+ import { Cache, type QueryFetcher, createClient } from 'gqty';
4
+ import { hasuraGraphqlUri, hasuraQueryTypeHeader } from './constants';
5
+ import {
6
+ type GeneratedSchema,
7
+ generatedSchema,
8
+ scalarsEnumsHash,
9
+ } from './gqty';
10
+ import type { GqlAuthParam, Headers } from './types';
11
+
12
+ export type HasuraClient = ReturnType<typeof useHasuraClientInner>;
13
+
14
+ export function useHasuraClientInner(args?: Omit<GqlAuthParam, 'retries'>) {
15
+ const $headers = args && 'headers' in args ? args.headers : undefined;
16
+ const $fetch = (args && 'fetch' in args ? args.fetch : undefined) || fetch;
17
+ const uri = args?.uri || hasuraGraphqlUri;
18
+
19
+ const getHeaders = async (base?: Headers): Promise<Headers> => {
20
+ const headers: Record<string, any> =
21
+ ($headers && typeof $headers === 'function'
22
+ ? await $headers()
23
+ : $headers) || {};
24
+ if (base) for (const key in base) headers[key] = base[key];
25
+ if (args && 'secret' in args && args.secret) {
26
+ headers['x-hasura-admin-secret'] = args.secret;
27
+ } else if (args && 'accessToken' in args && args.accessToken) {
28
+ headers.authorization = args.accessToken.startsWith('Bearer ')
29
+ ? args.accessToken
30
+ : `Bearer ${args.accessToken}`;
31
+ }
32
+ if (args?.auditUserId) headers['x-hasura-audit-user-id'] = args.auditUserId;
33
+ return headers;
34
+ };
35
+
36
+ const queryFetcher: QueryFetcher = async (
37
+ { query, variables, operationName },
38
+ fetchOptions
39
+ ) => {
40
+ const headers = await getHeaders();
41
+ if (fetchOptions?.headers) {
42
+ for (const key in fetchOptions.headers) {
43
+ headers[key] = fetchOptions.headers[key];
44
+ }
45
+ }
46
+
47
+ // Modify "https://finalytic.hasura.app/v1/graphql" if needed
48
+ const response = await $fetch('https://finalytic.hasura.app/v1/graphql', {
49
+ ...fetchOptions,
50
+ method: 'POST',
51
+ headers: {
52
+ 'Content-Type': 'application/json',
53
+ ...headers,
54
+ },
55
+ body: JSON.stringify({
56
+ query,
57
+ variables,
58
+ operationName,
59
+ }),
60
+ mode: 'cors',
61
+ });
62
+
63
+ const json = await response.json();
64
+ return json; //await defaultResponseHandler(json);
65
+ };
66
+
67
+ const subscriptionsClient =
68
+ args?.subscriptions === true
69
+ ? createSubscriptionsClient({
70
+ lazy: true,
71
+ connectionInitPayload: async () => ({
72
+ headers: await getHeaders({
73
+ [hasuraQueryTypeHeader]: 'subscription',
74
+ }),
75
+ }),
76
+ wsEndpoint() {
77
+ const wsUrl = new URL(uri);
78
+ wsUrl.protocol = wsUrl.protocol
79
+ .replace('https', 'wss')
80
+ .replace('http', 'ws');
81
+ return wsUrl.href;
82
+ },
83
+ /*url: () => {
84
+ },*/
85
+ })
86
+ : undefined;
87
+
88
+ const cache = new Cache(undefined, {
89
+ maxAge: 0,
90
+ staleWhileRevalidate: 0,
91
+ normalization: false,
92
+ });
93
+
94
+ const client = createClient<GeneratedSchema>({
95
+ schema: generatedSchema,
96
+ scalars: scalarsEnumsHash,
97
+ //cache,
98
+ cache,
99
+ fetchOptions: {
100
+ fetcher: queryFetcher,
101
+ subscriber: subscriptionsClient,
102
+ },
103
+ });
104
+
105
+ /*const client: GQtyClient<GeneratedSchema> = createClient<GeneratedSchema>({
106
+ schema: generatedSchema,
107
+ scalarsEnumsHash,
108
+ queryFetcher,
109
+ subscriptionsClient,
110
+ normalization: args?.normalization === true,
111
+ defaults: {
112
+ resolved: {
113
+ noCache: args?.cache !== true,
114
+ retry: false,
115
+ },
116
+ },
117
+ ...args,
118
+ });*/
119
+
120
+ return { subscriptionsClient, client };
121
+ }
@@ -0,0 +1 @@
1
+ export * from './schema.generated';