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
package/dist/env.d.ts
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 };
|
package/dist/file/client.d.mts
CHANGED
|
@@ -1,7 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Returns a function that uploads a file to your file upload endpoint with the current auth token.
|
|
3
|
+
* Must be used inside a tree that provides the token (i.e. inside `AuthWrapper`).
|
|
4
|
+
*
|
|
5
|
+
* The endpoint is read from `NEXT_PUBLIC_FILE_ENDPOINT` env var. The file is sent as multipart form data
|
|
6
|
+
* along with a `type` string and optional JSON `data` for metadata.
|
|
7
|
+
*
|
|
8
|
+
* @returns A function `(file, type, data?) => Promise<FileUploadResponseType | null>`.
|
|
9
|
+
* - `file` — `File` or `Blob` to upload.
|
|
10
|
+
* - `type` — String category (e.g. `"avatar"`, `"DealDocument"`); sent as form field `type`.
|
|
11
|
+
* - `data` — Optional JSON-serializable object for metadata; sent as form field `data`.
|
|
12
|
+
* Resolves to the JSON response `{ url, onUploadResponse }` or `null`.
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```tsx
|
|
16
|
+
* import { useFileUpload } from "naystack/file/client";
|
|
17
|
+
*
|
|
18
|
+
* function FileUploader({ dealId }: { dealId: number }) {
|
|
19
|
+
* const uploadFile = useFileUpload();
|
|
20
|
+
* const [uploading, setUploading] = useState(false);
|
|
21
|
+
*
|
|
22
|
+
* const handleUpload = async (file: File) => {
|
|
23
|
+
* setUploading(true);
|
|
24
|
+
* try {
|
|
25
|
+
* const result = await uploadFile(file, "DealDocument", {
|
|
26
|
+
* dealId,
|
|
27
|
+
* fileName: file.name,
|
|
28
|
+
* category: "Contract",
|
|
29
|
+
* });
|
|
30
|
+
* if (result?.url) {
|
|
31
|
+
* console.log("Uploaded:", result.url);
|
|
32
|
+
* router.refresh();
|
|
33
|
+
* }
|
|
34
|
+
* } finally {
|
|
35
|
+
* setUploading(false);
|
|
36
|
+
* }
|
|
37
|
+
* };
|
|
38
|
+
*
|
|
39
|
+
* return <input type="file" onChange={(e) => e.target.files?.[0] && handleUpload(e.target.files[0])} />;
|
|
40
|
+
* }
|
|
41
|
+
* ```
|
|
42
|
+
*
|
|
43
|
+
* @category File
|
|
44
|
+
*/
|
|
1
45
|
declare const useFileUpload: () => (file: File | Blob, type: string, data?: object) => Promise<FileUploadResponseType>;
|
|
46
|
+
/**
|
|
47
|
+
* Shape of the JSON response from the file upload PUT endpoint.
|
|
48
|
+
*
|
|
49
|
+
* @property url - The public S3 URL of the uploaded file.
|
|
50
|
+
* @property onUploadResponse - The return value from the `onUpload` callback in `setupFileUpload`.
|
|
51
|
+
*
|
|
52
|
+
* @category File
|
|
53
|
+
*/
|
|
2
54
|
interface FileUploadResponseType {
|
|
3
55
|
url?: string;
|
|
4
56
|
onUploadResponse?: object;
|
|
5
57
|
}
|
|
6
58
|
|
|
7
|
-
export { useFileUpload };
|
|
59
|
+
export { type FileUploadResponseType, useFileUpload };
|
package/dist/file/client.d.ts
CHANGED
|
@@ -1,7 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Returns a function that uploads a file to your file upload endpoint with the current auth token.
|
|
3
|
+
* Must be used inside a tree that provides the token (i.e. inside `AuthWrapper`).
|
|
4
|
+
*
|
|
5
|
+
* The endpoint is read from `NEXT_PUBLIC_FILE_ENDPOINT` env var. The file is sent as multipart form data
|
|
6
|
+
* along with a `type` string and optional JSON `data` for metadata.
|
|
7
|
+
*
|
|
8
|
+
* @returns A function `(file, type, data?) => Promise<FileUploadResponseType | null>`.
|
|
9
|
+
* - `file` — `File` or `Blob` to upload.
|
|
10
|
+
* - `type` — String category (e.g. `"avatar"`, `"DealDocument"`); sent as form field `type`.
|
|
11
|
+
* - `data` — Optional JSON-serializable object for metadata; sent as form field `data`.
|
|
12
|
+
* Resolves to the JSON response `{ url, onUploadResponse }` or `null`.
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```tsx
|
|
16
|
+
* import { useFileUpload } from "naystack/file/client";
|
|
17
|
+
*
|
|
18
|
+
* function FileUploader({ dealId }: { dealId: number }) {
|
|
19
|
+
* const uploadFile = useFileUpload();
|
|
20
|
+
* const [uploading, setUploading] = useState(false);
|
|
21
|
+
*
|
|
22
|
+
* const handleUpload = async (file: File) => {
|
|
23
|
+
* setUploading(true);
|
|
24
|
+
* try {
|
|
25
|
+
* const result = await uploadFile(file, "DealDocument", {
|
|
26
|
+
* dealId,
|
|
27
|
+
* fileName: file.name,
|
|
28
|
+
* category: "Contract",
|
|
29
|
+
* });
|
|
30
|
+
* if (result?.url) {
|
|
31
|
+
* console.log("Uploaded:", result.url);
|
|
32
|
+
* router.refresh();
|
|
33
|
+
* }
|
|
34
|
+
* } finally {
|
|
35
|
+
* setUploading(false);
|
|
36
|
+
* }
|
|
37
|
+
* };
|
|
38
|
+
*
|
|
39
|
+
* return <input type="file" onChange={(e) => e.target.files?.[0] && handleUpload(e.target.files[0])} />;
|
|
40
|
+
* }
|
|
41
|
+
* ```
|
|
42
|
+
*
|
|
43
|
+
* @category File
|
|
44
|
+
*/
|
|
1
45
|
declare const useFileUpload: () => (file: File | Blob, type: string, data?: object) => Promise<FileUploadResponseType>;
|
|
46
|
+
/**
|
|
47
|
+
* Shape of the JSON response from the file upload PUT endpoint.
|
|
48
|
+
*
|
|
49
|
+
* @property url - The public S3 URL of the uploaded file.
|
|
50
|
+
* @property onUploadResponse - The return value from the `onUpload` callback in `setupFileUpload`.
|
|
51
|
+
*
|
|
52
|
+
* @category File
|
|
53
|
+
*/
|
|
2
54
|
interface FileUploadResponseType {
|
|
3
55
|
url?: string;
|
|
4
56
|
onUploadResponse?: object;
|
|
5
57
|
}
|
|
6
58
|
|
|
7
|
-
export { useFileUpload };
|
|
59
|
+
export { type FileUploadResponseType, useFileUpload };
|
package/dist/file/index.cjs.js
CHANGED
package/dist/file/index.esm.js
CHANGED
package/dist/file/put.cjs.js
CHANGED
package/dist/file/put.d.mts
CHANGED
|
@@ -2,6 +2,17 @@ import { S3Client } from '@aws-sdk/client-s3';
|
|
|
2
2
|
import { NextRequest, NextResponse } from 'next/server';
|
|
3
3
|
import { SetupFileUploadOptions } from './setup.mjs';
|
|
4
4
|
|
|
5
|
+
/**
|
|
6
|
+
* Returns the PUT route handler for file upload.
|
|
7
|
+
*
|
|
8
|
+
* Requires authentication (Bearer token, not refresh cookie).
|
|
9
|
+
* Expects multipart form data with fields: `file` (File), `type` (string), and optional `data` (JSON string).
|
|
10
|
+
*
|
|
11
|
+
* @param options - `SetupFileUploadOptions` (getKey, onUpload).
|
|
12
|
+
* @param client - S3 client instance.
|
|
13
|
+
* @returns Async Next.js route handler for PUT requests.
|
|
14
|
+
* @category File
|
|
15
|
+
*/
|
|
5
16
|
declare const getFileUploadPutRoute: (options: SetupFileUploadOptions, client: S3Client) => (req: NextRequest) => Promise<NextResponse<{
|
|
6
17
|
error: string;
|
|
7
18
|
}> | NextResponse<{
|
package/dist/file/put.d.ts
CHANGED
|
@@ -2,6 +2,17 @@ import { S3Client } from '@aws-sdk/client-s3';
|
|
|
2
2
|
import { NextRequest, NextResponse } from 'next/server';
|
|
3
3
|
import { SetupFileUploadOptions } from './setup.js';
|
|
4
4
|
|
|
5
|
+
/**
|
|
6
|
+
* Returns the PUT route handler for file upload.
|
|
7
|
+
*
|
|
8
|
+
* Requires authentication (Bearer token, not refresh cookie).
|
|
9
|
+
* Expects multipart form data with fields: `file` (File), `type` (string), and optional `data` (JSON string).
|
|
10
|
+
*
|
|
11
|
+
* @param options - `SetupFileUploadOptions` (getKey, onUpload).
|
|
12
|
+
* @param client - S3 client instance.
|
|
13
|
+
* @returns Async Next.js route handler for PUT requests.
|
|
14
|
+
* @category File
|
|
15
|
+
*/
|
|
5
16
|
declare const getFileUploadPutRoute: (options: SetupFileUploadOptions, client: S3Client) => (req: NextRequest) => Promise<NextResponse<{
|
|
6
17
|
error: string;
|
|
7
18
|
}> | NextResponse<{
|
package/dist/file/put.esm.js
CHANGED
package/dist/file/setup.cjs.js
CHANGED
package/dist/file/setup.d.mts
CHANGED
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
import * as next_server from 'next/server';
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* Options for setting up file upload via {@link setupFileUpload}.
|
|
5
|
+
*
|
|
6
|
+
* @property getKey - Optional. Given `{ type, userId, data }`, returns the S3 object key for the upload. If omitted, a UUID is generated.
|
|
7
|
+
* @property onUpload - **Required.** Called after each successful upload with `{ url, type, userId, data }`.
|
|
8
|
+
* The return value is included in the API response as `onUploadResponse` (e.g. save metadata to your database and return it).
|
|
9
|
+
*
|
|
10
|
+
* @category File
|
|
11
|
+
*/
|
|
3
12
|
interface SetupFileUploadOptions {
|
|
4
13
|
getKey?: (data: {
|
|
5
14
|
type: string;
|
|
@@ -13,6 +22,45 @@ interface SetupFileUploadOptions {
|
|
|
13
22
|
data: object;
|
|
14
23
|
}) => Promise<object>;
|
|
15
24
|
}
|
|
25
|
+
/**
|
|
26
|
+
* Configures file upload for S3. Returns a `PUT` route handler (for the client to upload files) and server-side helpers.
|
|
27
|
+
*
|
|
28
|
+
* Mount the `PUT` handler on your file upload API route (e.g. `app/api/(rest)/file/route.ts`).
|
|
29
|
+
* The client can then use `useFileUpload()` from `naystack/file/client` to upload files with the auth token.
|
|
30
|
+
*
|
|
31
|
+
* AWS credentials are read from env vars: `AWS_ACCESS_KEY_ID`, `AWS_ACCESS_KEY_SECRET`, `AWS_REGION`, `AWS_BUCKET`.
|
|
32
|
+
*
|
|
33
|
+
* @param options - Configuration. See {@link SetupFileUploadOptions}.
|
|
34
|
+
* @returns Object with:
|
|
35
|
+
* - `PUT` — Next.js route handler for file uploads (auth required, multipart form).
|
|
36
|
+
* - `uploadFile(keys, { url?, blob? })` — Server-side: upload a file from URL or Blob to S3.
|
|
37
|
+
* - `deleteFile(url)` — Server-side: delete a file by its S3 URL.
|
|
38
|
+
* - `getUploadURL(keys)` — Server-side: get a presigned PUT URL (5-minute expiry).
|
|
39
|
+
* - `getDownloadURL(keys)` — Get the public download URL for a key.
|
|
40
|
+
*
|
|
41
|
+
* @example
|
|
42
|
+
* ```ts
|
|
43
|
+
* // app/api/(rest)/file/route.ts
|
|
44
|
+
* import { setupFileUpload } from "naystack/file";
|
|
45
|
+
*
|
|
46
|
+
* export const { PUT } = setupFileUpload({
|
|
47
|
+
* onUpload: async ({ url, type, userId, data }) => {
|
|
48
|
+
* if (type === "DealDocument" && url) {
|
|
49
|
+
* const payload = data as { dealId: number; fileName: string };
|
|
50
|
+
* const [row] = await db.insert(DocumentsTable).values({
|
|
51
|
+
* dealId: payload.dealId, fileURL: url, fileName: payload.fileName,
|
|
52
|
+
* }).returning();
|
|
53
|
+
* return row ?? {};
|
|
54
|
+
* }
|
|
55
|
+
* return {};
|
|
56
|
+
* },
|
|
57
|
+
* // Optional: customize the S3 key (defaults to UUID)
|
|
58
|
+
* getKey: async ({ type, userId }) => `${type}/${userId}/${crypto.randomUUID()}`,
|
|
59
|
+
* });
|
|
60
|
+
* ```
|
|
61
|
+
*
|
|
62
|
+
* @category File
|
|
63
|
+
*/
|
|
16
64
|
declare function setupFileUpload(options: SetupFileUploadOptions): {
|
|
17
65
|
PUT: (req: next_server.NextRequest) => Promise<next_server.NextResponse<{
|
|
18
66
|
error: string;
|
package/dist/file/setup.d.ts
CHANGED
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
import * as next_server from 'next/server';
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* Options for setting up file upload via {@link setupFileUpload}.
|
|
5
|
+
*
|
|
6
|
+
* @property getKey - Optional. Given `{ type, userId, data }`, returns the S3 object key for the upload. If omitted, a UUID is generated.
|
|
7
|
+
* @property onUpload - **Required.** Called after each successful upload with `{ url, type, userId, data }`.
|
|
8
|
+
* The return value is included in the API response as `onUploadResponse` (e.g. save metadata to your database and return it).
|
|
9
|
+
*
|
|
10
|
+
* @category File
|
|
11
|
+
*/
|
|
3
12
|
interface SetupFileUploadOptions {
|
|
4
13
|
getKey?: (data: {
|
|
5
14
|
type: string;
|
|
@@ -13,6 +22,45 @@ interface SetupFileUploadOptions {
|
|
|
13
22
|
data: object;
|
|
14
23
|
}) => Promise<object>;
|
|
15
24
|
}
|
|
25
|
+
/**
|
|
26
|
+
* Configures file upload for S3. Returns a `PUT` route handler (for the client to upload files) and server-side helpers.
|
|
27
|
+
*
|
|
28
|
+
* Mount the `PUT` handler on your file upload API route (e.g. `app/api/(rest)/file/route.ts`).
|
|
29
|
+
* The client can then use `useFileUpload()` from `naystack/file/client` to upload files with the auth token.
|
|
30
|
+
*
|
|
31
|
+
* AWS credentials are read from env vars: `AWS_ACCESS_KEY_ID`, `AWS_ACCESS_KEY_SECRET`, `AWS_REGION`, `AWS_BUCKET`.
|
|
32
|
+
*
|
|
33
|
+
* @param options - Configuration. See {@link SetupFileUploadOptions}.
|
|
34
|
+
* @returns Object with:
|
|
35
|
+
* - `PUT` — Next.js route handler for file uploads (auth required, multipart form).
|
|
36
|
+
* - `uploadFile(keys, { url?, blob? })` — Server-side: upload a file from URL or Blob to S3.
|
|
37
|
+
* - `deleteFile(url)` — Server-side: delete a file by its S3 URL.
|
|
38
|
+
* - `getUploadURL(keys)` — Server-side: get a presigned PUT URL (5-minute expiry).
|
|
39
|
+
* - `getDownloadURL(keys)` — Get the public download URL for a key.
|
|
40
|
+
*
|
|
41
|
+
* @example
|
|
42
|
+
* ```ts
|
|
43
|
+
* // app/api/(rest)/file/route.ts
|
|
44
|
+
* import { setupFileUpload } from "naystack/file";
|
|
45
|
+
*
|
|
46
|
+
* export const { PUT } = setupFileUpload({
|
|
47
|
+
* onUpload: async ({ url, type, userId, data }) => {
|
|
48
|
+
* if (type === "DealDocument" && url) {
|
|
49
|
+
* const payload = data as { dealId: number; fileName: string };
|
|
50
|
+
* const [row] = await db.insert(DocumentsTable).values({
|
|
51
|
+
* dealId: payload.dealId, fileURL: url, fileName: payload.fileName,
|
|
52
|
+
* }).returning();
|
|
53
|
+
* return row ?? {};
|
|
54
|
+
* }
|
|
55
|
+
* return {};
|
|
56
|
+
* },
|
|
57
|
+
* // Optional: customize the S3 key (defaults to UUID)
|
|
58
|
+
* getKey: async ({ type, userId }) => `${type}/${userId}/${crypto.randomUUID()}`,
|
|
59
|
+
* });
|
|
60
|
+
* ```
|
|
61
|
+
*
|
|
62
|
+
* @category File
|
|
63
|
+
*/
|
|
16
64
|
declare function setupFileUpload(options: SetupFileUploadOptions): {
|
|
17
65
|
PUT: (req: next_server.NextRequest) => Promise<next_server.NextResponse<{
|
|
18
66
|
error: string;
|
package/dist/file/setup.esm.js
CHANGED
package/dist/file/utils.d.mts
CHANGED
|
@@ -1,14 +1,55 @@
|
|
|
1
1
|
import * as _aws_sdk_client_s3 from '@aws-sdk/client-s3';
|
|
2
2
|
import { S3Client } from '@aws-sdk/client-s3';
|
|
3
3
|
|
|
4
|
+
/**
|
|
5
|
+
* Creates an S3 client using env credentials (`AWS_ACCESS_KEY_ID`, `AWS_ACCESS_KEY_SECRET`, `AWS_REGION`).
|
|
6
|
+
* @returns Configured `S3Client` instance.
|
|
7
|
+
* @category File
|
|
8
|
+
*/
|
|
4
9
|
declare const getS3Client: () => S3Client;
|
|
10
|
+
/**
|
|
11
|
+
* Returns a function that generates a presigned PUT URL for uploading to the given S3 key(s).
|
|
12
|
+
* The presigned URL expires after 5 minutes.
|
|
13
|
+
*
|
|
14
|
+
* @param client - S3 client instance.
|
|
15
|
+
* @returns `(keys: string | string[]) => Promise<string>` — the presigned upload URL.
|
|
16
|
+
* @category File
|
|
17
|
+
*/
|
|
5
18
|
declare const getUploadURL: (client: S3Client) => (keys: string | string[]) => Promise<string>;
|
|
19
|
+
/**
|
|
20
|
+
* Builds the public download URL for one or more keys in the configured S3 bucket.
|
|
21
|
+
*
|
|
22
|
+
* @param keys - S3 key or key path segments (array joined by `/`).
|
|
23
|
+
* @returns Full HTTPS URL for the object.
|
|
24
|
+
* @category File
|
|
25
|
+
*/
|
|
6
26
|
declare const getDownloadURL: (keys: string | string[]) => string;
|
|
27
|
+
/**
|
|
28
|
+
* Returns a function that uploads a file (by URL or Blob) to the given S3 key(s).
|
|
29
|
+
*
|
|
30
|
+
* @param client - S3 client instance.
|
|
31
|
+
* @returns `(keys, { url?, blob? }) => Promise<string | null>` — the download URL on success, or `null` if no input.
|
|
32
|
+
* @category File
|
|
33
|
+
*/
|
|
7
34
|
declare const uploadFile: (client: S3Client) => (keys: string | string[], { url, blob, }: {
|
|
8
35
|
blob?: Blob;
|
|
9
36
|
url?: string;
|
|
10
37
|
}) => Promise<string | null>;
|
|
38
|
+
/**
|
|
39
|
+
* Returns a function that deletes an S3 object by its full URL.
|
|
40
|
+
*
|
|
41
|
+
* @param client - S3 client instance.
|
|
42
|
+
* @returns `(url: string) => Promise<boolean>` — `true` if deleted successfully, `false` otherwise.
|
|
43
|
+
* @category File
|
|
44
|
+
*/
|
|
11
45
|
declare const deleteFile: (client: S3Client) => (url: string) => Promise<boolean>;
|
|
46
|
+
/**
|
|
47
|
+
* Returns a function that uploads a Blob/File to S3 at the given key.
|
|
48
|
+
*
|
|
49
|
+
* @param client - S3 client instance.
|
|
50
|
+
* @returns `(file: File | Blob, key: string) => Promise<PutObjectCommandOutput>`.
|
|
51
|
+
* @category File
|
|
52
|
+
*/
|
|
12
53
|
declare const uploadBlob: (client: S3Client) => (file: File | Blob, key: string) => Promise<_aws_sdk_client_s3.PutObjectCommandOutput>;
|
|
13
54
|
|
|
14
55
|
export { deleteFile, getDownloadURL, getS3Client, getUploadURL, uploadBlob, uploadFile };
|
package/dist/file/utils.d.ts
CHANGED
|
@@ -1,14 +1,55 @@
|
|
|
1
1
|
import * as _aws_sdk_client_s3 from '@aws-sdk/client-s3';
|
|
2
2
|
import { S3Client } from '@aws-sdk/client-s3';
|
|
3
3
|
|
|
4
|
+
/**
|
|
5
|
+
* Creates an S3 client using env credentials (`AWS_ACCESS_KEY_ID`, `AWS_ACCESS_KEY_SECRET`, `AWS_REGION`).
|
|
6
|
+
* @returns Configured `S3Client` instance.
|
|
7
|
+
* @category File
|
|
8
|
+
*/
|
|
4
9
|
declare const getS3Client: () => S3Client;
|
|
10
|
+
/**
|
|
11
|
+
* Returns a function that generates a presigned PUT URL for uploading to the given S3 key(s).
|
|
12
|
+
* The presigned URL expires after 5 minutes.
|
|
13
|
+
*
|
|
14
|
+
* @param client - S3 client instance.
|
|
15
|
+
* @returns `(keys: string | string[]) => Promise<string>` — the presigned upload URL.
|
|
16
|
+
* @category File
|
|
17
|
+
*/
|
|
5
18
|
declare const getUploadURL: (client: S3Client) => (keys: string | string[]) => Promise<string>;
|
|
19
|
+
/**
|
|
20
|
+
* Builds the public download URL for one or more keys in the configured S3 bucket.
|
|
21
|
+
*
|
|
22
|
+
* @param keys - S3 key or key path segments (array joined by `/`).
|
|
23
|
+
* @returns Full HTTPS URL for the object.
|
|
24
|
+
* @category File
|
|
25
|
+
*/
|
|
6
26
|
declare const getDownloadURL: (keys: string | string[]) => string;
|
|
27
|
+
/**
|
|
28
|
+
* Returns a function that uploads a file (by URL or Blob) to the given S3 key(s).
|
|
29
|
+
*
|
|
30
|
+
* @param client - S3 client instance.
|
|
31
|
+
* @returns `(keys, { url?, blob? }) => Promise<string | null>` — the download URL on success, or `null` if no input.
|
|
32
|
+
* @category File
|
|
33
|
+
*/
|
|
7
34
|
declare const uploadFile: (client: S3Client) => (keys: string | string[], { url, blob, }: {
|
|
8
35
|
blob?: Blob;
|
|
9
36
|
url?: string;
|
|
10
37
|
}) => Promise<string | null>;
|
|
38
|
+
/**
|
|
39
|
+
* Returns a function that deletes an S3 object by its full URL.
|
|
40
|
+
*
|
|
41
|
+
* @param client - S3 client instance.
|
|
42
|
+
* @returns `(url: string) => Promise<boolean>` — `true` if deleted successfully, `false` otherwise.
|
|
43
|
+
* @category File
|
|
44
|
+
*/
|
|
11
45
|
declare const deleteFile: (client: S3Client) => (url: string) => Promise<boolean>;
|
|
46
|
+
/**
|
|
47
|
+
* Returns a function that uploads a Blob/File to S3 at the given key.
|
|
48
|
+
*
|
|
49
|
+
* @param client - S3 client instance.
|
|
50
|
+
* @returns `(file: File | Blob, key: string) => Promise<PutObjectCommandOutput>`.
|
|
51
|
+
* @category File
|
|
52
|
+
*/
|
|
12
53
|
declare const uploadBlob: (client: S3Client) => (file: File | Blob, key: string) => Promise<_aws_sdk_client_s3.PutObjectCommandOutput>;
|
|
13
54
|
|
|
14
55
|
export { deleteFile, getDownloadURL, getS3Client, getUploadURL, uploadBlob, uploadFile };
|
|
@@ -3,16 +3,129 @@ import { InMemoryCacheConfig, OperationVariables, MutationHookOptions } from '@a
|
|
|
3
3
|
import { TypedDocumentNode } from '@graphql-typed-document-node/core';
|
|
4
4
|
import React__default, { PropsWithChildren } from 'react';
|
|
5
5
|
|
|
6
|
+
/**
|
|
7
|
+
* Apollo Client provider for Next.js. Wrap your app (or a subtree) so client components can run GraphQL queries and mutations.
|
|
8
|
+
* The GraphQL endpoint is read from `NEXT_PUBLIC_GRAPHQL_ENDPOINT` env var.
|
|
9
|
+
*
|
|
10
|
+
* Must be placed **inside** `AuthWrapper` (since `useAuthQuery` / `useAuthMutation` depend on the auth token).
|
|
11
|
+
*
|
|
12
|
+
* @param props - Component props.
|
|
13
|
+
* @param props.children - React children (your app or page content).
|
|
14
|
+
* @param props.cacheConfig - Optional `InMemoryCache` config (e.g. `typePolicies`, `addTypename`). Passed to Apollo's `InMemoryCache`.
|
|
15
|
+
* @returns Provider component that supplies Apollo Client to the tree.
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* ```tsx
|
|
19
|
+
* // app/layout.tsx
|
|
20
|
+
* import { AuthWrapper } from "naystack/auth/email/client";
|
|
21
|
+
* import { ApolloWrapper } from "naystack/graphql/client";
|
|
22
|
+
*
|
|
23
|
+
* export default function RootLayout({ children }: { children: React.ReactNode }) {
|
|
24
|
+
* return (
|
|
25
|
+
* <html lang="en">
|
|
26
|
+
* <body>
|
|
27
|
+
* <AuthWrapper>
|
|
28
|
+
* <ApolloWrapper>{children}</ApolloWrapper>
|
|
29
|
+
* </AuthWrapper>
|
|
30
|
+
* </body>
|
|
31
|
+
* </html>
|
|
32
|
+
* );
|
|
33
|
+
* }
|
|
34
|
+
* ```
|
|
35
|
+
*
|
|
36
|
+
* @category GraphQL
|
|
37
|
+
*/
|
|
6
38
|
declare const ApolloWrapper: ({ children, cacheConfig, }: PropsWithChildren<{
|
|
7
39
|
cacheConfig?: InMemoryCacheConfig;
|
|
8
40
|
}>) => React__default.JSX.Element;
|
|
41
|
+
/**
|
|
42
|
+
* Builds the Apollo link context so requests include the user's Bearer token.
|
|
43
|
+
* Used internally by `useAuthQuery` / `useAuthMutation`; you typically don't call this directly.
|
|
44
|
+
*
|
|
45
|
+
* @param token - The JWT access token. If `null`/`undefined`, returns `undefined` (no auth header).
|
|
46
|
+
* @returns Context object with `headers.authorization` and `credentials: 'omit'`, or `undefined` if no token.
|
|
47
|
+
*
|
|
48
|
+
* @category GraphQL
|
|
49
|
+
*/
|
|
9
50
|
declare const tokenContext: (token?: string | null) => {
|
|
10
51
|
headers: {
|
|
11
52
|
authorization: string;
|
|
12
53
|
};
|
|
13
54
|
credentials: string;
|
|
14
55
|
} | undefined;
|
|
56
|
+
/**
|
|
57
|
+
* Hook to run a GraphQL query with the current user's token. The query auto-fires when both the token
|
|
58
|
+
* and variables are available. Returns a refetch function and the Apollo query result.
|
|
59
|
+
*
|
|
60
|
+
* Uses `fetchPolicy: "no-cache"` by default to always get fresh data.
|
|
61
|
+
*
|
|
62
|
+
* @param query - A `TypedDocumentNode` for the query (e.g. from codegen or a `gql` template).
|
|
63
|
+
* @param variables - Optional initial variables. Query fires automatically when this and token are set; change to refetch.
|
|
64
|
+
* @returns Tuple: `[refetch, result]`.
|
|
65
|
+
* - `refetch(input)` — runs the query again with the given input (passed as `variables.input`).
|
|
66
|
+
* - `result` — `{ data, loading, error }` from Apollo.
|
|
67
|
+
*
|
|
68
|
+
* @example Lazy query (no initial variables, manually triggered):
|
|
69
|
+
* ```tsx
|
|
70
|
+
* import { useAuthQuery } from "naystack/graphql/client";
|
|
71
|
+
* import { GET_SUMMARY } from "@/constants/graphql/queries";
|
|
72
|
+
*
|
|
73
|
+
* function SummaryCard({ type }: { type: string }) {
|
|
74
|
+
* const [getSummary, { loading, data }] = useAuthQuery(GET_SUMMARY);
|
|
75
|
+
*
|
|
76
|
+
* const handleFetch = async () => {
|
|
77
|
+
* const result = await getSummary({ type });
|
|
78
|
+
* if (result.data?.getSummary) setSummary(result.data.getSummary);
|
|
79
|
+
* };
|
|
80
|
+
*
|
|
81
|
+
* return <button onClick={handleFetch} disabled={loading}>Get Summary</button>;
|
|
82
|
+
* }
|
|
83
|
+
* ```
|
|
84
|
+
*
|
|
85
|
+
* @example Auto-firing query with variables:
|
|
86
|
+
* ```tsx
|
|
87
|
+
* const [refetch, { data, loading }] = useAuthQuery(GET_ORGANIZATION_DETAILS, { id: orgId });
|
|
88
|
+
* // Query fires automatically when orgId and token are available
|
|
89
|
+
* ```
|
|
90
|
+
*
|
|
91
|
+
* @category GraphQL
|
|
92
|
+
*/
|
|
15
93
|
declare function useAuthQuery<T, V extends OperationVariables>(query: TypedDocumentNode<T, V>, variables?: V): readonly [(input: V["input"]) => Promise<_apollo_client.QueryResult<T, V>>, _apollo_client.QueryResult<T, V>];
|
|
94
|
+
/**
|
|
95
|
+
* Hook to run a GraphQL mutation with the current user's token. Returns a function you call with the mutation input.
|
|
96
|
+
*
|
|
97
|
+
* The input is sent as `variables.input` to the GraphQL endpoint.
|
|
98
|
+
*
|
|
99
|
+
* @param mutation - A `TypedDocumentNode` for the mutation (e.g. from codegen or a `gql` template).
|
|
100
|
+
* @param options - Optional Apollo `MutationHookOptions` (e.g. `onCompleted`, `onError`, `refetchQueries`).
|
|
101
|
+
* @returns Tuple: `[mutate, result]`.
|
|
102
|
+
* - `mutate(input)` — runs the mutation with the given input. Returns a Promise with `{ data }`.
|
|
103
|
+
* - `result` — `{ data, loading, error }` from Apollo.
|
|
104
|
+
*
|
|
105
|
+
* @example
|
|
106
|
+
* ```tsx
|
|
107
|
+
* import { useAuthMutation } from "naystack/graphql/client";
|
|
108
|
+
* import { CREATE_DEAL } from "@/lib/gql/mutations";
|
|
109
|
+
*
|
|
110
|
+
* function CreateDealModal({ propertyId }: { propertyId: number }) {
|
|
111
|
+
* const [createDeal, { loading }] = useAuthMutation(CREATE_DEAL);
|
|
112
|
+
*
|
|
113
|
+
* const onSubmit = async (values: FormFields) => {
|
|
114
|
+
* const response = await createDeal({
|
|
115
|
+
* propertyId,
|
|
116
|
+
* share: Number(values.share),
|
|
117
|
+
* targetProfit: Number(values.targetProfit),
|
|
118
|
+
* });
|
|
119
|
+
* const dealId = response.data?.createDeal;
|
|
120
|
+
* if (dealId) router.push(`/deals/${dealId}`);
|
|
121
|
+
* };
|
|
122
|
+
*
|
|
123
|
+
* return <form onSubmit={handleSubmit(onSubmit)}>...</form>;
|
|
124
|
+
* }
|
|
125
|
+
* ```
|
|
126
|
+
*
|
|
127
|
+
* @category GraphQL
|
|
128
|
+
*/
|
|
16
129
|
declare function useAuthMutation<T, V extends OperationVariables>(mutation: TypedDocumentNode<T, V>, options?: MutationHookOptions<T, V>): readonly [(input: V["input"]) => Promise<_apollo_client.FetchResult<T>>, _apollo_client.MutationResult<T>];
|
|
17
130
|
|
|
18
131
|
export { ApolloWrapper, tokenContext, useAuthMutation, useAuthQuery };
|