naystack 1.8.3 → 1.8.5

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 (47) hide show
  1. package/dist/auth/client.cjs.js +18 -8
  2. package/dist/auth/client.d.mts +1 -0
  3. package/dist/auth/client.d.ts +1 -0
  4. package/dist/auth/client.esm.js +24 -8
  5. package/dist/auth/email/client.cjs.js +18 -8
  6. package/dist/auth/email/client.d.mts +2 -1
  7. package/dist/auth/email/client.d.ts +2 -1
  8. package/dist/auth/email/client.esm.js +24 -8
  9. package/dist/auth/email/index.cjs.js +4 -2
  10. package/dist/auth/email/index.d.mts +1 -0
  11. package/dist/auth/email/index.d.ts +1 -0
  12. package/dist/auth/email/index.esm.js +4 -2
  13. package/dist/auth/email/next.d.mts +1 -0
  14. package/dist/auth/email/next.d.ts +1 -0
  15. package/dist/auth/email/routes/delete.cjs.js +4 -2
  16. package/dist/auth/email/routes/delete.esm.js +4 -2
  17. package/dist/auth/email/routes/get.cjs.js +4 -2
  18. package/dist/auth/email/routes/get.esm.js +4 -2
  19. package/dist/auth/email/routes/post.cjs.js +4 -2
  20. package/dist/auth/email/routes/post.esm.js +4 -2
  21. package/dist/auth/email/routes/put.cjs.js +4 -2
  22. package/dist/auth/email/routes/put.esm.js +4 -2
  23. package/dist/auth/email/token.cjs.js +4 -2
  24. package/dist/auth/email/token.d.mts +2 -2
  25. package/dist/auth/email/token.d.ts +2 -2
  26. package/dist/auth/email/token.esm.js +4 -2
  27. package/dist/auth/google/get.cjs.js +3 -1
  28. package/dist/auth/google/get.esm.js +3 -1
  29. package/dist/auth/google/index.cjs.js +3 -1
  30. package/dist/auth/google/index.esm.js +3 -1
  31. package/dist/auth/index.cjs.js +4 -2
  32. package/dist/auth/index.d.mts +1 -0
  33. package/dist/auth/index.d.ts +1 -0
  34. package/dist/auth/index.esm.js +4 -2
  35. package/dist/auth/token-store.cjs.js +120 -0
  36. package/dist/auth/token-store.d.mts +42 -0
  37. package/dist/auth/token-store.d.ts +42 -0
  38. package/dist/auth/token-store.esm.js +90 -0
  39. package/dist/graphql/client.cjs.js +77 -31
  40. package/dist/graphql/client.esm.js +69 -24
  41. package/dist/graphql/links.cjs.js +126 -0
  42. package/dist/graphql/links.d.mts +14 -0
  43. package/dist/graphql/links.d.ts +14 -0
  44. package/dist/graphql/links.esm.js +101 -0
  45. package/dist/graphql/next.cjs.js +67 -21
  46. package/dist/graphql/next.esm.js +67 -21
  47. package/package.json +6 -1
