naystack 1.5.9 → 1.5.10

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 (114) hide show
  1. package/README.md +646 -91
  2. package/dist/auth/constants.d.mts +4 -0
  3. package/dist/auth/constants.d.ts +4 -0
  4. package/dist/auth/email/client.d.mts +149 -0
  5. package/dist/auth/email/client.d.ts +149 -0
  6. package/dist/auth/email/index.cjs.js +2 -20
  7. package/dist/auth/email/index.d.mts +41 -1
  8. package/dist/auth/email/index.d.ts +41 -1
  9. package/dist/auth/email/index.esm.js +1 -17
  10. package/dist/auth/email/routes/delete.cjs.js +0 -1
  11. package/dist/auth/email/routes/delete.d.mts +5 -0
  12. package/dist/auth/email/routes/delete.d.ts +5 -0
  13. package/dist/auth/email/routes/delete.esm.js +0 -1
  14. package/dist/auth/email/routes/get.d.mts +5 -0
  15. package/dist/auth/email/routes/get.d.ts +5 -0
  16. package/dist/auth/email/routes/post.cjs.js +0 -1
  17. package/dist/auth/email/routes/post.d.mts +5 -0
  18. package/dist/auth/email/routes/post.d.ts +5 -0
  19. package/dist/auth/email/routes/post.esm.js +0 -1
  20. package/dist/auth/email/routes/put.cjs.js +0 -1
  21. package/dist/auth/email/routes/put.d.mts +5 -0
  22. package/dist/auth/email/routes/put.d.ts +5 -0
  23. package/dist/auth/email/routes/put.esm.js +0 -1
  24. package/dist/auth/email/token.d.mts +62 -0
  25. package/dist/auth/email/token.d.ts +62 -0
  26. package/dist/auth/email/types.d.mts +22 -0
  27. package/dist/auth/email/types.d.ts +22 -0
  28. package/dist/auth/email/utils.cjs.js +0 -18
  29. package/dist/auth/email/utils.d.mts +41 -3
  30. package/dist/auth/email/utils.d.ts +41 -3
  31. package/dist/auth/email/utils.esm.js +0 -16
  32. package/dist/auth/google/get.d.mts +5 -0
  33. package/dist/auth/google/get.d.ts +5 -0
  34. package/dist/auth/google/index.d.mts +39 -0
  35. package/dist/auth/google/index.d.ts +39 -0
  36. package/dist/auth/index.cjs.js +4 -22
  37. package/dist/auth/index.d.mts +1 -1
  38. package/dist/auth/index.d.ts +1 -1
  39. package/dist/auth/index.esm.js +3 -19
  40. package/dist/auth/instagram/client.d.mts +19 -0
  41. package/dist/auth/instagram/client.d.ts +19 -0
  42. package/dist/auth/instagram/index.d.mts +37 -0
  43. package/dist/auth/instagram/index.d.ts +37 -0
  44. package/dist/auth/instagram/route.d.mts +5 -0
  45. package/dist/auth/instagram/route.d.ts +5 -0
  46. package/dist/auth/instagram/utils.d.mts +13 -0
  47. package/dist/auth/instagram/utils.d.ts +13 -0
  48. package/dist/auth/types.d.mts +24 -0
  49. package/dist/auth/types.d.ts +24 -0
  50. package/dist/auth/utils/errors.d.mts +10 -0
  51. package/dist/auth/utils/errors.d.ts +10 -0
  52. package/dist/auth/utils/token.d.mts +20 -0
  53. package/dist/auth/utils/token.d.ts +20 -0
  54. package/dist/client/hooks.d.mts +59 -0
  55. package/dist/client/hooks.d.ts +59 -0
  56. package/dist/client/seo.d.mts +46 -0
  57. package/dist/client/seo.d.ts +46 -0
  58. package/dist/env.d.mts +61 -0
  59. package/dist/env.d.ts +61 -0
  60. package/dist/file/client.d.mts +53 -1
  61. package/dist/file/client.d.ts +53 -1
  62. package/dist/file/index.cjs.js +0 -1
  63. package/dist/file/index.esm.js +0 -1
  64. package/dist/file/put.cjs.js +0 -1
  65. package/dist/file/put.d.mts +11 -0
  66. package/dist/file/put.d.ts +11 -0
  67. package/dist/file/put.esm.js +0 -1
  68. package/dist/file/setup.cjs.js +0 -1
  69. package/dist/file/setup.d.mts +48 -0
  70. package/dist/file/setup.d.ts +48 -0
  71. package/dist/file/setup.esm.js +0 -1
  72. package/dist/file/utils.d.mts +41 -0
  73. package/dist/file/utils.d.ts +41 -0
  74. package/dist/graphql/client.d.mts +113 -0
  75. package/dist/graphql/client.d.ts +113 -0
  76. package/dist/graphql/errors.d.mts +26 -0
  77. package/dist/graphql/errors.d.ts +26 -0
  78. package/dist/graphql/index.cjs.js +2 -3
  79. package/dist/graphql/index.esm.js +2 -3
  80. package/dist/graphql/init.cjs.js +0 -1
  81. package/dist/graphql/init.d.mts +33 -0
  82. package/dist/graphql/init.d.ts +33 -0
  83. package/dist/graphql/init.esm.js +0 -1
  84. package/dist/graphql/server.d.mts +88 -0
  85. package/dist/graphql/server.d.ts +88 -0
  86. package/dist/graphql/types.d.mts +21 -0
  87. package/dist/graphql/types.d.ts +21 -0
  88. package/dist/graphql/utils.d.mts +217 -0
  89. package/dist/graphql/utils.d.ts +217 -0
  90. package/dist/index.d.mts +16 -0
  91. package/dist/index.d.ts +16 -0
  92. package/dist/socials/instagram/getters.d.mts +115 -0
  93. package/dist/socials/instagram/getters.d.ts +115 -0
  94. package/dist/socials/instagram/setters.d.mts +18 -0
  95. package/dist/socials/instagram/setters.d.ts +18 -0
  96. package/dist/socials/instagram/types.d.mts +46 -0
  97. package/dist/socials/instagram/types.d.ts +46 -0
  98. package/dist/socials/instagram/utils.d.mts +19 -0
  99. package/dist/socials/instagram/utils.d.ts +19 -0
  100. package/dist/socials/instagram/webhook.d.mts +31 -0
  101. package/dist/socials/instagram/webhook.d.ts +31 -0
  102. package/dist/socials/meta-webhook.d.mts +11 -0
  103. package/dist/socials/meta-webhook.d.ts +11 -0
  104. package/dist/socials/threads/getters.d.mts +57 -0
  105. package/dist/socials/threads/getters.d.ts +57 -0
  106. package/dist/socials/threads/setters.d.mts +59 -0
  107. package/dist/socials/threads/setters.d.ts +59 -0
  108. package/dist/socials/threads/types.d.mts +9 -0
  109. package/dist/socials/threads/types.d.ts +9 -0
  110. package/dist/socials/threads/utils.d.mts +19 -0
  111. package/dist/socials/threads/utils.d.ts +19 -0
  112. package/dist/socials/threads/webhook.d.mts +30 -0
  113. package/dist/socials/threads/webhook.d.ts +30 -0
  114. package/package.json +4 -2
