@seo-console/package 1.0.3 → 1.1.0
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 +136 -66
- package/dist/hooks/index.js +6 -408
- package/dist/hooks/index.js.map +1 -1
- package/dist/hooks/index.mjs +6 -408
- package/dist/hooks/index.mjs.map +1 -1
- package/dist/index.d.mts +6 -9
- package/dist/index.d.ts +6 -9
- package/dist/index.js +3 -399
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +3 -399
- package/dist/index.mjs.map +1 -1
- package/dist/{robots-generator-D6T5HVNx.d.mts → robots-generator-9d9aTULk.d.mts} +1 -1
- package/dist/{robots-generator-B1KOf8vn.d.ts → robots-generator-CYA9Ofu_.d.ts} +1 -1
- package/dist/server.d.mts +3 -36
- package/dist/server.d.ts +3 -36
- package/dist/server.js +6 -422
- package/dist/server.js.map +1 -1
- package/dist/server.mjs +6 -415
- package/dist/server.mjs.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -12,7 +12,7 @@ npm install @seo-console/package
|
|
|
12
12
|
|
|
13
13
|
### Step 1: Configure Storage (Optional)
|
|
14
14
|
|
|
15
|
-
The package uses **file storage
|
|
15
|
+
The package uses **file storage** (no database required). SEO records are stored in `seo-records.json` in your project root.
|
|
16
16
|
|
|
17
17
|
To customize the storage location, add to your `.env.local`:
|
|
18
18
|
|
|
@@ -20,40 +20,39 @@ To customize the storage location, add to your `.env.local`:
|
|
|
20
20
|
SEO_CONSOLE_STORAGE_PATH=./data/seo-records.json
|
|
21
21
|
```
|
|
22
22
|
|
|
23
|
-
|
|
23
|
+
That's it! No database setup needed.
|
|
24
24
|
|
|
25
|
-
|
|
26
|
-
NEXT_PUBLIC_SUPABASE_URL=https://your-project.supabase.co
|
|
27
|
-
NEXT_PUBLIC_SUPABASE_ANON_KEY=your-anon-key
|
|
28
|
-
```
|
|
29
|
-
|
|
30
|
-
The package will automatically detect and use Supabase if these are set.
|
|
25
|
+
### Step 2: Create API Routes (REQUIRED - This is why you're getting 404 errors!)
|
|
31
26
|
|
|
32
|
-
|
|
27
|
+
**⚠️ CRITICAL:** The package does NOT include API routes. You MUST create them in your Next.js app. The 404 error you're seeing means the API route doesn't exist yet.
|
|
33
28
|
|
|
34
|
-
Create
|
|
35
|
-
|
|
36
|
-
**`app/api/seo-records/route.ts`:**
|
|
29
|
+
**Create `app/api/seo-records/route.ts`:**
|
|
37
30
|
|
|
38
31
|
```typescript
|
|
39
32
|
import { NextRequest, NextResponse } from "next/server";
|
|
40
|
-
import {
|
|
41
|
-
|
|
42
|
-
getSEORecordByRoute,
|
|
43
|
-
createSEORecord,
|
|
44
|
-
updateSEORecord,
|
|
45
|
-
deleteSEORecord
|
|
46
|
-
} from "@seo-console/package/server";
|
|
33
|
+
import { detectStorageConfig, createStorageAdapter } from "@seo-console/package";
|
|
34
|
+
import { createSEORecordSchema } from "@seo-console/package/server";
|
|
47
35
|
|
|
48
36
|
// GET - Fetch all SEO records
|
|
49
37
|
export async function GET() {
|
|
50
38
|
try {
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
39
|
+
// Get file storage adapter
|
|
40
|
+
const config = detectStorageConfig();
|
|
41
|
+
const storage = createStorageAdapter(config);
|
|
42
|
+
|
|
43
|
+
// Check if storage is available
|
|
44
|
+
const isAvailable = await storage.isAvailable();
|
|
45
|
+
if (!isAvailable) {
|
|
46
|
+
return NextResponse.json(
|
|
47
|
+
{ error: "Storage not available" },
|
|
48
|
+
{ status: 500 }
|
|
49
|
+
);
|
|
54
50
|
}
|
|
55
|
-
|
|
51
|
+
|
|
52
|
+
const records = await storage.getRecords();
|
|
53
|
+
return NextResponse.json({ data: records || [] });
|
|
56
54
|
} catch (error) {
|
|
55
|
+
console.error("Error fetching SEO records:", error);
|
|
57
56
|
return NextResponse.json(
|
|
58
57
|
{ error: error instanceof Error ? error.message : "Failed to fetch records" },
|
|
59
58
|
{ status: 500 }
|
|
@@ -65,48 +64,111 @@ export async function GET() {
|
|
|
65
64
|
export async function POST(request: NextRequest) {
|
|
66
65
|
try {
|
|
67
66
|
const body = await request.json();
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
67
|
+
|
|
68
|
+
// Validate the request body
|
|
69
|
+
const validated = createSEORecordSchema.parse(body);
|
|
70
|
+
|
|
71
|
+
// Auto-detect storage type
|
|
72
|
+
const config = detectStorageConfig();
|
|
73
|
+
const storage = createStorageAdapter(config);
|
|
74
|
+
|
|
75
|
+
const record = await storage.createRecord(validated);
|
|
76
|
+
return NextResponse.json({ data: record }, { status: 201 });
|
|
77
|
+
} catch (error) {
|
|
78
|
+
console.error("Error creating SEO record:", error);
|
|
79
|
+
if (error instanceof Error) {
|
|
80
|
+
return NextResponse.json(
|
|
81
|
+
{ error: error.message },
|
|
82
|
+
{ status: 400 }
|
|
83
|
+
);
|
|
84
|
+
}
|
|
85
|
+
return NextResponse.json(
|
|
86
|
+
{ error: "Invalid request" },
|
|
87
|
+
{ status: 400 }
|
|
88
|
+
);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
**Create `app/api/seo-records/[id]/route.ts`:**
|
|
94
|
+
|
|
95
|
+
```typescript
|
|
96
|
+
import { NextRequest, NextResponse } from "next/server";
|
|
97
|
+
import { detectStorageConfig, createStorageAdapter } from "@seo-console/package";
|
|
98
|
+
import { updateSEORecordSchema } from "@seo-console/package/server";
|
|
99
|
+
|
|
100
|
+
interface RouteParams {
|
|
101
|
+
params: Promise<{ id: string }>;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// GET - Get a single SEO record
|
|
105
|
+
export async function GET(
|
|
106
|
+
request: NextRequest,
|
|
107
|
+
{ params }: RouteParams
|
|
108
|
+
) {
|
|
109
|
+
try {
|
|
110
|
+
const { id } = await params;
|
|
111
|
+
const config = detectStorageConfig();
|
|
112
|
+
const storage = createStorageAdapter(config);
|
|
113
|
+
|
|
114
|
+
const record = await storage.getRecordById(id);
|
|
115
|
+
|
|
116
|
+
if (!record) {
|
|
117
|
+
return NextResponse.json(
|
|
118
|
+
{ error: "Record not found" },
|
|
119
|
+
{ status: 404 }
|
|
120
|
+
);
|
|
71
121
|
}
|
|
72
|
-
|
|
122
|
+
|
|
123
|
+
return NextResponse.json({ data: record });
|
|
73
124
|
} catch (error) {
|
|
74
125
|
return NextResponse.json(
|
|
75
|
-
{ error: error instanceof Error ? error.message : "Failed to
|
|
126
|
+
{ error: error instanceof Error ? error.message : "Failed to fetch record" },
|
|
76
127
|
{ status: 500 }
|
|
77
128
|
);
|
|
78
129
|
}
|
|
79
130
|
}
|
|
80
131
|
|
|
81
|
-
//
|
|
82
|
-
export async function
|
|
132
|
+
// PATCH - Update an SEO record
|
|
133
|
+
export async function PATCH(
|
|
134
|
+
request: NextRequest,
|
|
135
|
+
{ params }: RouteParams
|
|
136
|
+
) {
|
|
83
137
|
try {
|
|
138
|
+
const { id } = await params;
|
|
84
139
|
const body = await request.json();
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
140
|
+
|
|
141
|
+
const validated = updateSEORecordSchema.parse({ ...body, id });
|
|
142
|
+
const config = detectStorageConfig();
|
|
143
|
+
const storage = createStorageAdapter(config);
|
|
144
|
+
|
|
145
|
+
const record = await storage.updateRecord(validated);
|
|
146
|
+
return NextResponse.json({ data: record });
|
|
90
147
|
} catch (error) {
|
|
148
|
+
if (error instanceof Error) {
|
|
149
|
+
return NextResponse.json(
|
|
150
|
+
{ error: error.message },
|
|
151
|
+
{ status: 400 }
|
|
152
|
+
);
|
|
153
|
+
}
|
|
91
154
|
return NextResponse.json(
|
|
92
|
-
{ error:
|
|
93
|
-
{ status:
|
|
155
|
+
{ error: "Invalid request" },
|
|
156
|
+
{ status: 400 }
|
|
94
157
|
);
|
|
95
158
|
}
|
|
96
159
|
}
|
|
97
160
|
|
|
98
161
|
// DELETE - Delete an SEO record
|
|
99
|
-
export async function DELETE(
|
|
162
|
+
export async function DELETE(
|
|
163
|
+
request: NextRequest,
|
|
164
|
+
{ params }: RouteParams
|
|
165
|
+
) {
|
|
100
166
|
try {
|
|
101
|
-
const {
|
|
102
|
-
const
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
const result = await deleteSEORecord(id);
|
|
107
|
-
if (!result.success) {
|
|
108
|
-
return NextResponse.json({ error: result.error?.message }, { status: 500 });
|
|
109
|
-
}
|
|
167
|
+
const { id } = await params;
|
|
168
|
+
const config = detectStorageConfig();
|
|
169
|
+
const storage = createStorageAdapter(config);
|
|
170
|
+
|
|
171
|
+
await storage.deleteRecord(id);
|
|
110
172
|
return NextResponse.json({ success: true });
|
|
111
173
|
} catch (error) {
|
|
112
174
|
return NextResponse.json(
|
|
@@ -117,6 +179,8 @@ export async function DELETE(request: NextRequest) {
|
|
|
117
179
|
}
|
|
118
180
|
```
|
|
119
181
|
|
|
182
|
+
> **Important:** These API routes use file storage. SEO records are stored in `seo-records.json` in your project root (or the path specified in `SEO_CONSOLE_STORAGE_PATH`).
|
|
183
|
+
|
|
120
184
|
### Step 3: Add Admin Pages
|
|
121
185
|
|
|
122
186
|
Create the admin SEO section in your Next.js app. This will be accessible as a new tab in your admin area.
|
|
@@ -271,15 +335,28 @@ const metadata = await useGenerateMetadata({
|
|
|
271
335
|
});
|
|
272
336
|
```
|
|
273
337
|
|
|
274
|
-
###
|
|
338
|
+
### Storage Functions
|
|
339
|
+
|
|
340
|
+
```typescript
|
|
341
|
+
import {
|
|
342
|
+
detectStorageConfig,
|
|
343
|
+
createStorageAdapter
|
|
344
|
+
} from "@seo-console/package";
|
|
345
|
+
|
|
346
|
+
// Get storage adapter (uses file storage)
|
|
347
|
+
const config = detectStorageConfig();
|
|
348
|
+
const storage = createStorageAdapter(config);
|
|
349
|
+
|
|
350
|
+
// Use storage methods
|
|
351
|
+
const records = await storage.getRecords();
|
|
352
|
+
const record = await storage.getRecordByRoute("/about");
|
|
353
|
+
await storage.createRecord({ routePath: "/contact", title: "Contact" });
|
|
354
|
+
```
|
|
355
|
+
|
|
356
|
+
### Other Server-Side Functions
|
|
275
357
|
|
|
276
358
|
```typescript
|
|
277
359
|
import {
|
|
278
|
-
getSEORecords,
|
|
279
|
-
getSEORecordByRoute,
|
|
280
|
-
createSEORecord,
|
|
281
|
-
updateSEORecord,
|
|
282
|
-
deleteSEORecord,
|
|
283
360
|
generateSitemapFromRecords,
|
|
284
361
|
generateRobotsTxt,
|
|
285
362
|
discoverNextJSRoutes,
|
|
@@ -287,21 +364,14 @@ import {
|
|
|
287
364
|
} from "@seo-console/package/server";
|
|
288
365
|
```
|
|
289
366
|
|
|
290
|
-
## Storage
|
|
291
|
-
|
|
292
|
-
### File Storage (Default)
|
|
293
|
-
|
|
294
|
-
- **No database required** - stores data in a JSON file
|
|
295
|
-
- **Perfect for small to medium sites** - simple and fast
|
|
296
|
-
- **File location**: `seo-records.json` (configurable via `SEO_CONSOLE_STORAGE_PATH`)
|
|
297
|
-
- **Automatic**: Works out of the box with no configuration
|
|
367
|
+
## Storage
|
|
298
368
|
|
|
299
|
-
|
|
369
|
+
The package uses **file storage** - SEO records are stored in a JSON file (`seo-records.json` by default).
|
|
300
370
|
|
|
301
|
-
- **
|
|
302
|
-
- **
|
|
303
|
-
- **
|
|
304
|
-
- **
|
|
371
|
+
- **No database required** - works out of the box
|
|
372
|
+
- **Simple and fast** - perfect for most sites
|
|
373
|
+
- **Version controlled** - the JSON file can be committed to git
|
|
374
|
+
- **Configurable** - set `SEO_CONSOLE_STORAGE_PATH` to customize the file location
|
|
305
375
|
|
|
306
376
|
## License
|
|
307
377
|
|