@@ -0,0 +1,126 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/graphql/links.ts
21
+ var links_exports = {};
22
+ __export(links_exports, {
23
+ makeAuthLink: () => makeAuthLink
24
+ });
25
+ module.exports = __toCommonJS(links_exports);
26
+ var import_client = require("@apollo/client");
27
+ var import_context = require("@apollo/client/link/context");
28
+ var import_error = require("@apollo/client/link/error");
29
+ var import_token_store = require("naystack/auth/token-store");
30
+
31
+ // src/env.ts
32
+ var EXTRA_ENV = globalThis.__NAYSTACK_ENV__ || (globalThis.__NAYSTACK_ENV__ = {});
33
+ var getEnvValue = (key) => {
34
+ switch (key) {
35
+ case "NEXT_PUBLIC_GRAPHQL_ENDPOINT" /* NEXT_PUBLIC_GRAPHQL_ENDPOINT */:
36
+ return process.env.NEXT_PUBLIC_GRAPHQL_ENDPOINT || EXTRA_ENV.GRAPHQL_ENDPOINT;
37
+ case "NEXT_PUBLIC_EMAIL_AUTH_ENDPOINT" /* NEXT_PUBLIC_EMAIL_AUTH_ENDPOINT */:
38
+ return process.env.NEXT_PUBLIC_EMAIL_AUTH_ENDPOINT || EXTRA_ENV.EMAIL_AUTH_ENDPOINT;
39
+ case "NEXT_PUBLIC_GOOGLE_AUTH_ENDPOINT" /* NEXT_PUBLIC_GOOGLE_AUTH_ENDPOINT */:
40
+ return process.env.NEXT_PUBLIC_GOOGLE_AUTH_ENDPOINT || EXTRA_ENV.GOOGLE_AUTH_ENDPOINT;
41
+ case "NEXT_PUBLIC_INSTAGRAM_AUTH_ENDPOINT" /* NEXT_PUBLIC_INSTAGRAM_AUTH_ENDPOINT */:
42
+ return process.env.NEXT_PUBLIC_INSTAGRAM_AUTH_ENDPOINT || EXTRA_ENV.INSTAGRAM_AUTH_ENDPOINT;
43
+ case "NEXT_PUBLIC_FILE_ENDPOINT" /* NEXT_PUBLIC_FILE_ENDPOINT */:
44
+ return process.env.NEXT_PUBLIC_FILE_ENDPOINT || EXTRA_ENV.FILE_ENDPOINT;
45
+ case "NEXT_PUBLIC_BASE_URL" /* NEXT_PUBLIC_BASE_URL */:
46
+ return process.env.NEXT_PUBLIC_BASE_URL || EXTRA_ENV.BASE_URL;
47
+ case "REFRESH_KEY" /* REFRESH_KEY */:
48
+ return process.env.REFRESH_KEY;
49
+ case "SIGNING_KEY" /* SIGNING_KEY */:
50
+ return process.env.SIGNING_KEY;
51
+ case "INSTAGRAM_CLIENT_SECRET" /* INSTAGRAM_CLIENT_SECRET */:
52
+ return process.env.INSTAGRAM_CLIENT_SECRET;
53
+ case "INSTAGRAM_CLIENT_ID" /* INSTAGRAM_CLIENT_ID */:
54
+ return process.env.INSTAGRAM_CLIENT_ID;
55
+ case "GOOGLE_CLIENT_SECRET" /* GOOGLE_CLIENT_SECRET */:
56
+ return process.env.GOOGLE_CLIENT_SECRET;
57
+ case "GOOGLE_CLIENT_ID" /* GOOGLE_CLIENT_ID */:
58
+ return process.env.GOOGLE_CLIENT_ID;
59
+ case "TURNSTILE_KEY" /* TURNSTILE_KEY */:
60
+ return process.env.TURNSTILE_KEY;
61
+ case "S3_ACCESS_KEY_ID" /* S3_ACCESS_KEY_ID */:
62
+ return process.env.S3_ACCESS_KEY_ID;
63
+ case "S3_ACCESS_KEY_SECRET" /* S3_ACCESS_KEY_SECRET */:
64
+ return process.env.S3_ACCESS_KEY_SECRET;
65
+ case "S3_REGION" /* S3_REGION */:
66
+ return process.env.S3_REGION;
67
+ case "S3_BUCKET" /* S3_BUCKET */:
68
+ return process.env.S3_BUCKET;
69
+ case "NODE_ENV" /* NODE_ENV */:
70
+ return process.env.NODE_ENV;
71
+ default:
72
+ return process.env[key];
73
+ }
74
+ };
75
+ function getEnv(key, skipCheck) {
76
+ const value = getEnvValue(key);
77
+ if (!skipCheck && !value) throw new Error(`${key} is not defined`);
78
+ return value;
79
+ }
80
+
81
+ // src/graphql/links.ts
82
+ var RETRY_CONTEXT_KEY = "__naystackRetried";
83
+ function isExpiredTokenError(error) {
84
+ return error.extensions?.code === "UNAUTHENTICATED";
85
+ }
86
+ var authLink = (0, import_context.setContext)((_, previousContext) => {
87
+ const token = (0, import_token_store.getAccessToken)();
88
+ if (!token || previousContext.credentials === "include")
89
+ return previousContext;
90
+ return {
91
+ ...previousContext,
92
+ headers: {
93
+ ...previousContext.headers,
94
+ authorization: `Bearer ${token}`
95
+ },
96
+ credentials: "omit"
97
+ };
98
+ });
99
+ var refreshLink = (0, import_error.onError)(({ graphQLErrors, operation, forward }) => {
100
+ if (!graphQLErrors?.some(isExpiredTokenError)) return;
101
+ if (operation.getContext()[RETRY_CONTEXT_KEY]) return;
102
+ return (0, import_client.fromPromise)(
103
+ // A failed refresh still replays once: the retry reproduces the original
104
+ // error for the caller instead of surfacing the refresh's error in its place.
105
+ (0, import_token_store.refreshAccessToken)().catch(() => null)
106
+ ).flatMap(() => {
107
+ operation.setContext((previousContext) => ({
108
+ ...previousContext,
109
+ [RETRY_CONTEXT_KEY]: true
110
+ }));
111
+ return forward(operation);
112
+ });
113
+ });
114
+ function makeAuthLink() {
115
+ return import_client.ApolloLink.from([
116
+ refreshLink,
117
+ authLink,
118
+ new import_client.HttpLink({
119
+ uri: getEnv("NEXT_PUBLIC_GRAPHQL_ENDPOINT" /* NEXT_PUBLIC_GRAPHQL_ENDPOINT */)
120
+ })
121
+ ]);
122
+ }
123
+ // Annotate the CommonJS export names for ESM import in node:
124
+ 0 && (module.exports = {
125
+ makeAuthLink
126
+ });
@@ -0,0 +1,14 @@
1
+ import { ApolloLink } from '@apollo/client';
2
+
3
+ /**
4
+ * Builds the client link chain: refresh-and-retry → auth header → HTTP.
5
+ *
6
+ * `refreshLink` sits outermost so its replayed operation passes back through
7
+ * `authLink` and picks up the refreshed token.
8
+ *
9
+ * @returns An `ApolloLink` for the `link` option of `ApolloClient`.
10
+ * @category GraphQL
11
+ */
12
+ declare function makeAuthLink(): ApolloLink;
13
+
14
+ export { makeAuthLink };
@@ -0,0 +1,14 @@
1
+ import { ApolloLink } from '@apollo/client';
2
+
3
+ /**
4
+ * Builds the client link chain: refresh-and-retry → auth header → HTTP.
5
+ *
6
+ * `refreshLink` sits outermost so its replayed operation passes back through
7
+ * `authLink` and picks up the refreshed token.
8
+ *
9
+ * @returns An `ApolloLink` for the `link` option of `ApolloClient`.
10
+ * @category GraphQL
11
+ */
12
+ declare function makeAuthLink(): ApolloLink;
13
+
14
+ export { makeAuthLink };
@@ -0,0 +1,101 @@
1
+ // src/graphql/links.ts
2
+ import { ApolloLink, fromPromise, HttpLink } from "@apollo/client";
3
+ import { setContext } from "@apollo/client/link/context";
4
+ import { onError } from "@apollo/client/link/error";
5
+ import { getAccessToken, refreshAccessToken } from "naystack/auth/token-store";
6
+
7
+ // src/env.ts
8
+ var EXTRA_ENV = globalThis.__NAYSTACK_ENV__ || (globalThis.__NAYSTACK_ENV__ = {});
9
+ var getEnvValue = (key) => {
10
+ switch (key) {
11
+ case "NEXT_PUBLIC_GRAPHQL_ENDPOINT" /* NEXT_PUBLIC_GRAPHQL_ENDPOINT */:
12
+ return process.env.NEXT_PUBLIC_GRAPHQL_ENDPOINT || EXTRA_ENV.GRAPHQL_ENDPOINT;
13
+ case "NEXT_PUBLIC_EMAIL_AUTH_ENDPOINT" /* NEXT_PUBLIC_EMAIL_AUTH_ENDPOINT */:
14
+ return process.env.NEXT_PUBLIC_EMAIL_AUTH_ENDPOINT || EXTRA_ENV.EMAIL_AUTH_ENDPOINT;
15
+ case "NEXT_PUBLIC_GOOGLE_AUTH_ENDPOINT" /* NEXT_PUBLIC_GOOGLE_AUTH_ENDPOINT */:
16
+ return process.env.NEXT_PUBLIC_GOOGLE_AUTH_ENDPOINT || EXTRA_ENV.GOOGLE_AUTH_ENDPOINT;
17
+ case "NEXT_PUBLIC_INSTAGRAM_AUTH_ENDPOINT" /* NEXT_PUBLIC_INSTAGRAM_AUTH_ENDPOINT */:
18
+ return process.env.NEXT_PUBLIC_INSTAGRAM_AUTH_ENDPOINT || EXTRA_ENV.INSTAGRAM_AUTH_ENDPOINT;
19
+ case "NEXT_PUBLIC_FILE_ENDPOINT" /* NEXT_PUBLIC_FILE_ENDPOINT */:
20
+ return process.env.NEXT_PUBLIC_FILE_ENDPOINT || EXTRA_ENV.FILE_ENDPOINT;
21
+ case "NEXT_PUBLIC_BASE_URL" /* NEXT_PUBLIC_BASE_URL */:
22
+ return process.env.NEXT_PUBLIC_BASE_URL || EXTRA_ENV.BASE_URL;
23
+ case "REFRESH_KEY" /* REFRESH_KEY */:
24
+ return process.env.REFRESH_KEY;
25
+ case "SIGNING_KEY" /* SIGNING_KEY */:
26
+ return process.env.SIGNING_KEY;
27
+ case "INSTAGRAM_CLIENT_SECRET" /* INSTAGRAM_CLIENT_SECRET */:
28
+ return process.env.INSTAGRAM_CLIENT_SECRET;
29
+ case "INSTAGRAM_CLIENT_ID" /* INSTAGRAM_CLIENT_ID */:
30
+ return process.env.INSTAGRAM_CLIENT_ID;
31
+ case "GOOGLE_CLIENT_SECRET" /* GOOGLE_CLIENT_SECRET */:
32
+ return process.env.GOOGLE_CLIENT_SECRET;
33
+ case "GOOGLE_CLIENT_ID" /* GOOGLE_CLIENT_ID */:
34
+ return process.env.GOOGLE_CLIENT_ID;
35
+ case "TURNSTILE_KEY" /* TURNSTILE_KEY */:
36
+ return process.env.TURNSTILE_KEY;
37
+ case "S3_ACCESS_KEY_ID" /* S3_ACCESS_KEY_ID */:
38
+ return process.env.S3_ACCESS_KEY_ID;
39
+ case "S3_ACCESS_KEY_SECRET" /* S3_ACCESS_KEY_SECRET */:
40
+ return process.env.S3_ACCESS_KEY_SECRET;
41
+ case "S3_REGION" /* S3_REGION */:
42
+ return process.env.S3_REGION;
43
+ case "S3_BUCKET" /* S3_BUCKET */:
44
+ return process.env.S3_BUCKET;
45
+ case "NODE_ENV" /* NODE_ENV */:
46
+ return process.env.NODE_ENV;
47
+ default:
48
+ return process.env[key];
49
+ }
50
+ };
51
+ function getEnv(key, skipCheck) {
52
+ const value = getEnvValue(key);
53
+ if (!skipCheck && !value) throw new Error(`${key} is not defined`);
54
+ return value;
55
+ }
56
+
57
+ // src/graphql/links.ts
58
+ var RETRY_CONTEXT_KEY = "__naystackRetried";
59
+ function isExpiredTokenError(error) {
60
+ return error.extensions?.code === "UNAUTHENTICATED";
61
+ }
62
+ var authLink = setContext((_, previousContext) => {
63
+ const token = getAccessToken();
64
+ if (!token || previousContext.credentials === "include")
65
+ return previousContext;
66
+ return {
67
+ ...previousContext,
68
+ headers: {
69
+ ...previousContext.headers,
70
+ authorization: `Bearer ${token}`
71
+ },
72
+ credentials: "omit"
73
+ };
74
+ });
75
+ var refreshLink = onError(({ graphQLErrors, operation, forward }) => {
76
+ if (!graphQLErrors?.some(isExpiredTokenError)) return;
77
+ if (operation.getContext()[RETRY_CONTEXT_KEY]) return;
78
+ return fromPromise(
79
+ // A failed refresh still replays once: the retry reproduces the original
80
+ // error for the caller instead of surfacing the refresh's error in its place.
81
+ refreshAccessToken().catch(() => null)
82
+ ).flatMap(() => {
83
+ operation.setContext((previousContext) => ({
84
+ ...previousContext,
85
+ [RETRY_CONTEXT_KEY]: true
86
+ }));
87
+ return forward(operation);
88
+ });
89
+ });
90
+ function makeAuthLink() {
91
+ return ApolloLink.from([
92
+ refreshLink,
93
+ authLink,
94
+ new HttpLink({
95
+ uri: getEnv("NEXT_PUBLIC_GRAPHQL_ENDPOINT" /* NEXT_PUBLIC_GRAPHQL_ENDPOINT */)
96
+ })
97
+ ]);
98
+ }
99
+ export {
100
+ makeAuthLink
101
+ };
@@ -34,10 +34,34 @@ __export(next_exports, {
34
34
  ApolloWrapper: () => ApolloWrapper
35
35
  });
