naystack 1.5.8 → 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.
- package/README.md +646 -91
- package/dist/auth/constants.d.mts +4 -0
- package/dist/auth/constants.d.ts +4 -0
- package/dist/auth/email/client.d.mts +149 -0
- package/dist/auth/email/client.d.ts +149 -0
- package/dist/auth/email/index.cjs.js +2 -14
- package/dist/auth/email/index.d.mts +41 -1
- package/dist/auth/email/index.d.ts +41 -1
- package/dist/auth/email/index.esm.js +1 -12
- package/dist/auth/email/routes/delete.cjs.js +0 -1
- package/dist/auth/email/routes/delete.d.mts +5 -0
- package/dist/auth/email/routes/delete.d.ts +5 -0
- package/dist/auth/email/routes/delete.esm.js +0 -1
- package/dist/auth/email/routes/get.d.mts +5 -0
- package/dist/auth/email/routes/get.d.ts +5 -0
- package/dist/auth/email/routes/post.cjs.js +0 -1
- package/dist/auth/email/routes/post.d.mts +5 -0
- package/dist/auth/email/routes/post.d.ts +5 -0
- package/dist/auth/email/routes/post.esm.js +0 -1
- package/dist/auth/email/routes/put.cjs.js +0 -1
- package/dist/auth/email/routes/put.d.mts +5 -0
- package/dist/auth/email/routes/put.d.ts +5 -0
- package/dist/auth/email/routes/put.esm.js +0 -1
- package/dist/auth/email/token.d.mts +62 -0
- package/dist/auth/email/token.d.ts +62 -0
- package/dist/auth/email/types.d.mts +22 -0
- package/dist/auth/email/types.d.ts +22 -0
- package/dist/auth/email/utils.cjs.js +0 -12
- package/dist/auth/email/utils.d.mts +41 -2
- package/dist/auth/email/utils.d.ts +41 -2
- package/dist/auth/email/utils.esm.js +0 -11
- package/dist/auth/google/get.d.mts +5 -0
- package/dist/auth/google/get.d.ts +5 -0
- package/dist/auth/google/index.d.mts +39 -0
- package/dist/auth/google/index.d.ts +39 -0
- package/dist/auth/index.cjs.js +4 -16
- package/dist/auth/index.d.mts +1 -1
- package/dist/auth/index.d.ts +1 -1
- package/dist/auth/index.esm.js +3 -14
- package/dist/auth/instagram/client.d.mts +19 -0
- package/dist/auth/instagram/client.d.ts +19 -0
- package/dist/auth/instagram/index.d.mts +37 -0
- package/dist/auth/instagram/index.d.ts +37 -0
- package/dist/auth/instagram/route.d.mts +5 -0
- package/dist/auth/instagram/route.d.ts +5 -0
- package/dist/auth/instagram/utils.d.mts +13 -0
- package/dist/auth/instagram/utils.d.ts +13 -0
- package/dist/auth/types.d.mts +24 -0
- package/dist/auth/types.d.ts +24 -0
- package/dist/auth/utils/errors.d.mts +10 -0
- package/dist/auth/utils/errors.d.ts +10 -0
- package/dist/auth/utils/token.d.mts +20 -0
- package/dist/auth/utils/token.d.ts +20 -0
- package/dist/client/hooks.d.mts +59 -0
- package/dist/client/hooks.d.ts +59 -0
- package/dist/client/seo.d.mts +46 -0
- package/dist/client/seo.d.ts +46 -0
- package/dist/env.d.mts +61 -0
- package/dist/env.d.ts +61 -0
- package/dist/file/client.d.mts +53 -1
- package/dist/file/client.d.ts +53 -1
- package/dist/file/index.cjs.js +0 -1
- package/dist/file/index.esm.js +0 -1
- package/dist/file/put.cjs.js +0 -1
- package/dist/file/put.d.mts +11 -0
- package/dist/file/put.d.ts +11 -0
- package/dist/file/put.esm.js +0 -1
- package/dist/file/setup.cjs.js +0 -1
- package/dist/file/setup.d.mts +48 -0
- package/dist/file/setup.d.ts +48 -0
- package/dist/file/setup.esm.js +0 -1
- package/dist/file/utils.d.mts +41 -0
- package/dist/file/utils.d.ts +41 -0
- package/dist/graphql/client.d.mts +113 -0
- package/dist/graphql/client.d.ts +113 -0
- package/dist/graphql/errors.d.mts +26 -0
- package/dist/graphql/errors.d.ts +26 -0
- package/dist/graphql/index.cjs.js +2 -3
- package/dist/graphql/index.esm.js +2 -3
- package/dist/graphql/init.cjs.js +0 -1
- package/dist/graphql/init.d.mts +33 -0
- package/dist/graphql/init.d.ts +33 -0
- package/dist/graphql/init.esm.js +0 -1
- package/dist/graphql/server.d.mts +88 -0
- package/dist/graphql/server.d.ts +88 -0
- package/dist/graphql/types.d.mts +21 -0
- package/dist/graphql/types.d.ts +21 -0
- package/dist/graphql/utils.d.mts +217 -0
- package/dist/graphql/utils.d.ts +217 -0
- package/dist/index.d.mts +16 -0
- package/dist/index.d.ts +16 -0
- package/dist/socials/instagram/getters.d.mts +115 -0
- package/dist/socials/instagram/getters.d.ts +115 -0
- package/dist/socials/instagram/setters.d.mts +18 -0
- package/dist/socials/instagram/setters.d.ts +18 -0
- package/dist/socials/instagram/types.d.mts +46 -0
- package/dist/socials/instagram/types.d.ts +46 -0
- package/dist/socials/instagram/utils.d.mts +19 -0
- package/dist/socials/instagram/utils.d.ts +19 -0
- package/dist/socials/instagram/webhook.d.mts +31 -0
- package/dist/socials/instagram/webhook.d.ts +31 -0
- package/dist/socials/meta-webhook.d.mts +11 -0
- package/dist/socials/meta-webhook.d.ts +11 -0
- package/dist/socials/threads/getters.d.mts +57 -0
- package/dist/socials/threads/getters.d.ts +57 -0
- package/dist/socials/threads/setters.d.mts +59 -0
- package/dist/socials/threads/setters.d.ts +59 -0
- package/dist/socials/threads/types.d.mts +9 -0
- package/dist/socials/threads/types.d.ts +9 -0
- package/dist/socials/threads/utils.d.mts +19 -0
- package/dist/socials/threads/utils.d.ts +19 -0
- package/dist/socials/threads/webhook.d.mts +30 -0
- package/dist/socials/threads/webhook.d.ts +30 -0
- package/package.json +4 -2
|
@@ -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;
|
package/dist/auth/types.d.mts
CHANGED
|
@@ -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;
|
package/dist/auth/types.d.ts
CHANGED
|
@@ -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 };
|
package/dist/client/hooks.d.mts
CHANGED
|
@@ -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 };
|
package/dist/client/hooks.d.ts
CHANGED
|
@@ -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 };
|
package/dist/client/seo.d.mts
CHANGED
|
@@ -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;
|
package/dist/client/seo.d.ts
CHANGED
|
@@ -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;
|
package/dist/env.d.mts
CHANGED
|
@@ -1,24 +1,85 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Enum of all environment variable keys used by the naystack stack.
|
|
3
|
+
* Use with {@link getEnv} or {@link getEnvValue} to read these variables.
|
|
4
|
+
*
|
|
5
|
+
* @category Environment
|
|
6
|
+
*/
|
|
1
7
|
declare enum EnvVariable {
|
|
8
|
+
/** GraphQL endpoint URL (client-side, e.g. `/api/graphql`). */
|
|
2
9
|
NEXT_PUBLIC_GRAPHQL_ENDPOINT = "NEXT_PUBLIC_GRAPHQL_ENDPOINT",
|
|
10
|
+
/** Email auth endpoint URL (client-side, e.g. `/api/email`). */
|
|
3
11
|
NEXT_PUBLIC_EMAIL_AUTH_ENDPOINT = "NEXT_PUBLIC_EMAIL_AUTH_ENDPOINT",
|
|
12
|
+
/** Google OAuth endpoint URL (client-side, e.g. `/api/google`). */
|
|
4
13
|
NEXT_PUBLIC_GOOGLE_AUTH_ENDPOINT = "NEXT_PUBLIC_GOOGLE_AUTH_ENDPOINT",
|
|
14
|
+
/** Instagram OAuth endpoint URL (client-side, e.g. `/api/instagram`). */
|
|
5
15
|
NEXT_PUBLIC_INSTAGRAM_AUTH_ENDPOINT = "NEXT_PUBLIC_INSTAGRAM_AUTH_ENDPOINT",
|
|
16
|
+
/** File upload endpoint URL (client-side, e.g. `/api/file`). */
|
|
6
17
|
NEXT_PUBLIC_FILE_ENDPOINT = "NEXT_PUBLIC_FILE_ENDPOINT",
|
|
18
|
+
/** Base URL of the app (e.g. `https://yourapp.com`). Used for SEO and Apple Web App metadata. */
|
|
7
19
|
NEXT_PUBLIC_BASE_URL = "NEXT_PUBLIC_BASE_URL",
|
|
20
|
+
/** Secret key for signing JWT refresh tokens. */
|
|
8
21
|
REFRESH_KEY = "REFRESH_KEY",
|
|
22
|
+
/** Secret key for signing JWT access tokens. */
|
|
9
23
|
SIGNING_KEY = "SIGNING_KEY",
|
|
24
|
+
/** Instagram app client secret (from Meta Developer Portal). */
|
|
10
25
|
INSTAGRAM_CLIENT_SECRET = "INSTAGRAM_CLIENT_SECRET",
|
|
26
|
+
/** Instagram app client id (from Meta Developer Portal). */
|
|
11
27
|
INSTAGRAM_CLIENT_ID = "INSTAGRAM_CLIENT_ID",
|
|
28
|
+
/** Google OAuth client secret (from Google Cloud Console). */
|
|
12
29
|
GOOGLE_CLIENT_SECRET = "GOOGLE_CLIENT_SECRET",
|
|
30
|
+
/** Google OAuth client id (from Google Cloud Console). */
|
|
13
31
|
GOOGLE_CLIENT_ID = "GOOGLE_CLIENT_ID",
|
|
32
|
+
/** Cloudflare Turnstile secret key (optional — enables captcha on auth routes). */
|
|
14
33
|
TURNSTILE_KEY = "TURNSTILE_KEY",
|
|
34
|
+
/** AWS access key id for S3. */
|
|
15
35
|
AWS_ACCESS_KEY_ID = "AWS_ACCESS_KEY_ID",
|
|
36
|
+
/** AWS secret access key for S3. */
|
|
16
37
|
AWS_ACCESS_KEY_SECRET = "AWS_ACCESS_KEY_SECRET",
|
|
38
|
+
/** AWS region for S3 (e.g. `us-east-1`). */
|
|
17
39
|
AWS_REGION = "AWS_REGION",
|
|
40
|
+
/** AWS S3 bucket name. */
|
|
18
41
|
AWS_BUCKET = "AWS_BUCKET",
|
|
42
|
+
/** Node environment (`development`, `production`, etc.). Used for Apollo landing page and introspection. */
|
|
19
43
|
NODE_ENV = "NODE_ENV"
|
|
20
44
|
}
|
|
45
|
+
/**
|
|
46
|
+
* Reads an environment variable by key. Does **not** throw if the value is missing.
|
|
47
|
+
*
|
|
48
|
+
* @param key - One of the {@link EnvVariable} enum values.
|
|
49
|
+
* @returns The value of the env var, or `undefined` if unset.
|
|
50
|
+
*
|
|
51
|
+
* @example
|
|
52
|
+
* ```ts
|
|
53
|
+
* import { getEnvValue, EnvVariable } from "naystack/env";
|
|
54
|
+
*
|
|
55
|
+
* const region = getEnvValue(EnvVariable.AWS_REGION); // "us-east-1" or undefined
|
|
56
|
+
* ```
|
|
57
|
+
*
|
|
58
|
+
* @category Environment
|
|
59
|
+
*/
|
|
21
60
|
declare const getEnvValue: (key: EnvVariable) => string | undefined;
|
|
61
|
+
/**
|
|
62
|
+
* Reads an environment variable and **throws** if it's missing (unless `skipCheck` is `true`).
|
|
63
|
+
* Use this for required configuration values.
|
|
64
|
+
*
|
|
65
|
+
* @param key - One of the {@link EnvVariable} enum values.
|
|
66
|
+
* @param skipCheck - If `true`, the function does **not** throw when the value is missing and returns `string | undefined`.
|
|
67
|
+
* Useful for optional vars (e.g. `getEnv(EnvVariable.TURNSTILE_KEY, true)`).
|
|
68
|
+
* @returns The env value. When `skipCheck` is `true`, the type is `string | undefined`; otherwise `string` (throws before returning if missing).
|
|
69
|
+
*
|
|
70
|
+
* @example
|
|
71
|
+
* ```ts
|
|
72
|
+
* import { getEnv, EnvVariable } from "naystack/env";
|
|
73
|
+
*
|
|
74
|
+
* // Required — throws if missing:
|
|
75
|
+
* const signingKey = getEnv(EnvVariable.SIGNING_KEY);
|
|
76
|
+
*
|
|
77
|
+
* // Optional — returns undefined if missing:
|
|
78
|
+
* const turnstile = getEnv(EnvVariable.TURNSTILE_KEY, true);
|
|
79
|
+
* ```
|
|
80
|
+
*
|
|
81
|
+
* @category Environment
|
|
82
|
+
*/
|
|
22
83
|
declare function getEnv<T extends boolean = false>(key: EnvVariable, skipCheck?: T): T extends true ? string | undefined : string;
|
|
23
84
|
|
|
24
85
|
export { EnvVariable, getEnv, getEnvValue };
|