@@ -125,7 +125,6 @@ async function checkAuthStatus(redirectUnauthorizedURL) {
125
125
 
126
126
  // src/auth/email/utils.ts
127
127
  import { verify as verify2 } from "jsonwebtoken";
128
- import { cookies as cookies2 } from "next/headers";
129
128
 
130
129
  // src/auth/utils/errors.ts
131
130
  import { NextResponse as NextResponse2 } from "next/server";
@@ -202,19 +201,6 @@ var getContext = (req) => {
202
201
  }
203
202
  return { userId: null };
204
203
  };
205
- async function logout(data) {
206
- const Cookie = await cookies2();
207
- Cookie.delete(REFRESH_COOKIE_NAME);
208
- await fetch(getEnv("NEXT_PUBLIC_EMAIL_AUTH_ENDPOINT" /* NEXT_PUBLIC_EMAIL_AUTH_ENDPOINT */), {
209
- method: "DELETE",
210
- credentials: "include",
211
- body: JSON.stringify(data)
212
- });
213
- }
214
- async function getCurrentRefreshToken() {
215
- const Cookie = await cookies2();
216
- return Cookie.get(REFRESH_COOKIE_NAME)?.value;
217
- }
218
204
 
219
205
  // src/auth/email/routes/delete.ts
220
206
  var getDeleteRoute = (options) => async (req) => {
@@ -498,18 +484,16 @@ function initInstagramAuth(props) {
498
484
  }
499
485
 
500
486
  // src/auth/utils/token.ts
501
- import { cookies as cookies3 } from "next/headers";
487
+ import { cookies as cookies2 } from "next/headers";
502
488
  async function getRefreshToken() {
503
- const Cookie = await cookies3();
489
+ const Cookie = await cookies2();
504
490
  return Cookie.get(REFRESH_COOKIE_NAME)?.value || null;
505
491
  }
506
492
  export {
507
493
  checkAuthStatus,
508
494
  getContext,
509
- getCurrentRefreshToken,
510
495
  getEmailAuthRoutes,
511
496
  getRefreshToken,
512
497
  initGoogleAuth,
513
- initInstagramAuth,
514
- logout
498
+ initInstagramAuth
515
499
  };
@@ -1,3 +1,22 @@
1
+ /**
2
+ * Creates a function that builds the Instagram OAuth authorization URL for a given state token.
3
+ * The state token is typically the user's access token, used to link the Instagram account to the logged-in user.
4
+ *
5
+ * @param redirectURL - The OAuth redirect URI registered with Instagram (e.g. `NEXT_PUBLIC_INSTAGRAM_AUTH_ENDPOINT`).
6
+ * @returns A function `(stateToken: string) => string` that returns the full authorization URL.
7
+ *
8
+ * @example
9
+ * ```ts
10
+ * import { getInstagramAuthorizationURLSetup } from "naystack/auth/instagram/client";
11
+ *
12
+ * const getAuthURL = getInstagramAuthorizationURLSetup("/api/instagram");
13
+ * const url = getAuthURL(userAccessToken);
14
+ * // => "https://www.instagram.com/oauth/authorize?client_id=...&state=...&redirect_uri=..."
15
+ * window.location.href = url;
16
+ * ```
17
+ *
18
+ * @category Auth
19
+ */
1
20
  declare const getInstagramAuthorizationURLSetup: (redirectURL: string) => (token: string) => string;
2
21
 
3
22
  export { getInstagramAuthorizationURLSetup };
@@ -1,3 +1,22 @@
1
+ /**
2
+ * Creates a function that builds the Instagram OAuth authorization URL for a given state token.
3
+ * The state token is typically the user's access token, used to link the Instagram account to the logged-in user.
4
+ *
5
+ * @param redirectURL - The OAuth redirect URI registered with Instagram (e.g. `NEXT_PUBLIC_INSTAGRAM_AUTH_ENDPOINT`).
6
+ * @returns A function `(stateToken: string) => string` that returns the full authorization URL.
7
+ *
8
+ * @example
9
+ * ```ts
10
+ * import { getInstagramAuthorizationURLSetup } from "naystack/auth/instagram/client";
11
+ *
12
+ * const getAuthURL = getInstagramAuthorizationURLSetup("/api/instagram");
13
+ * const url = getAuthURL(userAccessToken);
14
+ * // => "https://www.instagram.com/oauth/authorize?client_id=...&state=...&redirect_uri=..."
15
+ * window.location.href = url;
16
+ * ```
17
+ *
18
+ * @category Auth
19
+ */
1
20
  declare const getInstagramAuthorizationURLSetup: (redirectURL: string) => (token: string) => string;
2
21
 
3
22
  export { getInstagramAuthorizationURLSetup };
@@ -2,12 +2,49 @@ import * as next_server from 'next/server';
2
2
  import { getRefreshedAccessToken } from './utils.mjs';
3
3
  import { InstagramUser } from '../../socials/instagram/types.mjs';
4
4
 
5
+ /**
6
+ * Options for initializing Instagram OAuth via {@link initInstagramAuth}.
7
+ *
8
+ * @property onUser - Called with `(instagramUser, appUserId, accessToken)` after successful OAuth. Return a string to show as error (redirects to `errorRedirectURL`); return `void` on success.
9
+ * @property successRedirectURL - Where to redirect after successful Instagram auth.
10
+ * @property errorRedirectURL - Where to redirect on error (with `?error=` query param).
11
+ * @property refreshKey - Your app secret (e.g. `REFRESH_KEY` env var) used in the flow.
12
+ *
13
+ * @category Auth
14
+ */
5
15
  interface InitInstagramAuthOptions {
6
16
  onUser: (data: InstagramUser, id: number | null, accessToken: string) => Promise<string | void>;
7
17
  successRedirectURL: string;
8
18
  errorRedirectURL: string;
9
19
  refreshKey: string;
10
20
  }
21
+ /**
22
+ * Initializes Instagram OAuth. Returns a GET handler for the OAuth callback and a helper to refresh long-lived tokens.
23
+ *
24
+ * Mount the GET handler on your Instagram auth route (e.g. `app/api/(auth)/instagram/route.ts`).
25
+ *
26
+ * Requires env vars: `INSTAGRAM_CLIENT_ID`, `INSTAGRAM_CLIENT_SECRET`, `NEXT_PUBLIC_INSTAGRAM_AUTH_ENDPOINT`.
27
+ *
28
+ * @param props - Options. See {@link InitInstagramAuthOptions}.
29
+ * @returns Object with `GET` (route handler) and `getRefreshedAccessToken` (refreshes a long-lived token).
30
+ *
31
+ * @example
32
+ * ```ts
33
+ * // app/api/(auth)/instagram/route.ts
34
+ * import { initInstagramAuth } from "naystack/auth";
35
+ *
36
+ * export const { GET, getRefreshedAccessToken } = initInstagramAuth({
37
+ * onUser: async (igUser, appUserId, accessToken) => {
38
+ * await saveInstagramUser(appUserId, igUser, accessToken);
39
+ * },
40
+ * successRedirectURL: "/dashboard",
41
+ * errorRedirectURL: "/login",
42
+ * refreshKey: process.env.REFRESH_KEY!,
43
+ * });
44
+ * ```
45
+ *
46
+ * @category Auth
47
+ */
11
48
  declare function initInstagramAuth(props: InitInstagramAuthOptions): {
12
49
  GET: (req: next_server.NextRequest) => Promise<next_server.NextResponse<unknown>>;
13
50
  getRefreshedAccessToken: typeof getRefreshedAccessToken;
@@ -2,12 +2,49 @@ import * as next_server from 'next/server';
2
2
  import { getRefreshedAccessToken } from './utils.js';
3
3
  import { InstagramUser } from '../../socials/instagram/types.js';
4
4
 
5
+ /**
6
+ * Options for initializing Instagram OAuth via {@link initInstagramAuth}.
7
+ *
8
+ * @property onUser - Called with `(instagramUser, appUserId, accessToken)` after successful OAuth. Return a string to show as error (redirects to `errorRedirectURL`); return `void` on success.
9
+ * @property successRedirectURL - Where to redirect after successful Instagram auth.
10
+ * @property errorRedirectURL - Where to redirect on error (with `?error=` query param).
11
+ * @property refreshKey - Your app secret (e.g. `REFRESH_KEY` env var) used in the flow.
12
+ *
13
+ * @category Auth
14
+ */
5
15
  interface InitInstagramAuthOptions {
6
16
  onUser: (data: InstagramUser, id: number | null, accessToken: string) => Promise<string | void>;
7
17
  successRedirectURL: string;
8
18
  errorRedirectURL: string;
9
19
  refreshKey: string;
10
20
  }
21
+ /**
22
+ * Initializes Instagram OAuth. Returns a GET handler for the OAuth callback and a helper to refresh long-lived tokens.
23
+ *
24
+ * Mount the GET handler on your Instagram auth route (e.g. `app/api/(auth)/instagram/route.ts`).
25
+ *
26
+ * Requires env vars: `INSTAGRAM_CLIENT_ID`, `INSTAGRAM_CLIENT_SECRET`, `NEXT_PUBLIC_INSTAGRAM_AUTH_ENDPOINT`.
27
+ *
28
+ * @param props - Options. See {@link InitInstagramAuthOptions}.
29
+ * @returns Object with `GET` (route handler) and `getRefreshedAccessToken` (refreshes a long-lived token).
30
+ *
31
+ * @example
32
+ * ```ts
33
+ * // app/api/(auth)/instagram/route.ts
34
+ * import { initInstagramAuth } from "naystack/auth";
35
+ *
36
+ * export const { GET, getRefreshedAccessToken } = initInstagramAuth({
37
+ * onUser: async (igUser, appUserId, accessToken) => {
38
+ * await saveInstagramUser(appUserId, igUser, accessToken);
39
+ * },
40
+ * successRedirectURL: "/dashboard",
41
+ * errorRedirectURL: "/login",
42
+ * refreshKey: process.env.REFRESH_KEY!,
43
+ * });
44
+ * ```
45
+ *
46
+ * @category Auth
47
+ */
11
48
  declare function initInstagramAuth(props: InitInstagramAuthOptions): {
12
49
  GET: (req: next_server.NextRequest) => Promise<next_server.NextResponse<unknown>>;
13
50
  getRefreshedAccessToken: typeof getRefreshedAccessToken;
@@ -3,6 +3,11 @@ import { InitInstagramAuthOptions } from './index.mjs';
3
3
  import './utils.mjs';
4
4
  import '../../socials/instagram/types.mjs';
5
5
 
6
+ /**
7
+ * Returns the GET route handler for Instagram OAuth callback.
8
+ * @param options - InitInstagramAuthOptions (onUser, redirect URLs)
9
+ * @returns Async route handler for the OAuth callback
10
+ */
6
11
  declare const getInstagramRoute: ({ successRedirectURL, errorRedirectURL, onUser, }: InitInstagramAuthOptions) => (req: NextRequest) => Promise<NextResponse<unknown>>;
7
12
 
8
13
  export { getInstagramRoute };
@@ -3,6 +3,11 @@ import { InitInstagramAuthOptions } from './index.js';
3
3
  import './utils.js';
4
4
  import '../../socials/instagram/types.js';
5
5
 
6
+ /**
7
+ * Returns the GET route handler for Instagram OAuth callback.
8
+ * @param options - InitInstagramAuthOptions (onUser, redirect URLs)
9
+ * @returns Async route handler for the OAuth callback
10
+ */
6
11
  declare const getInstagramRoute: ({ successRedirectURL, errorRedirectURL, onUser, }: InitInstagramAuthOptions) => (req: NextRequest) => Promise<NextResponse<unknown>>;
7
12
 
8
13
  export { getInstagramRoute };
@@ -1,4 +1,17 @@
1
+ /**
2
+ * Exchanges a long-lived Instagram token for a refreshed token.
3
+ * @param token - Current long-lived access token
4
+ * @returns New access token or undefined
5
+ */
1
6
  declare function getRefreshedAccessToken(token: string): Promise<string | undefined>;
7
+ /**
8
+ * Exchanges an OAuth code for a long-lived Instagram access token.
9
+ * @param code - OAuth authorization code from redirect
10
+ * @param redirectURL - Registered redirect URI
11
+ * @param clientId - Instagram app client id
12
+ * @param clientSecret - Instagram app client secret
13
+ * @returns Object with accessToken and userId, or undefined
14
+ */
2
15
  declare function getLongLivedToken(code: string, redirectURL: string, clientId: string, clientSecret: string): Promise<{
3
16
  accessToken: string;
4
17
  userId: string;
@@ -1,4 +1,17 @@
1
+ /**
2
+ * Exchanges a long-lived Instagram token for a refreshed token.
3
+ * @param token - Current long-lived access token
4
+ * @returns New access token or undefined
5
+ */
1
6
  declare function getRefreshedAccessToken(token: string): Promise<string | undefined>;
7
+ /**
8
+ * Exchanges an OAuth code for a long-lived Instagram access token.
9
+ * @param code - OAuth authorization code from redirect
10
+ * @param redirectURL - Registered redirect URI
11
+ * @param clientId - Instagram app client id
12
+ * @param clientSecret - Instagram app client secret
13
+ * @returns Object with accessToken and userId, or undefined
14
+ */
2
15
  declare function getLongLivedToken(code: string, redirectURL: string, clientId: string, clientSecret: string): Promise<{
3
16
  accessToken: string;
4
17
  userId: string;
@@ -1,9 +1,33 @@
1
1
  import { NextResponse } from 'next/server';
2
2
 
3
+ /**
4
+ * Custom error handler for auth routes. Return a NextResponse to send a custom error; otherwise the default response is used.
5
+ *
6
+ * @param error - Object with `status` (HTTP code) and `message` (error text).
7
+ * @returns NextResponse to override the default error, or undefined to use the default.
8
+ *
9
+ * @example
10
+ * ```ts
11
+ * const onError: ErrorHandler = ({ status, message }) => {
12
+ * if (status === 400) return NextResponse.json({ error: message }, { status: 400 });
13
+ * return undefined; // Use default handling
14
+ * };
15
+ * ```
16
+ *
17
+ * @category Auth
18
+ */
3
19
  type ErrorHandler = (error: {
4
20
  status: number;
5
21
  message: string;
6
22
  }) => NextResponse;
23
+ /**
24
+ * Shape expected from `getUser` / `createUser` callbacks: at least `id` and optional `password` hash, plus any extra fields.
25
+ *
26
+ * @property id - User id (numeric primary key).
27
+ * @property password - Bcrypt-hashed password, or `null` for OAuth-only users.
28
+ *
29
+ * @category Auth
30
+ */
7
31
  type UserOutput = {
8
32
  id: number;
9
33
  password: string | null;
@@ -1,9 +1,33 @@
1
1
  import { NextResponse } from 'next/server';
2
2
 
3
+ /**
4
+ * Custom error handler for auth routes. Return a NextResponse to send a custom error; otherwise the default response is used.
5
+ *
6
+ * @param error - Object with `status` (HTTP code) and `message` (error text).
7
+ * @returns NextResponse to override the default error, or undefined to use the default.
8
+ *
9
+ * @example
10
+ * ```ts
11
+ * const onError: ErrorHandler = ({ status, message }) => {
12
+ * if (status === 400) return NextResponse.json({ error: message }, { status: 400 });
13
+ * return undefined; // Use default handling
14
+ * };
15
+ * ```
16
+ *
17
+ * @category Auth
18
+ */
3
19
  type ErrorHandler = (error: {
4
20
  status: number;
5
21
  message: string;
6
22
  }) => NextResponse;
23
+ /**
24
+ * Shape expected from `getUser` / `createUser` callbacks: at least `id` and optional `password` hash, plus any extra fields.
25
+ *
26
+ * @property id - User id (numeric primary key).
27
+ * @property password - Bcrypt-hashed password, or `null` for OAuth-only users.
28
+ *
29
+ * @category Auth
30
+ */
7
31
  type UserOutput = {
8
32
  id: number;
9
33
  password: string | null;
@@ -1,6 +1,16 @@
1
1
  import { NextResponse } from 'next/server';
2
2
  import { ErrorHandler } from '../types.mjs';
3
3
 
4
+ /**
5
+ * Creates a NextResponse for an error, or delegates to a custom `onError` handler if provided.
6
+ * Used internally by auth routes for consistent error handling.
7
+ *
8
+ * @param status - HTTP status code.
9
+ * @param message - Error message body.
10
+ * @param onError - Optional custom handler; if it returns a Response, that is used instead of the default.
11
+ * @returns NextResponse with the given status and message, or the custom handler's response.
12
+ * @category Auth
13
+ */
4
14
  declare function handleError(status: number, message: string, onError?: ErrorHandler): NextResponse<unknown>;
5
15
 
6
16
  export { handleError };
@@ -1,6 +1,16 @@
1
1
  import { NextResponse } from 'next/server';
2
2
  import { ErrorHandler } from '../types.js';
3
3
 
4
+ /**
5
+ * Creates a NextResponse for an error, or delegates to a custom `onError` handler if provided.
6
+ * Used internally by auth routes for consistent error handling.
7
+ *
8
+ * @param status - HTTP status code.
9
+ * @param message - Error message body.
10
+ * @param onError - Optional custom handler; if it returns a Response, that is used instead of the default.
11
+ * @returns NextResponse with the given status and message, or the custom handler's response.
12
+ * @category Auth
13
+ */
4
14
  declare function handleError(status: number, message: string, onError?: ErrorHandler): NextResponse<unknown>;
5
15
 
6
16
  export { handleError };
@@ -1,3 +1,23 @@
1
+ /**
2
+ * Reads the refresh token from cookies (server-side only). Use this in Server Components, layouts,
3
+ * or Server Actions to check if the user is authenticated.
4
+ *
5
+ * @returns The refresh token string, or `null` if no refresh cookie is present.
6
+ *
7
+ * @example
8
+ * ```ts
9
+ * import { getRefreshToken } from "naystack/auth";
10
+ * import { redirect } from "next/navigation";
11
+ *
12
+ * export default async function ProtectedLayout({ children }: { children: React.ReactNode }) {
13
+ * const token = await getRefreshToken();
14
+ * if (!token) return redirect("/login");
15
+ * return <div>{children}</div>;
16
+ * }
17
+ * ```
18
+ *
19
+ * @category Auth
20
+ */
1
21
  declare function getRefreshToken(): Promise<string | null>;
2
22
 
3
23
  export { getRefreshToken };
@@ -1,3 +1,23 @@
1
+ /**
2
+ * Reads the refresh token from cookies (server-side only). Use this in Server Components, layouts,
3
+ * or Server Actions to check if the user is authenticated.
4
+ *
5
+ * @returns The refresh token string, or `null` if no refresh cookie is present.
6
+ *
7
+ * @example
8
+ * ```ts
9
+ * import { getRefreshToken } from "naystack/auth";
10
+ * import { redirect } from "next/navigation";
11
+ *
12
+ * export default async function ProtectedLayout({ children }: { children: React.ReactNode }) {
13
+ * const token = await getRefreshToken();
14
+ * if (!token) return redirect("/login");
15
+ * return <div>{children}</div>;
16
+ * }
17
+ * ```
18
+ *
19
+ * @category Auth
20
+ */
1
21
  declare function getRefreshToken(): Promise<string | null>;
2
22
 
3
23
  export { getRefreshToken };
@@ -1,6 +1,65 @@
1
1
  import * as React from 'react';
2
2
 
3
+ /**
4
+ * Tracks when a DOM element enters the viewport and calls a callback.
5
+ * Uses `IntersectionObserver` with `rootMargin: "100px"` and `threshold: 0.1`.
6
+ *
7
+ * Attach the returned ref to the element you want to observe.
8
+ *
9
+ * @param onVisible - Optional callback invoked once when the observed element becomes visible.
10
+ * @returns A ref object to attach to the observed element (e.g. `<div ref={ref}>`).
11
+ *
12
+ * @example Lazy-load content when a section enters the viewport:
13
+ * ```tsx
14
+ * import { useVisibility } from "naystack/client";
15
+ *
16
+ * function LazySection() {
17
+ * const [loaded, setLoaded] = useState(false);
18
+ * const ref = useVisibility(() => setLoaded(true));
19
+ *
20
+ * return (
21
+ * <section ref={ref}>
22
+ * {loaded ? <HeavyContent /> : <Placeholder />}
23
+ * </section>
24
+ * );
25
+ * }
26
+ * ```
27
+ *
28
+ * @example Trigger analytics when an element is seen:
29
+ * ```tsx
30
+ * const ref = useVisibility(() => trackImpression("hero-banner"));
31
+ * return <div ref={ref}>...</div>;
32
+ * ```
33
+ *
34
+ * @category Client
35
+ */
3
36
  declare function useVisibility(onVisible?: () => void): React.RefObject<null>;
37
+ /**
38
+ * Returns whether a CSS media query currently matches. Useful for responsive behavior in JS.
39
+ *
40
+ * Returns `null` during SSR / before the first client-side check (to avoid hydration mismatches).
41
+ *
42
+ * @param query - A valid CSS media query string (e.g. `"(min-width: 768px)"`, `"(prefers-color-scheme: dark)"`).
43
+ * @returns `true` if the query matches, `false` if it doesn't, or `null` during SSR.
44
+ *
45
+ * @example Responsive navigation:
46
+ * ```tsx
47
+ * import { useBreakpoint } from "naystack/client";
48
+ *
49
+ * function ResponsiveNav() {
50
+ * const isMobile = useBreakpoint("(max-width: 639px)");
51
+ * if (isMobile === null) return <Skeleton />; // SSR fallback
52
+ * return isMobile ? <MobileNav /> : <DesktopNav />;
53
+ * }
54
+ * ```
55
+ *
56
+ * @example Detect user preferences:
57
+ * ```tsx
58
+ * const prefersReducedMotion = useBreakpoint("(prefers-reduced-motion: reduce)");
59
+ * ```
60
+ *
61
+ * @category Client
62
+ */
4
63
  declare function useBreakpoint(query: string): boolean | null;
5
64
 
6
65
  export { useBreakpoint, useVisibility };
@@ -1,6 +1,65 @@
1
1
  import * as React from 'react';
2
2
 
3
+ /**
4
+ * Tracks when a DOM element enters the viewport and calls a callback.
5
+ * Uses `IntersectionObserver` with `rootMargin: "100px"` and `threshold: 0.1`.
6
+ *
7
+ * Attach the returned ref to the element you want to observe.
8
+ *
9
+ * @param onVisible - Optional callback invoked once when the observed element becomes visible.
10
+ * @returns A ref object to attach to the observed element (e.g. `<div ref={ref}>`).
11
+ *
12
+ * @example Lazy-load content when a section enters the viewport:
13
+ * ```tsx
14
+ * import { useVisibility } from "naystack/client";
15
+ *
16
+ * function LazySection() {
17
+ * const [loaded, setLoaded] = useState(false);
18
+ * const ref = useVisibility(() => setLoaded(true));
19
+ *
20
+ * return (
21
+ * <section ref={ref}>
22
+ * {loaded ? <HeavyContent /> : <Placeholder />}
23
+ * </section>
24
+ * );
25
+ * }
26
+ * ```
27
+ *
28
+ * @example Trigger analytics when an element is seen:
29
+ * ```tsx
30
+ * const ref = useVisibility(() => trackImpression("hero-banner"));
31
+ * return <div ref={ref}>...</div>;
32
+ * ```
33
+ *
34
+ * @category Client
35
+ */
3
36
  declare function useVisibility(onVisible?: () => void): React.RefObject<null>;
37
+ /**
38
+ * Returns whether a CSS media query currently matches. Useful for responsive behavior in JS.
39
+ *
40
+ * Returns `null` during SSR / before the first client-side check (to avoid hydration mismatches).
41
+ *
42
+ * @param query - A valid CSS media query string (e.g. `"(min-width: 768px)"`, `"(prefers-color-scheme: dark)"`).
43
+ * @returns `true` if the query matches, `false` if it doesn't, or `null` during SSR.
44
+ *
45
+ * @example Responsive navigation:
46
+ * ```tsx
47
+ * import { useBreakpoint } from "naystack/client";
48
+ *
49
+ * function ResponsiveNav() {
50
+ * const isMobile = useBreakpoint("(max-width: 639px)");
51
+ * if (isMobile === null) return <Skeleton />; // SSR fallback
52
+ * return isMobile ? <MobileNav /> : <DesktopNav />;
53
+ * }
54
+ * ```
55
+ *
56
+ * @example Detect user preferences:
57
+ * ```tsx
58
+ * const prefersReducedMotion = useBreakpoint("(prefers-reduced-motion: reduce)");
59
+ * ```
60
+ *
61
+ * @category Client
62
+ */
4
63
  declare function useBreakpoint(query: string): boolean | null;
5
64
 
6
65
  export { useBreakpoint, useVisibility };
@@ -1,5 +1,51 @@
1
1
  import { Metadata } from 'next';
2
2
 
3
+ /**
4
+ * Creates a metadata factory for Next.js pages. Call once with your site's default SEO config,
5
+ * then call the returned function per-page to generate the `Metadata` object.
6
+ *
7
+ * The returned function supports page-specific `title`, `description`, and `image` overrides.
8
+ * When a page title is provided, it's formatted as `"Page Title • Site Name"`.
9
+ *
10
+ * @param SEO - Base defaults for the whole site.
11
+ * @param SEO.title - Default document title (used when no page-specific title is provided).
12
+ * @param SEO.description - Default meta description.
13
+ * @param SEO.siteName - Application/site name (used in openGraph, twitter, and as the separator in titles).
14
+ * @param SEO.themeColor - Theme color for mobile browsers (e.g. `"#000000"`).
15
+ * @returns A function `(title?, description?, image?) => Metadata`. Pass page-specific overrides; they fill in or replace the defaults.
16
+ *
17
+ * @example Setup in a utility file:
18
+ * ```ts
19
+ * // lib/utils/seo.ts
20
+ * import { setupSEO } from "naystack/client";
21
+ *
22
+ * export const getSEO = setupSEO({
23
+ * title: "Land Exchange Toolbox - Premium Real Estate Tools",
24
+ * description: "Empower your real estate business with advanced tools.",
25
+ * siteName: "Land Exchange Toolbox",
26
+ * themeColor: "#5b9364",
27
+ * });
28
+ * ```
29
+ *
30
+ * @example Usage in a page:
31
+ * ```ts
32
+ * // app/dashboard/page.tsx
33
+ * import { getSEO } from "@/lib/utils/seo";
34
+ *
35
+ * export const metadata = getSEO("Dashboard", "Your personalized dashboard");
36
+ * // => title: "Dashboard • Land Exchange Toolbox", description: "Your personalized dashboard"
37
+ * ```
38
+ *
39
+ * @example Usage in generateMetadata:
40
+ * ```ts
41
+ * export async function generateMetadata({ params }) {
42
+ * const deal = await getDeal(params.id);
43
+ * return getSEO(deal.title, deal.description, deal.coverImage);
44
+ * }
45
+ * ```
46
+ *
47
+ * @category Client
48
+ */
3
49
  declare const setupSEO: (SEO: {
4
50
  title: string;
5
51
  description: string;
@@ -1,5 +1,51 @@
1
1
  import { Metadata } from 'next';
2
2
 
3
+ /**
4
+ * Creates a metadata factory for Next.js pages. Call once with your site's default SEO config,
5
+ * then call the returned function per-page to generate the `Metadata` object.
6
+ *
7
+ * The returned function supports page-specific `title`, `description`, and `image` overrides.
8
+ * When a page title is provided, it's formatted as `"Page Title • Site Name"`.
9
+ *
10
+ * @param SEO - Base defaults for the whole site.
11
+ * @param SEO.title - Default document title (used when no page-specific title is provided).
12
+ * @param SEO.description - Default meta description.
13
+ * @param SEO.siteName - Application/site name (used in openGraph, twitter, and as the separator in titles).
14
+ * @param SEO.themeColor - Theme color for mobile browsers (e.g. `"#000000"`).
15
+ * @returns A function `(title?, description?, image?) => Metadata`. Pass page-specific overrides; they fill in or replace the defaults.
16
+ *
17
+ * @example Setup in a utility file:
18
+ * ```ts
19
+ * // lib/utils/seo.ts
20
+ * import { setupSEO } from "naystack/client";
21
+ *
22
+ * export const getSEO = setupSEO({
23
+ * title: "Land Exchange Toolbox - Premium Real Estate Tools",
24
+ * description: "Empower your real estate business with advanced tools.",
25
+ * siteName: "Land Exchange Toolbox",
26
+ * themeColor: "#5b9364",
27
+ * });
28
+ * ```
29
+ *
30
+ * @example Usage in a page:
31
+ * ```ts
32
+ * // app/dashboard/page.tsx
33
+ * import { getSEO } from "@/lib/utils/seo";
34
+ *
35
+ * export const metadata = getSEO("Dashboard", "Your personalized dashboard");
36
+ * // => title: "Dashboard • Land Exchange Toolbox", description: "Your personalized dashboard"
37
+ * ```
38
+ *
39
+ * @example Usage in generateMetadata:
40
+ * ```ts
41
+ * export async function generateMetadata({ params }) {
42
+ * const deal = await getDeal(params.id);
43
+ * return getSEO(deal.title, deal.description, deal.coverImage);
44
+ * }
45
+ * ```
46
+ *
47
+ * @category Client
48
+ */
3
49
  declare const setupSEO: (SEO: {
4
50
  title: string;
5
51
  description: string;