36
36
  module.exports = __toCommonJS(next_exports);
37
- var import_client3 = require("@apollo/client");
38
37
  var import_client_integration_nextjs = require("@apollo/client-integration-nextjs");
39
38
  var import_react2 = __toESM(require("react"));
40
39
 
40
+ // src/graphql/clear-store.tsx
41
+ var import_client = require("@apollo/client");
42
+ var import_client2 = require("naystack/auth/client");
43
+ var import_react = require("react");
44
+ function ClearStoreOnLogout() {
45
+ const client = (0, import_client.useApolloClient)();
46
+ const token = (0, import_client2.useToken)();
47
+ const hadToken = (0, import_react.useRef)(false);
48
+ (0, import_react.useEffect)(() => {
49
+ if (token) {
50
+ hadToken.current = true;
51
+ } else if (token === null && hadToken.current) {
52
+ hadToken.current = false;
53
+ void client.clearStore();
54
+ }
55
+ }, [client, token]);
56
+ return null;
57
+ }
58
+
59
+ // src/graphql/links.ts
60
+ var import_client3 = require("@apollo/client");
61
+ var import_context = require("@apollo/client/link/context");
62
+ var import_error = require("@apollo/client/link/error");
63
+ var import_token_store = require("naystack/auth/token-store");
64
+
41
65
  // src/env.ts
