@djangocfg/nextjs 2.1.10 → 2.1.14

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/package.json CHANGED
@@ -1,13 +1,12 @@
1
1
  {
2
2
  "name": "@djangocfg/nextjs",
3
- "version": "2.1.10",
3
+ "version": "2.1.14",
4
4
  "description": "Next.js server utilities: sitemap, health, OG images, contact forms, navigation, config",
5
5
  "keywords": [
6
6
  "nextjs",
7
7
  "sitemap",
8
8
  "health",
9
9
  "og-image",
10
- "contact",
11
10
  "navigation",
12
11
  "config",
13
12
  "react",
@@ -60,11 +59,6 @@
60
59
  "import": "./src/og-image/components/index.ts",
61
60
  "default": "./src/og-image/components/index.ts"
62
61
  },
63
- "./contact": {
64
- "types": "./src/contact/index.ts",
65
- "import": "./src/contact/index.ts",
66
- "default": "./src/contact/index.ts"
67
- },
68
62
  "./navigation": {
69
63
  "types": "./src/navigation/index.ts",
70
64
  "import": "./src/navigation/index.ts",
@@ -105,13 +99,12 @@
105
99
  "ai-docs": "tsx src/ai/cli.ts"
106
100
  },
107
101
  "peerDependencies": {
108
- "@djangocfg/api": "^2.1.10",
109
102
  "next": "^15.5.7"
110
103
  },
111
104
  "devDependencies": {
112
- "@djangocfg/imgai": "^2.1.10",
113
- "@djangocfg/layouts": "^2.1.10",
114
- "@djangocfg/typescript-config": "^2.1.10",
105
+ "@djangocfg/imgai": "^2.1.14",
106
+ "@djangocfg/layouts": "^2.1.14",
107
+ "@djangocfg/typescript-config": "^2.1.14",
115
108
  "@types/node": "^24.7.2",
116
109
  "@types/react": "19.2.2",
117
110
  "@types/react-dom": "19.2.1",
@@ -35,7 +35,6 @@ export const DEFAULT_TRANSPILE_PACKAGES = [
35
35
  '@djangocfg/ui-core',
36
36
  '@djangocfg/ui-nextjs',
37
37
  '@djangocfg/layouts',
38
- '@djangocfg/nextjs',
39
38
  '@djangocfg/api',
40
39
  '@djangocfg/centrifugo',
41
40
  ] as const;
@@ -115,6 +115,8 @@ export function createBaseNextConfig(
115
115
  NEXT_PUBLIC_BASE_PATH: basePath,
116
116
  NEXT_PUBLIC_API_URL: apiUrl,
117
117
  NEXT_PUBLIC_SITE_URL: siteUrl,
118
+ // Disable Next.js telemetry (Next.js 15+ uses env var instead of config option)
119
+ NEXT_TELEMETRY_DISABLED: '1',
118
120
  ...options.env,
119
121
  },
120
122
 
package/src/index.ts CHANGED
@@ -13,9 +13,6 @@ export * from './health';
13
13
  // OG Image
14
14
  export * from './og-image';
15
15
 
16
- // Contact form
17
- export * from './contact';
18
-
19
16
  // Navigation
20
17
  export * from './navigation';
21
18
 
@@ -1,47 +0,0 @@
1
- import { Schemas } from '@djangocfg/api/server';
2
- export { ContactRouteOptions, POST, createContactRoute } from './route.mjs';
3
- import 'next/server';
4
-
5
- /**
6
- * Contact Form Submission - Server-side function
7
- *
8
- * Server-side function to submit contact form data to backend API.
9
- * Can be used in Next.js API routes to avoid CORS issues.
10
- *
11
- * Uses Fetchers with server-side API instance for type safety and Zod validation.
12
- *
13
- * @example
14
- * ```ts
15
- * import { submitContactForm } from '@djangocfg/nextjs/contact';
16
- *
17
- * const result = await submitContactForm({
18
- * name: 'John Doe',
19
- * email: 'john@example.com',
20
- * message: 'Hello!',
21
- * apiUrl: 'https://api.example.com'
22
- * });
23
- * ```
24
- */
25
-
26
- interface SubmitContactFormOptions {
27
- /** Lead submission data */
28
- data: Schemas.LeadSubmissionRequest;
29
- /** Backend API base URL */
30
- apiUrl: string;
31
- /** Optional site URL (auto-detected from origin if not provided) */
32
- siteUrl?: string;
33
- }
34
- interface SubmitContactFormResult {
35
- success: boolean;
36
- message: string;
37
- lead_id?: number;
38
- }
39
- /**
40
- * Submit contact form data to backend API
41
- *
42
- * Server-side function that uses Fetchers with server-side API instance.
43
- * This provides type safety, Zod validation, and proper error handling.
44
- */
45
- declare function submitContactForm({ data, apiUrl, siteUrl, }: SubmitContactFormOptions): Promise<SubmitContactFormResult>;
46
-
47
- export { type SubmitContactFormOptions, type SubmitContactFormResult, submitContactForm };
@@ -1,98 +0,0 @@
1
- // src/contact/submit.ts
2
- import { API, MemoryStorageAdapter, Fetchers } from "@djangocfg/api/server";
3
- async function submitContactForm({
4
- data,
5
- apiUrl,
6
- siteUrl
7
- }) {
8
- if (!data.name || !data.email || !data.message) {
9
- throw new Error("Missing required fields: name, email, message");
10
- }
11
- if (!apiUrl) {
12
- throw new Error("API URL is required");
13
- }
14
- const serverApi = new API(apiUrl, {
15
- storage: new MemoryStorageAdapter()
16
- });
17
- const submissionData = {
18
- ...data,
19
- site_url: data.site_url || siteUrl
20
- };
21
- try {
22
- const result = await Fetchers.createLeadsSubmitCreate(submissionData, serverApi);
23
- return {
24
- success: result.success ?? true,
25
- message: result.message || "Contact form submitted successfully",
26
- lead_id: result.lead_id
27
- };
28
- } catch (error) {
29
- if (error instanceof Error) {
30
- throw new Error(`Failed to submit contact form: ${error.message}`);
31
- }
32
- throw new Error("An unexpected error occurred while submitting the contact form");
33
- }
34
- }
35
-
36
- // src/contact/route.ts
37
- import { NextResponse } from "next/server";
38
- function createContactRoute(options) {
39
- return async function POST2(request) {
40
- try {
41
- const body = await request.json();
42
- const apiUrl = body._apiUrl && body._apiUrl !== "" ? body._apiUrl : options?.apiUrl || process.env.NEXT_PUBLIC_API_URL || "";
43
- if (!apiUrl) {
44
- return NextResponse.json(
45
- {
46
- success: false,
47
- message: "API URL not configured. Set NEXT_PUBLIC_API_URL, provide apiUrl option, or pass _apiUrl in request body."
48
- },
49
- { status: 500 }
50
- );
51
- }
52
- const { _apiUrl, ...submissionData } = body;
53
- const response = await submitContactForm({
54
- data: submissionData,
55
- apiUrl,
56
- siteUrl: request.headers.get("origin") || void 0
57
- });
58
- return NextResponse.json(response);
59
- } catch (error) {
60
- console.error("Contact form submission error:", error);
61
- if (error instanceof Error && error.message.includes("Missing required fields")) {
62
- return NextResponse.json(
63
- {
64
- success: false,
65
- message: error.message
66
- },
67
- { status: 400 }
68
- );
69
- }
70
- if (error instanceof Error) {
71
- return NextResponse.json(
72
- {
73
- success: false,
74
- message: error.message || "Failed to submit contact form"
75
- },
76
- { status: 500 }
77
- );
78
- }
79
- return NextResponse.json(
80
- {
81
- success: false,
82
- message: "An unexpected error occurred"
83
- },
84
- { status: 500 }
85
- );
86
- }
87
- };
88
- }
89
- async function POST(request) {
90
- const handler = createContactRoute();
91
- return handler(request);
92
- }
93
- export {
94
- POST,
95
- createContactRoute,
96
- submitContactForm
97
- };
98
- //# sourceMappingURL=index.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/contact/submit.ts","../../src/contact/route.ts"],"sourcesContent":["/**\n * Contact Form Submission - Server-side function\n * \n * Server-side function to submit contact form data to backend API.\n * Can be used in Next.js API routes to avoid CORS issues.\n * \n * Uses Fetchers with server-side API instance for type safety and Zod validation.\n * \n * @example\n * ```ts\n * import { submitContactForm } from '@djangocfg/nextjs/contact';\n * \n * const result = await submitContactForm({\n * name: 'John Doe',\n * email: 'john@example.com',\n * message: 'Hello!',\n * apiUrl: 'https://api.example.com'\n * });\n * ```\n */\n\n// Use server-only exports to avoid loading React hooks (useSWRConfig)\nimport { API, MemoryStorageAdapter, Fetchers } from '@djangocfg/api/server';\nimport type { Schemas } from '@djangocfg/api/server';\n\nexport interface SubmitContactFormOptions {\n /** Lead submission data */\n data: Schemas.LeadSubmissionRequest;\n /** Backend API base URL */\n apiUrl: string;\n /** Optional site URL (auto-detected from origin if not provided) */\n siteUrl?: string;\n}\n\nexport interface SubmitContactFormResult {\n success: boolean;\n message: string;\n lead_id?: number;\n}\n\n/**\n * Submit contact form data to backend API\n * \n * Server-side function that uses Fetchers with server-side API instance.\n * This provides type safety, Zod validation, and proper error handling.\n */\nexport async function submitContactForm({\n data,\n apiUrl,\n siteUrl,\n}: SubmitContactFormOptions): Promise<SubmitContactFormResult> {\n // Validate required fields\n if (!data.name || !data.email || !data.message) {\n throw new Error('Missing required fields: name, email, message');\n }\n\n if (!apiUrl) {\n throw new Error('API URL is required');\n }\n\n // Create server-side API instance with MemoryStorageAdapter\n // This works on server-side and doesn't require browser APIs\n const serverApi = new API(apiUrl, {\n storage: new MemoryStorageAdapter(),\n });\n\n // Prepare submission data with site_url\n const submissionData: Schemas.LeadSubmissionRequest = {\n ...data,\n site_url: data.site_url || siteUrl,\n };\n\n try {\n // Use typed fetcher with server API instance\n // This provides type safety and runtime validation via Zod\n // Using Fetchers namespace to avoid loading hooks\n const result = await Fetchers.createLeadsSubmitCreate(submissionData, serverApi);\n\n // Return formatted result\n return {\n success: result.success ?? true,\n message: result.message || 'Contact form submitted successfully',\n lead_id: result.lead_id,\n };\n } catch (error) {\n // Handle API errors (including validation errors from Zod)\n if (error instanceof Error) {\n throw new Error(`Failed to submit contact form: ${error.message}`);\n }\n throw new Error('An unexpected error occurred while submitting the contact form');\n }\n}\n\n","/**\n * Contact Form API Route Handler\n * \n * Ready-to-use Next.js API route handler for contact form submissions.\n * Proxies requests to backend API to avoid CORS issues.\n * \n * @example\n * ```ts\n * // In app/api/contact/route.ts\n * export { POST } from '@djangocfg/nextjs/contact/route';\n * ```\n */\n\nimport { NextRequest, NextResponse } from 'next/server';\nimport { submitContactForm } from './submit';\nimport type { Schemas } from '@djangocfg/api';\n\nexport interface ContactRouteOptions {\n /** Backend API base URL (defaults to process.env.NEXT_PUBLIC_API_URL) */\n apiUrl?: string;\n}\n\n/**\n * Create contact form route handler with custom options\n */\nexport function createContactRoute(options?: ContactRouteOptions) {\n return async function POST(request: NextRequest) {\n try {\n // Parse request body\n const body: any = await request.json();\n\n // Extract apiUrl from request body (passed from ContactFormProvider)\n // or use from options/environment as fallback\n const apiUrl = (body._apiUrl && body._apiUrl !== '') \n ? body._apiUrl \n : (options?.apiUrl || process.env.NEXT_PUBLIC_API_URL || '');\n \n if (!apiUrl) {\n return NextResponse.json(\n {\n success: false,\n message: 'API URL not configured. Set NEXT_PUBLIC_API_URL, provide apiUrl option, or pass _apiUrl in request body.',\n },\n { status: 500 }\n );\n }\n\n // Remove _apiUrl from body before submitting\n const { _apiUrl, ...submissionData } = body;\n\n // Submit using smart wrapper from @djangocfg/nextjs\n const response = await submitContactForm({\n data: submissionData as Schemas.LeadSubmissionRequest,\n apiUrl,\n siteUrl: request.headers.get('origin') || undefined,\n });\n\n return NextResponse.json(response);\n } catch (error) {\n console.error('Contact form submission error:', error);\n\n // Handle validation errors (400)\n if (error instanceof Error && error.message.includes('Missing required fields')) {\n return NextResponse.json(\n {\n success: false,\n message: error.message,\n },\n { status: 400 }\n );\n }\n\n // Handle API errors\n if (error instanceof Error) {\n return NextResponse.json(\n {\n success: false,\n message: error.message || 'Failed to submit contact form',\n },\n { status: 500 }\n );\n }\n\n return NextResponse.json(\n {\n success: false,\n message: 'An unexpected error occurred',\n },\n { status: 500 }\n );\n }\n };\n}\n\n/**\n * Default POST handler (uses process.env.NEXT_PUBLIC_API_URL)\n */\nexport async function POST(request: NextRequest) {\n const handler = createContactRoute();\n return handler(request);\n}\n\n"],"mappings":";AAsBA,SAAS,KAAK,sBAAsB,gBAAgB;AAwBpD,eAAsB,kBAAkB;AAAA,EACtC;AAAA,EACA;AAAA,EACA;AACF,GAA+D;AAE7D,MAAI,CAAC,KAAK,QAAQ,CAAC,KAAK,SAAS,CAAC,KAAK,SAAS;AAC9C,UAAM,IAAI,MAAM,+CAA+C;AAAA,EACjE;AAEA,MAAI,CAAC,QAAQ;AACX,UAAM,IAAI,MAAM,qBAAqB;AAAA,EACvC;AAIA,QAAM,YAAY,IAAI,IAAI,QAAQ;AAAA,IAChC,SAAS,IAAI,qBAAqB;AAAA,EACpC,CAAC;AAGD,QAAM,iBAAgD;AAAA,IACpD,GAAG;AAAA,IACH,UAAU,KAAK,YAAY;AAAA,EAC7B;AAEA,MAAI;AAIF,UAAM,SAAS,MAAM,SAAS,wBAAwB,gBAAgB,SAAS;AAG/E,WAAO;AAAA,MACL,SAAS,OAAO,WAAW;AAAA,MAC3B,SAAS,OAAO,WAAW;AAAA,MAC3B,SAAS,OAAO;AAAA,IAClB;AAAA,EACF,SAAS,OAAO;AAEd,QAAI,iBAAiB,OAAO;AAC1B,YAAM,IAAI,MAAM,kCAAkC,MAAM,OAAO,EAAE;AAAA,IACnE;AACA,UAAM,IAAI,MAAM,gEAAgE;AAAA,EAClF;AACF;;;AC9EA,SAAsB,oBAAoB;AAYnC,SAAS,mBAAmB,SAA+B;AAChE,SAAO,eAAeA,MAAK,SAAsB;AAC/C,QAAI;AAEF,YAAM,OAAY,MAAM,QAAQ,KAAK;AAIrC,YAAM,SAAU,KAAK,WAAW,KAAK,YAAY,KAC7C,KAAK,UACJ,SAAS,UAAU,QAAQ,IAAI,uBAAuB;AAE3D,UAAI,CAAC,QAAQ;AACX,eAAO,aAAa;AAAA,UAClB;AAAA,YACE,SAAS;AAAA,YACT,SAAS;AAAA,UACX;AAAA,UACA,EAAE,QAAQ,IAAI;AAAA,QAChB;AAAA,MACF;AAGA,YAAM,EAAE,SAAS,GAAG,eAAe,IAAI;AAGvC,YAAM,WAAW,MAAM,kBAAkB;AAAA,QACvC,MAAM;AAAA,QACN;AAAA,QACA,SAAS,QAAQ,QAAQ,IAAI,QAAQ,KAAK;AAAA,MAC5C,CAAC;AAED,aAAO,aAAa,KAAK,QAAQ;AAAA,IACnC,SAAS,OAAO;AACd,cAAQ,MAAM,kCAAkC,KAAK;AAGrD,UAAI,iBAAiB,SAAS,MAAM,QAAQ,SAAS,yBAAyB,GAAG;AAC/E,eAAO,aAAa;AAAA,UAClB;AAAA,YACE,SAAS;AAAA,YACT,SAAS,MAAM;AAAA,UACjB;AAAA,UACA,EAAE,QAAQ,IAAI;AAAA,QAChB;AAAA,MACF;AAGA,UAAI,iBAAiB,OAAO;AAC1B,eAAO,aAAa;AAAA,UAClB;AAAA,YACE,SAAS;AAAA,YACT,SAAS,MAAM,WAAW;AAAA,UAC5B;AAAA,UACA,EAAE,QAAQ,IAAI;AAAA,QAChB;AAAA,MACF;AAEA,aAAO,aAAa;AAAA,QAClB;AAAA,UACE,SAAS;AAAA,UACT,SAAS;AAAA,QACX;AAAA,QACA,EAAE,QAAQ,IAAI;AAAA,MAChB;AAAA,IACF;AAAA,EACF;AACF;AAKA,eAAsB,KAAK,SAAsB;AAC/C,QAAM,UAAU,mBAAmB;AACnC,SAAO,QAAQ,OAAO;AACxB;","names":["POST"]}
@@ -1,35 +0,0 @@
1
- import { NextRequest, NextResponse } from 'next/server';
2
-
3
- /**
4
- * Contact Form API Route Handler
5
- *
6
- * Ready-to-use Next.js API route handler for contact form submissions.
7
- * Proxies requests to backend API to avoid CORS issues.
8
- *
9
- * @example
10
- * ```ts
11
- * // In app/api/contact/route.ts
12
- * export { POST } from '@djangocfg/nextjs/contact/route';
13
- * ```
14
- */
15
-
16
- interface ContactRouteOptions {
17
- /** Backend API base URL (defaults to process.env.NEXT_PUBLIC_API_URL) */
18
- apiUrl?: string;
19
- }
20
- /**
21
- * Create contact form route handler with custom options
22
- */
23
- declare function createContactRoute(options?: ContactRouteOptions): (request: NextRequest) => Promise<NextResponse<{
24
- success: boolean;
25
- message: string;
26
- }>>;
27
- /**
28
- * Default POST handler (uses process.env.NEXT_PUBLIC_API_URL)
29
- */
30
- declare function POST(request: NextRequest): Promise<NextResponse<{
31
- success: boolean;
32
- message: string;
33
- }>>;
34
-
35
- export { type ContactRouteOptions, POST, createContactRoute };
@@ -1,99 +0,0 @@
1
- // src/contact/route.ts
2
- import { NextResponse } from "next/server";
3
-
4
- // src/contact/submit.ts
5
- import { API, MemoryStorageAdapter, Fetchers } from "@djangocfg/api/server";
6
- async function submitContactForm({
7
- data,
8
- apiUrl,
9
- siteUrl
10
- }) {
11
- if (!data.name || !data.email || !data.message) {
12
- throw new Error("Missing required fields: name, email, message");
13
- }
14
- if (!apiUrl) {
15
- throw new Error("API URL is required");
16
- }
17
- const serverApi = new API(apiUrl, {
18
- storage: new MemoryStorageAdapter()
19
- });
20
- const submissionData = {
21
- ...data,
22
- site_url: data.site_url || siteUrl
23
- };
24
- try {
25
- const result = await Fetchers.createLeadsSubmitCreate(submissionData, serverApi);
26
- return {
27
- success: result.success ?? true,
28
- message: result.message || "Contact form submitted successfully",
29
- lead_id: result.lead_id
30
- };
31
- } catch (error) {
32
- if (error instanceof Error) {
33
- throw new Error(`Failed to submit contact form: ${error.message}`);
34
- }
35
- throw new Error("An unexpected error occurred while submitting the contact form");
36
- }
37
- }
38
-
39
- // src/contact/route.ts
40
- function createContactRoute(options) {
41
- return async function POST2(request) {
42
- try {
43
- const body = await request.json();
44
- const apiUrl = body._apiUrl && body._apiUrl !== "" ? body._apiUrl : options?.apiUrl || process.env.NEXT_PUBLIC_API_URL || "";
45
- if (!apiUrl) {
46
- return NextResponse.json(
47
- {
48
- success: false,
49
- message: "API URL not configured. Set NEXT_PUBLIC_API_URL, provide apiUrl option, or pass _apiUrl in request body."
50
- },
51
- { status: 500 }
52
- );
53
- }
54
- const { _apiUrl, ...submissionData } = body;
55
- const response = await submitContactForm({
56
- data: submissionData,
57
- apiUrl,
58
- siteUrl: request.headers.get("origin") || void 0
59
- });
60
- return NextResponse.json(response);
61
- } catch (error) {
62
- console.error("Contact form submission error:", error);
63
- if (error instanceof Error && error.message.includes("Missing required fields")) {
64
- return NextResponse.json(
65
- {
66
- success: false,
67
- message: error.message
68
- },
69
- { status: 400 }
70
- );
71
- }
72
- if (error instanceof Error) {
73
- return NextResponse.json(
74
- {
75
- success: false,
76
- message: error.message || "Failed to submit contact form"
77
- },
78
- { status: 500 }
79
- );
80
- }
81
- return NextResponse.json(
82
- {
83
- success: false,
84
- message: "An unexpected error occurred"
85
- },
86
- { status: 500 }
87
- );
88
- }
89
- };
90
- }
91
- async function POST(request) {
92
- const handler = createContactRoute();
93
- return handler(request);
94
- }
95
- export {
96
- POST,
97
- createContactRoute
98
- };
99
- //# sourceMappingURL=route.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/contact/route.ts","../../src/contact/submit.ts"],"sourcesContent":["/**\n * Contact Form API Route Handler\n * \n * Ready-to-use Next.js API route handler for contact form submissions.\n * Proxies requests to backend API to avoid CORS issues.\n * \n * @example\n * ```ts\n * // In app/api/contact/route.ts\n * export { POST } from '@djangocfg/nextjs/contact/route';\n * ```\n */\n\nimport { NextRequest, NextResponse } from 'next/server';\nimport { submitContactForm } from './submit';\nimport type { Schemas } from '@djangocfg/api';\n\nexport interface ContactRouteOptions {\n /** Backend API base URL (defaults to process.env.NEXT_PUBLIC_API_URL) */\n apiUrl?: string;\n}\n\n/**\n * Create contact form route handler with custom options\n */\nexport function createContactRoute(options?: ContactRouteOptions) {\n return async function POST(request: NextRequest) {\n try {\n // Parse request body\n const body: any = await request.json();\n\n // Extract apiUrl from request body (passed from ContactFormProvider)\n // or use from options/environment as fallback\n const apiUrl = (body._apiUrl && body._apiUrl !== '') \n ? body._apiUrl \n : (options?.apiUrl || process.env.NEXT_PUBLIC_API_URL || '');\n \n if (!apiUrl) {\n return NextResponse.json(\n {\n success: false,\n message: 'API URL not configured. Set NEXT_PUBLIC_API_URL, provide apiUrl option, or pass _apiUrl in request body.',\n },\n { status: 500 }\n );\n }\n\n // Remove _apiUrl from body before submitting\n const { _apiUrl, ...submissionData } = body;\n\n // Submit using smart wrapper from @djangocfg/nextjs\n const response = await submitContactForm({\n data: submissionData as Schemas.LeadSubmissionRequest,\n apiUrl,\n siteUrl: request.headers.get('origin') || undefined,\n });\n\n return NextResponse.json(response);\n } catch (error) {\n console.error('Contact form submission error:', error);\n\n // Handle validation errors (400)\n if (error instanceof Error && error.message.includes('Missing required fields')) {\n return NextResponse.json(\n {\n success: false,\n message: error.message,\n },\n { status: 400 }\n );\n }\n\n // Handle API errors\n if (error instanceof Error) {\n return NextResponse.json(\n {\n success: false,\n message: error.message || 'Failed to submit contact form',\n },\n { status: 500 }\n );\n }\n\n return NextResponse.json(\n {\n success: false,\n message: 'An unexpected error occurred',\n },\n { status: 500 }\n );\n }\n };\n}\n\n/**\n * Default POST handler (uses process.env.NEXT_PUBLIC_API_URL)\n */\nexport async function POST(request: NextRequest) {\n const handler = createContactRoute();\n return handler(request);\n}\n\n","/**\n * Contact Form Submission - Server-side function\n * \n * Server-side function to submit contact form data to backend API.\n * Can be used in Next.js API routes to avoid CORS issues.\n * \n * Uses Fetchers with server-side API instance for type safety and Zod validation.\n * \n * @example\n * ```ts\n * import { submitContactForm } from '@djangocfg/nextjs/contact';\n * \n * const result = await submitContactForm({\n * name: 'John Doe',\n * email: 'john@example.com',\n * message: 'Hello!',\n * apiUrl: 'https://api.example.com'\n * });\n * ```\n */\n\n// Use server-only exports to avoid loading React hooks (useSWRConfig)\nimport { API, MemoryStorageAdapter, Fetchers } from '@djangocfg/api/server';\nimport type { Schemas } from '@djangocfg/api/server';\n\nexport interface SubmitContactFormOptions {\n /** Lead submission data */\n data: Schemas.LeadSubmissionRequest;\n /** Backend API base URL */\n apiUrl: string;\n /** Optional site URL (auto-detected from origin if not provided) */\n siteUrl?: string;\n}\n\nexport interface SubmitContactFormResult {\n success: boolean;\n message: string;\n lead_id?: number;\n}\n\n/**\n * Submit contact form data to backend API\n * \n * Server-side function that uses Fetchers with server-side API instance.\n * This provides type safety, Zod validation, and proper error handling.\n */\nexport async function submitContactForm({\n data,\n apiUrl,\n siteUrl,\n}: SubmitContactFormOptions): Promise<SubmitContactFormResult> {\n // Validate required fields\n if (!data.name || !data.email || !data.message) {\n throw new Error('Missing required fields: name, email, message');\n }\n\n if (!apiUrl) {\n throw new Error('API URL is required');\n }\n\n // Create server-side API instance with MemoryStorageAdapter\n // This works on server-side and doesn't require browser APIs\n const serverApi = new API(apiUrl, {\n storage: new MemoryStorageAdapter(),\n });\n\n // Prepare submission data with site_url\n const submissionData: Schemas.LeadSubmissionRequest = {\n ...data,\n site_url: data.site_url || siteUrl,\n };\n\n try {\n // Use typed fetcher with server API instance\n // This provides type safety and runtime validation via Zod\n // Using Fetchers namespace to avoid loading hooks\n const result = await Fetchers.createLeadsSubmitCreate(submissionData, serverApi);\n\n // Return formatted result\n return {\n success: result.success ?? true,\n message: result.message || 'Contact form submitted successfully',\n lead_id: result.lead_id,\n };\n } catch (error) {\n // Handle API errors (including validation errors from Zod)\n if (error instanceof Error) {\n throw new Error(`Failed to submit contact form: ${error.message}`);\n }\n throw new Error('An unexpected error occurred while submitting the contact form');\n }\n}\n\n"],"mappings":";AAaA,SAAsB,oBAAoB;;;ACS1C,SAAS,KAAK,sBAAsB,gBAAgB;AAwBpD,eAAsB,kBAAkB;AAAA,EACtC;AAAA,EACA;AAAA,EACA;AACF,GAA+D;AAE7D,MAAI,CAAC,KAAK,QAAQ,CAAC,KAAK,SAAS,CAAC,KAAK,SAAS;AAC9C,UAAM,IAAI,MAAM,+CAA+C;AAAA,EACjE;AAEA,MAAI,CAAC,QAAQ;AACX,UAAM,IAAI,MAAM,qBAAqB;AAAA,EACvC;AAIA,QAAM,YAAY,IAAI,IAAI,QAAQ;AAAA,IAChC,SAAS,IAAI,qBAAqB;AAAA,EACpC,CAAC;AAGD,QAAM,iBAAgD;AAAA,IACpD,GAAG;AAAA,IACH,UAAU,KAAK,YAAY;AAAA,EAC7B;AAEA,MAAI;AAIF,UAAM,SAAS,MAAM,SAAS,wBAAwB,gBAAgB,SAAS;AAG/E,WAAO;AAAA,MACL,SAAS,OAAO,WAAW;AAAA,MAC3B,SAAS,OAAO,WAAW;AAAA,MAC3B,SAAS,OAAO;AAAA,IAClB;AAAA,EACF,SAAS,OAAO;AAEd,QAAI,iBAAiB,OAAO;AAC1B,YAAM,IAAI,MAAM,kCAAkC,MAAM,OAAO,EAAE;AAAA,IACnE;AACA,UAAM,IAAI,MAAM,gEAAgE;AAAA,EAClF;AACF;;;ADlEO,SAAS,mBAAmB,SAA+B;AAChE,SAAO,eAAeA,MAAK,SAAsB;AAC/C,QAAI;AAEF,YAAM,OAAY,MAAM,QAAQ,KAAK;AAIrC,YAAM,SAAU,KAAK,WAAW,KAAK,YAAY,KAC7C,KAAK,UACJ,SAAS,UAAU,QAAQ,IAAI,uBAAuB;AAE3D,UAAI,CAAC,QAAQ;AACX,eAAO,aAAa;AAAA,UAClB;AAAA,YACE,SAAS;AAAA,YACT,SAAS;AAAA,UACX;AAAA,UACA,EAAE,QAAQ,IAAI;AAAA,QAChB;AAAA,MACF;AAGA,YAAM,EAAE,SAAS,GAAG,eAAe,IAAI;AAGvC,YAAM,WAAW,MAAM,kBAAkB;AAAA,QACvC,MAAM;AAAA,QACN;AAAA,QACA,SAAS,QAAQ,QAAQ,IAAI,QAAQ,KAAK;AAAA,MAC5C,CAAC;AAED,aAAO,aAAa,KAAK,QAAQ;AAAA,IACnC,SAAS,OAAO;AACd,cAAQ,MAAM,kCAAkC,KAAK;AAGrD,UAAI,iBAAiB,SAAS,MAAM,QAAQ,SAAS,yBAAyB,GAAG;AAC/E,eAAO,aAAa;AAAA,UAClB;AAAA,YACE,SAAS;AAAA,YACT,SAAS,MAAM;AAAA,UACjB;AAAA,UACA,EAAE,QAAQ,IAAI;AAAA,QAChB;AAAA,MACF;AAGA,UAAI,iBAAiB,OAAO;AAC1B,eAAO,aAAa;AAAA,UAClB;AAAA,YACE,SAAS;AAAA,YACT,SAAS,MAAM,WAAW;AAAA,UAC5B;AAAA,UACA,EAAE,QAAQ,IAAI;AAAA,QAChB;AAAA,MACF;AAEA,aAAO,aAAa;AAAA,QAClB;AAAA,UACE,SAAS;AAAA,UACT,SAAS;AAAA,QACX;AAAA,QACA,EAAE,QAAQ,IAAI;AAAA,MAChB;AAAA,IACF;AAAA,EACF;AACF;AAKA,eAAsB,KAAK,SAAsB;AAC/C,QAAM,UAAU,mBAAmB;AACnC,SAAO,QAAQ,OAAO;AACxB;","names":["POST"]}
@@ -1,13 +0,0 @@
1
- /**
2
- * Contact Form Utilities
3
- *
4
- * Server-side utilities for contact form submission
5
- */
6
-
7
- export { submitContactForm } from './submit';
8
- export type { SubmitContactFormOptions, SubmitContactFormResult } from './submit';
9
-
10
- // Route handler
11
- export { POST, createContactRoute } from './route';
12
- export type { ContactRouteOptions } from './route';
13
-
@@ -1,102 +0,0 @@
1
- /**
2
- * Contact Form API Route Handler
3
- *
4
- * Ready-to-use Next.js API route handler for contact form submissions.
5
- * Proxies requests to backend API to avoid CORS issues.
6
- *
7
- * @example
8
- * ```ts
9
- * // In app/api/contact/route.ts
10
- * export { POST } from '@djangocfg/nextjs/contact/route';
11
- * ```
12
- */
13
-
14
- import { NextRequest, NextResponse } from 'next/server';
15
- import { submitContactForm } from './submit';
16
- import type { Schemas } from '@djangocfg/api';
17
-
18
- export interface ContactRouteOptions {
19
- /** Backend API base URL (defaults to process.env.NEXT_PUBLIC_API_URL) */
20
- apiUrl?: string;
21
- }
22
-
23
- /**
24
- * Create contact form route handler with custom options
25
- */
26
- export function createContactRoute(options?: ContactRouteOptions) {
27
- return async function POST(request: NextRequest) {
28
- try {
29
- // Parse request body
30
- const body: any = await request.json();
31
-
32
- // Extract apiUrl from request body (passed from ContactFormProvider)
33
- // or use from options/environment as fallback
34
- const apiUrl = (body._apiUrl && body._apiUrl !== '')
35
- ? body._apiUrl
36
- : (options?.apiUrl || process.env.NEXT_PUBLIC_API_URL || '');
37
-
38
- if (!apiUrl) {
39
- return NextResponse.json(
40
- {
41
- success: false,
42
- message: 'API URL not configured. Set NEXT_PUBLIC_API_URL, provide apiUrl option, or pass _apiUrl in request body.',
43
- },
44
- { status: 500 }
45
- );
46
- }
47
-
48
- // Remove _apiUrl from body before submitting
49
- const { _apiUrl, ...submissionData } = body;
50
-
51
- // Submit using smart wrapper from @djangocfg/nextjs
52
- const response = await submitContactForm({
53
- data: submissionData as Schemas.LeadSubmissionRequest,
54
- apiUrl,
55
- siteUrl: request.headers.get('origin') || undefined,
56
- });
57
-
58
- return NextResponse.json(response);
59
- } catch (error) {
60
- console.error('Contact form submission error:', error);
61
-
62
- // Handle validation errors (400)
63
- if (error instanceof Error && error.message.includes('Missing required fields')) {
64
- return NextResponse.json(
65
- {
66
- success: false,
67
- message: error.message,
68
- },
69
- { status: 400 }
70
- );
71
- }
72
-
73
- // Handle API errors
74
- if (error instanceof Error) {
75
- return NextResponse.json(
76
- {
77
- success: false,
78
- message: error.message || 'Failed to submit contact form',
79
- },
80
- { status: 500 }
81
- );
82
- }
83
-
84
- return NextResponse.json(
85
- {
86
- success: false,
87
- message: 'An unexpected error occurred',
88
- },
89
- { status: 500 }
90
- );
91
- }
92
- };
93
- }
94
-
95
- /**
96
- * Default POST handler (uses process.env.NEXT_PUBLIC_API_URL)
97
- */
98
- export async function POST(request: NextRequest) {
99
- const handler = createContactRoute();
100
- return handler(request);
101
- }
102
-
@@ -1,93 +0,0 @@
1
- /**
2
- * Contact Form Submission - Server-side function
3
- *
4
- * Server-side function to submit contact form data to backend API.
5
- * Can be used in Next.js API routes to avoid CORS issues.
6
- *
7
- * Uses Fetchers with server-side API instance for type safety and Zod validation.
8
- *
9
- * @example
10
- * ```ts
11
- * import { submitContactForm } from '@djangocfg/nextjs/contact';
12
- *
13
- * const result = await submitContactForm({
14
- * name: 'John Doe',
15
- * email: 'john@example.com',
16
- * message: 'Hello!',
17
- * apiUrl: 'https://api.example.com'
18
- * });
19
- * ```
20
- */
21
-
22
- // Use server-only exports to avoid loading React hooks (useSWRConfig)
23
- import { API, MemoryStorageAdapter, Fetchers } from '@djangocfg/api/server';
24
- import type { Schemas } from '@djangocfg/api/server';
25
-
26
- export interface SubmitContactFormOptions {
27
- /** Lead submission data */
28
- data: Schemas.LeadSubmissionRequest;
29
- /** Backend API base URL */
30
- apiUrl: string;
31
- /** Optional site URL (auto-detected from origin if not provided) */
32
- siteUrl?: string;
33
- }
34
-
35
- export interface SubmitContactFormResult {
36
- success: boolean;
37
- message: string;
38
- lead_id?: number;
39
- }
40
-
41
- /**
42
- * Submit contact form data to backend API
43
- *
44
- * Server-side function that uses Fetchers with server-side API instance.
45
- * This provides type safety, Zod validation, and proper error handling.
46
- */
47
- export async function submitContactForm({
48
- data,
49
- apiUrl,
50
- siteUrl,
51
- }: SubmitContactFormOptions): Promise<SubmitContactFormResult> {
52
- // Validate required fields
53
- if (!data.name || !data.email || !data.message) {
54
- throw new Error('Missing required fields: name, email, message');
55
- }
56
-
57
- if (!apiUrl) {
58
- throw new Error('API URL is required');
59
- }
60
-
61
- // Create server-side API instance with MemoryStorageAdapter
62
- // This works on server-side and doesn't require browser APIs
63
- const serverApi = new API(apiUrl, {
64
- storage: new MemoryStorageAdapter(),
65
- });
66
-
67
- // Prepare submission data with site_url
68
- const submissionData: Schemas.LeadSubmissionRequest = {
69
- ...data,
70
- site_url: data.site_url || siteUrl,
71
- };
72
-
73
- try {
74
- // Use typed fetcher with server API instance
75
- // This provides type safety and runtime validation via Zod
76
- // Using Fetchers namespace to avoid loading hooks
77
- const result = await Fetchers.createLeadsSubmitCreate(submissionData, serverApi);
78
-
79
- // Return formatted result
80
- return {
81
- success: result.success ?? true,
82
- message: result.message || 'Contact form submitted successfully',
83
- lead_id: result.lead_id,
84
- };
85
- } catch (error) {
86
- // Handle API errors (including validation errors from Zod)
87
- if (error instanceof Error) {
88
- throw new Error(`Failed to submit contact form: ${error.message}`);
89
- }
90
- throw new Error('An unexpected error occurred while submitting the contact form');
91
- }
92
- }
93
-