@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/README.md +3 -33
- package/dist/config/index.d.mts +1 -1
- package/dist/config/index.mjs +3 -9
- package/dist/config/index.mjs.map +1 -1
- package/dist/index.d.mts +0 -3
- package/dist/index.mjs +3 -105
- package/dist/index.mjs.map +1 -1
- package/package.json +4 -11
- package/src/config/constants.ts +0 -1
- package/src/config/createNextConfig.ts +2 -0
- package/src/index.ts +0 -3
- package/dist/contact/index.d.mts +0 -47
- package/dist/contact/index.mjs +0 -98
- package/dist/contact/index.mjs.map +0 -1
- package/dist/contact/route.d.mts +0 -35
- package/dist/contact/route.mjs +0 -99
- package/dist/contact/route.mjs.map +0 -1
- package/src/contact/index.ts +0 -13
- package/src/contact/route.ts +0 -102
- package/src/contact/submit.ts +0 -93
package/package.json
CHANGED
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@djangocfg/nextjs",
|
|
3
|
-
"version": "2.1.
|
|
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.
|
|
113
|
-
"@djangocfg/layouts": "^2.1.
|
|
114
|
-
"@djangocfg/typescript-config": "^2.1.
|
|
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",
|
package/src/config/constants.ts
CHANGED
|
@@ -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
package/dist/contact/index.d.mts
DELETED
|
@@ -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 };
|
package/dist/contact/index.mjs
DELETED
|
@@ -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"]}
|
package/dist/contact/route.d.mts
DELETED
|
@@ -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 };
|
package/dist/contact/route.mjs
DELETED
|
@@ -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"]}
|
package/src/contact/index.ts
DELETED
|
@@ -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
|
-
|
package/src/contact/route.ts
DELETED
|
@@ -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
|
-
|
package/src/contact/submit.ts
DELETED
|
@@ -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
|
-
|