42
66
  var EXTRA_ENV = globalThis.__NAYSTACK_ENV__ || (globalThis.__NAYSTACK_ENV__ = {});
43
67
  var getEnvValue = (key) => {
@@ -88,32 +112,54 @@ function getEnv(key, skipCheck) {
88
112
  return value;
89
113
  }
90
114
 
91
- // src/graphql/clear-store.tsx
92
- var import_client = require("@apollo/client");
93
- var import_client2 = require("naystack/auth/client");
94
- var import_react = require("react");
95
- function ClearStoreOnLogout() {
96
- const client = (0, import_client.useApolloClient)();
97
- const token = (0, import_client2.useToken)();
98
- const hadToken = (0, import_react.useRef)(false);
99
- (0, import_react.useEffect)(() => {
100
- if (token) {
101
- hadToken.current = true;
102
- } else if (token === null && hadToken.current) {
103
- hadToken.current = false;
104
- void client.clearStore();
105
- }
106
- }, [client, token]);
107
- return null;
115
+ // src/graphql/links.ts
116
+ var RETRY_CONTEXT_KEY = "__naystackRetried";
117
+ function isExpiredTokenError(error) {
118
+ return error.extensions?.code === "UNAUTHENTICATED";
119
+ }
120
+ var authLink = (0, import_context.setContext)((_, previousContext) => {
121
+ const token = (0, import_token_store.getAccessToken)();
122
+ if (!token || previousContext.credentials === "include")
123
+ return previousContext;
124
+ return {
125
+ ...previousContext,
126
+ headers: {
127
+ ...previousContext.headers,
128
+ authorization: `Bearer ${token}`
129
+ },
130
+ credentials: "omit"
131
+ };
132
+ });
133
+ var refreshLink = (0, import_error.onError)(({ graphQLErrors, operation, forward }) => {
134
+ if (!graphQLErrors?.some(isExpiredTokenError)) return;
135
+ if (operation.getContext()[RETRY_CONTEXT_KEY]) return;
136
+ return (0, import_client3.fromPromise)(
137
+ // A failed refresh still replays once: the retry reproduces the original
138
+ // error for the caller instead of surfacing the refresh's error in its place.
139
+ (0, import_token_store.refreshAccessToken)().catch(() => null)
140
+ ).flatMap(() => {
141
+ operation.setContext((previousContext) => ({
142
+ ...previousContext,
143
+ [RETRY_CONTEXT_KEY]: true
144
+ }));
145
+ return forward(operation);
146
+ });
147
+ });
148
+ function makeAuthLink() {
149
+ return import_client3.ApolloLink.from([
150
+ refreshLink,
151
+ authLink,
152
+ new import_client3.HttpLink({
153
+ uri: getEnv("NEXT_PUBLIC_GRAPHQL_ENDPOINT" /* NEXT_PUBLIC_GRAPHQL_ENDPOINT */)
154
+ })
155
+ ]);
108
156
  }
109
157
 
110
158
  // src/graphql/next.tsx
111
159
  function makeClient(cacheConfig) {
112
160
  return new import_client_integration_nextjs.ApolloClient({
113
161
  cache: new import_client_integration_nextjs.InMemoryCache(cacheConfig),
114
- link: new import_client3.HttpLink({
115
- uri: getEnv("NEXT_PUBLIC_GRAPHQL_ENDPOINT" /* NEXT_PUBLIC_GRAPHQL_ENDPOINT */)
116
- })
162
+ link: makeAuthLink()
117
163
  });
118
164
  }
119
165
  var ApolloWrapper = ({
@@ -1,7 +1,6 @@
1
1
  "use client";
2
2
 
3
3
  // src/graphql/next.tsx
4
- import { HttpLink } from "@apollo/client";
5
4
  import {
6
5
  ApolloClient,
7
6
  ApolloNextAppProvider,
@@ -9,6 +8,31 @@ import {
9
8
  } from "@apollo/client-integration-nextjs";
10
9
  import React from "react";
11
10
 
11
+ // src/graphql/clear-store.tsx
12
+ import { useApolloClient } from "@apollo/client";
13
+ import { useToken } from "naystack/auth/client";
14
+ import { useEffect, useRef } from "react";
15
+ function ClearStoreOnLogout() {
16
+ const client = useApolloClient();
17
+ const token = useToken();
18
+ const hadToken = useRef(false);
19
+ useEffect(() => {
20
+ if (token) {
21
+ hadToken.current = true;
22
+ } else if (token === null && hadToken.current) {
23
+ hadToken.current = false;
24
+ void client.clearStore();
25
+ }
26
+ }, [client, token]);
27
+ return null;
28
+ }
29
+
30
+ // src/graphql/links.ts
31
+ import { ApolloLink, fromPromise, HttpLink } from "@apollo/client";
32
+ import { setContext } from "@apollo/client/link/context";
33
+ import { onError } from "@apollo/client/link/error";
34
+ import { getAccessToken, refreshAccessToken } from "naystack/auth/token-store";
35
+
12
36
  // src/env.ts
13
37
  var EXTRA_ENV = globalThis.__NAYSTACK_ENV__ || (globalThis.__NAYSTACK_ENV__ = {});
14
38
  var getEnvValue = (key) => {
@@ -59,32 +83,54 @@ function getEnv(key, skipCheck) {
59
83
  return value;
60
84
  }
61
85
 
62
- // src/graphql/clear-store.tsx
63
- import { useApolloClient } from "@apollo/client";
64
- import { useToken } from "naystack/auth/client";
65
- import { useEffect, useRef } from "react";
66
- function ClearStoreOnLogout() {
67
- const client = useApolloClient();
68
- const token = useToken();
69
- const hadToken = useRef(false);
70
- useEffect(() => {
71
- if (token) {
72
- hadToken.current = true;
73
- } else if (token === null && hadToken.current) {
74
- hadToken.current = false;
75
- void client.clearStore();
76
- }
77
- }, [client, token]);
78
- return null;
86
+ // src/graphql/links.ts
87
+ var RETRY_CONTEXT_KEY = "__naystackRetried";
88
+ function isExpiredTokenError(error) {
89
+ return error.extensions?.code === "UNAUTHENTICATED";
90
+ }
91
+ var authLink = setContext((_, previousContext) => {
92
+ const token = getAccessToken();
93
+ if (!token || previousContext.credentials === "include")
94
+ return previousContext;
95
+ return {
96
+ ...previousContext,
97
+ headers: {
98
+ ...previousContext.headers,
99
+ authorization: `Bearer ${token}`
100
+ },
101
+ credentials: "omit"
102
+ };
103
+ });
104
+ var refreshLink = onError(({ graphQLErrors, operation, forward }) => {
105
+ if (!graphQLErrors?.some(isExpiredTokenError)) return;
106
+ if (operation.getContext()[RETRY_CONTEXT_KEY]) return;
107
+ return fromPromise(
108
+ // A failed refresh still replays once: the retry reproduces the original
109
+ // error for the caller instead of surfacing the refresh's error in its place.
110
+ refreshAccessToken().catch(() => null)
111
+ ).flatMap(() => {
112
+ operation.setContext((previousContext) => ({
113
+ ...previousContext,
114
+ [RETRY_CONTEXT_KEY]: true
115
+ }));
116
+ return forward(operation);
117
+ });
118
+ });
119
+ function makeAuthLink() {
120
+ return ApolloLink.from([
121
+ refreshLink,
122
+ authLink,
123
+ new HttpLink({
124
+ uri: getEnv("NEXT_PUBLIC_GRAPHQL_ENDPOINT" /* NEXT_PUBLIC_GRAPHQL_ENDPOINT */)
125
+ })
126
+ ]);
79
127
  }
80
128
 
81
129
  // src/graphql/next.tsx
82
130
  function makeClient(cacheConfig) {
83
131
  return new ApolloClient({
84
132
  cache: new InMemoryCache(cacheConfig),
85
- link: new HttpLink({
86
- uri: getEnv("NEXT_PUBLIC_GRAPHQL_ENDPOINT" /* NEXT_PUBLIC_GRAPHQL_ENDPOINT */)
87
- })
133
+ link: makeAuthLink()
88
134
  });
89
135
  }
90
136
  var ApolloWrapper = ({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "naystack",
3
- "version": "1.8.3",
3
+ "version": "1.8.5",
4
4
  "description": "A stack built with Next + GraphQL + S3 + Auth",
5
5
  "main": "dist/index.cjs.js",
6
6
  "module": "dist/index.esm.js",
@@ -23,6 +23,11 @@
23
23
  "import": "./dist/auth/client.esm.js",
24
24
  "require": "./dist/auth/client.cjs.js"
25
25
  },
26
+ "./auth/token-store": {
27
+ "types": "./dist/auth/token-store.d.ts",
28
+ "import": "./dist/auth/token-store.esm.js",
29
+ "require": "./dist/auth/token-store.cjs.js"
30
+ },
26
31
  "./graphql": {
27
32
  "types": "./dist/graphql/index.d.ts",
28
33
  "import": "./dist/graphql/index.esm.js",