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.
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 -14
  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 -12
  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 -12
  29. package/dist/auth/email/utils.d.mts +41 -2
  30. package/dist/auth/email/utils.d.ts +41 -2
  31. package/dist/auth/email/utils.esm.js +0 -11
  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 -16
  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 -14
  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
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 };
@@ -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 };
@@ -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 };
@@ -30,7 +30,6 @@ var import_uuid = require("uuid");
30
30
 
31
31
  // src/auth/email/utils.ts
32
32
  var import_jsonwebtoken2 = require("jsonwebtoken");
33
- var import_headers2 = require("next/headers");
34
33
 
35
34
  // src/auth/email/token.ts
36
35
  var import_bcryptjs = require("bcryptjs");
@@ -4,7 +4,6 @@ import { v4 } from "uuid";
4
4
 
5
5
  // src/auth/email/utils.ts
6
6
  import { verify as verify2 } from "jsonwebtoken";
7
- import { cookies as cookies2 } from "next/headers";
8
7
 
9
8
  // src/auth/email/token.ts
10
9
  import { compare } from "bcryptjs";
@@ -28,7 +28,6 @@ var import_uuid = require("uuid");
28
28
 
29
29
  // src/auth/email/utils.ts
30
30
  var import_jsonwebtoken2 = require("jsonwebtoken");
31
- var import_headers2 = require("next/headers");
32
31
 
33
32
  // src/auth/email/token.ts
34
33
  var import_bcryptjs = require("bcryptjs");
@@ -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<{
@@ -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<{
@@ -4,7 +4,6 @@ import { v4 } from "uuid";
4
4
 
5
5
  // src/auth/email/utils.ts
6
6
  import { verify as verify2 } from "jsonwebtoken";
7
- import { cookies as cookies2 } from "next/headers";
8
7
 
9
8
  // src/auth/email/token.ts
10
9
  import { compare } from "bcryptjs";
@@ -30,7 +30,6 @@ var import_uuid = require("uuid");
30
30
 
31
31
  // src/auth/email/utils.ts
32
32
  var import_jsonwebtoken2 = require("jsonwebtoken");
33
- var import_headers2 = require("next/headers");
34
33
 
35
34
  // src/auth/email/token.ts
36
35
  var import_bcryptjs = require("bcryptjs");
@@ -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;
@@ -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;
@@ -4,7 +4,6 @@ import { v4 } from "uuid";
4
4
 
5
5
  // src/auth/email/utils.ts
6
6
  import { verify as verify2 } from "jsonwebtoken";
7
- import { cookies as cookies2 } from "next/headers";
8
7
 
9
8
  // src/auth/email/token.ts
10
9
  import { compare } from "bcryptjs";
@@ -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 };
@@ -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 };