@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/dist/server.mjs CHANGED
@@ -1,308 +1,3 @@
1
- // src/lib/supabase/server.ts
2
- import { createServerClient } from "@supabase/ssr";
3
- import { cookies } from "next/headers";
4
- async function createClient() {
5
- const cookieStore = await cookies();
6
- return createServerClient(
7
- process.env.NEXT_PUBLIC_SUPABASE_URL,
8
- process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY,
9
- {
10
- cookies: {
11
- getAll() {
12
- return cookieStore.getAll();
13
- },
14
- setAll(cookiesToSet) {
15
- try {
16
- cookiesToSet.forEach(
17
- ({ name, value, options }) => cookieStore.set(name, value, options)
18
- );
19
- } catch {
20
- }
21
- }
22
- }
23
- }
24
- );
25
- }
26
-
27
- // src/lib/database/seo-records.ts
28
- function transformRowToSEORecord(row) {
29
- return {
30
- id: row.id,
31
- userId: row.user_id,
32
- routePath: row.route_path,
33
- title: row.title ?? void 0,
34
- description: row.description ?? void 0,
35
- keywords: row.keywords ?? void 0,
36
- ogTitle: row.og_title ?? void 0,
37
- ogDescription: row.og_description ?? void 0,
38
- ogImageUrl: row.og_image_url ?? void 0,
39
- ogImageWidth: row.og_image_width ?? void 0,
40
- ogImageHeight: row.og_image_height ?? void 0,
41
- ogType: row.og_type ?? void 0,
42
- ogUrl: row.og_url ?? void 0,
43
- ogSiteName: row.og_site_name ?? void 0,
44
- twitterCard: row.twitter_card ?? void 0,
45
- twitterTitle: row.twitter_title ?? void 0,
46
- twitterDescription: row.twitter_description ?? void 0,
47
- twitterImageUrl: row.twitter_image_url ?? void 0,
48
- twitterSite: row.twitter_site ?? void 0,
49
- twitterCreator: row.twitter_creator ?? void 0,
50
- canonicalUrl: row.canonical_url ?? void 0,
51
- robots: row.robots ?? void 0,
52
- author: row.author ?? void 0,
53
- publishedTime: row.published_time ? new Date(row.published_time) : void 0,
54
- modifiedTime: row.modified_time ? new Date(row.modified_time) : void 0,
55
- structuredData: row.structured_data ? row.structured_data : void 0,
56
- validationStatus: row.validation_status ?? void 0,
57
- lastValidatedAt: row.last_validated_at ? new Date(row.last_validated_at) : void 0,
58
- validationErrors: row.validation_errors ? row.validation_errors : void 0,
59
- createdAt: new Date(row.created_at),
60
- updatedAt: new Date(row.updated_at)
61
- };
62
- }
63
- function transformToInsert(record) {
64
- return {
65
- user_id: record.userId,
66
- route_path: record.routePath,
67
- title: record.title ?? null,
68
- description: record.description ?? null,
69
- keywords: record.keywords ?? null,
70
- og_title: record.ogTitle ?? null,
71
- og_description: record.ogDescription ?? null,
72
- og_image_url: record.ogImageUrl ?? null,
73
- og_image_width: record.ogImageWidth ?? null,
74
- og_image_height: record.ogImageHeight ?? null,
75
- og_type: record.ogType ?? null,
76
- og_url: record.ogUrl ?? null,
77
- og_site_name: record.ogSiteName ?? null,
78
- twitter_card: record.twitterCard ?? null,
79
- twitter_title: record.twitterTitle ?? null,
80
- twitter_description: record.twitterDescription ?? null,
81
- twitter_image_url: record.twitterImageUrl ?? null,
82
- twitter_site: record.twitterSite ?? null,
83
- twitter_creator: record.twitterCreator ?? null,
84
- canonical_url: record.canonicalUrl ?? null,
85
- robots: record.robots ?? null,
86
- author: record.author ?? null,
87
- published_time: record.publishedTime?.toISOString() ?? null,
88
- modified_time: record.modifiedTime?.toISOString() ?? null,
89
- structured_data: record.structuredData ?? null
90
- };
91
- }
92
- function transformToUpdate(record) {
93
- const update = {};
94
- if (record.routePath !== void 0) update.route_path = record.routePath;
95
- if (record.title !== void 0) update.title = record.title ?? null;
96
- if (record.description !== void 0)
97
- update.description = record.description ?? null;
98
- if (record.keywords !== void 0) update.keywords = record.keywords ?? null;
99
- if (record.ogTitle !== void 0) update.og_title = record.ogTitle ?? null;
100
- if (record.ogDescription !== void 0)
101
- update.og_description = record.ogDescription ?? null;
102
- if (record.ogImageUrl !== void 0)
103
- update.og_image_url = record.ogImageUrl ?? null;
104
- if (record.ogImageWidth !== void 0)
105
- update.og_image_width = record.ogImageWidth ?? null;
106
- if (record.ogImageHeight !== void 0)
107
- update.og_image_height = record.ogImageHeight ?? null;
108
- if (record.ogType !== void 0) update.og_type = record.ogType ?? null;
109
- if (record.ogUrl !== void 0) update.og_url = record.ogUrl ?? null;
110
- if (record.ogSiteName !== void 0)
111
- update.og_site_name = record.ogSiteName ?? null;
112
- if (record.twitterCard !== void 0)
113
- update.twitter_card = record.twitterCard ?? null;
114
- if (record.twitterTitle !== void 0)
115
- update.twitter_title = record.twitterTitle ?? null;
116
- if (record.twitterDescription !== void 0)
117
- update.twitter_description = record.twitterDescription ?? null;
118
- if (record.twitterImageUrl !== void 0)
119
- update.twitter_image_url = record.twitterImageUrl ?? null;
120
- if (record.twitterSite !== void 0)
121
- update.twitter_site = record.twitterSite ?? null;
122
- if (record.twitterCreator !== void 0)
123
- update.twitter_creator = record.twitterCreator ?? null;
124
- if (record.canonicalUrl !== void 0)
125
- update.canonical_url = record.canonicalUrl ?? null;
126
- if (record.robots !== void 0) update.robots = record.robots ?? null;
127
- if (record.author !== void 0) update.author = record.author ?? null;
128
- if (record.publishedTime !== void 0)
129
- update.published_time = record.publishedTime?.toISOString() ?? null;
130
- if (record.modifiedTime !== void 0)
131
- update.modified_time = record.modifiedTime?.toISOString() ?? null;
132
- if (record.structuredData !== void 0)
133
- update.structured_data = record.structuredData ?? null;
134
- if (record.validationStatus !== void 0)
135
- update.validation_status = record.validationStatus ?? null;
136
- if (record.lastValidatedAt !== void 0)
137
- update.last_validated_at = record.lastValidatedAt?.toISOString() ?? null;
138
- if (record.validationErrors !== void 0)
139
- update.validation_errors = record.validationErrors ?? null;
140
- return update;
141
- }
142
- async function getSEORecords() {
143
- try {
144
- const supabase = await createClient();
145
- const {
146
- data: { user }
147
- } = await supabase.auth.getUser();
148
- if (!user) {
149
- return {
150
- success: false,
151
- error: new Error("User not authenticated")
152
- };
153
- }
154
- const { data, error } = await supabase.from("seo_records").select("*").eq("user_id", user.id).order("created_at", { ascending: false });
155
- if (error) {
156
- return { success: false, error };
157
- }
158
- const records = (data || []).map(transformRowToSEORecord);
159
- return { success: true, data: records };
160
- } catch (error) {
161
- return {
162
- success: false,
163
- error: error instanceof Error ? error : new Error("Unknown error")
164
- };
165
- }
166
- }
167
- async function getSEORecordById(id) {
168
- try {
169
- const supabase = await createClient();
170
- const {
171
- data: { user }
172
- } = await supabase.auth.getUser();
173
- if (!user) {
174
- return {
175
- success: false,
176
- error: new Error("User not authenticated")
177
- };
178
- }
179
- const { data, error } = await supabase.from("seo_records").select("*").eq("id", id).eq("user_id", user.id).single();
180
- if (error) {
181
- return { success: false, error };
182
- }
183
- if (!data) {
184
- return {
185
- success: false,
186
- error: new Error("SEO record not found")
187
- };
188
- }
189
- return { success: true, data: transformRowToSEORecord(data) };
190
- } catch (error) {
191
- return {
192
- success: false,
193
- error: error instanceof Error ? error : new Error("Unknown error")
194
- };
195
- }
196
- }
197
- async function getSEORecordByRoute(routePath) {
198
- try {
199
- const supabase = await createClient();
200
- const {
201
- data: { user }
202
- } = await supabase.auth.getUser();
203
- if (!user) {
204
- return {
205
- success: false,
206
- error: new Error("User not authenticated")
207
- };
208
- }
209
- const { data, error } = await supabase.from("seo_records").select("*").eq("route_path", routePath).eq("user_id", user.id).maybeSingle();
210
- if (error) {
211
- return { success: false, error };
212
- }
213
- if (!data) {
214
- return { success: true, data: null };
215
- }
216
- return { success: true, data: transformRowToSEORecord(data) };
217
- } catch (error) {
218
- return {
219
- success: false,
220
- error: error instanceof Error ? error : new Error("Unknown error")
221
- };
222
- }
223
- }
224
- async function createSEORecord(record) {
225
- try {
226
- const supabase = await createClient();
227
- const {
228
- data: { user }
229
- } = await supabase.auth.getUser();
230
- if (!user) {
231
- return {
232
- success: false,
233
- error: new Error("User not authenticated")
234
- };
235
- }
236
- const insertData = transformToInsert({ ...record, userId: user.id });
237
- const { data, error } = await supabase.from("seo_records").insert(insertData).select().single();
238
- if (error) {
239
- return { success: false, error };
240
- }
241
- return { success: true, data: transformRowToSEORecord(data) };
242
- } catch (error) {
243
- return {
244
- success: false,
245
- error: error instanceof Error ? error : new Error("Unknown error")
246
- };
247
- }
248
- }
249
- async function updateSEORecord(record) {
250
- try {
251
- const supabase = await createClient();
252
- const {
253
- data: { user }
254
- } = await supabase.auth.getUser();
255
- if (!user) {
256
- return {
257
- success: false,
258
- error: new Error("User not authenticated")
259
- };
260
- }
261
- const { id, ...updateData } = record;
262
- const transformedUpdate = transformToUpdate(updateData);
263
- const { data, error } = await supabase.from("seo_records").update(transformedUpdate).eq("id", id).eq("user_id", user.id).select().single();
264
- if (error) {
265
- return { success: false, error };
266
- }
267
- if (!data) {
268
- return {
269
- success: false,
270
- error: new Error("SEO record not found")
271
- };
272
- }
273
- return { success: true, data: transformRowToSEORecord(data) };
274
- } catch (error) {
275
- return {
276
- success: false,
277
- error: error instanceof Error ? error : new Error("Unknown error")
278
- };
279
- }
280
- }
281
- async function deleteSEORecord(id) {
282
- try {
283
- const supabase = await createClient();
284
- const {
285
- data: { user }
286
- } = await supabase.auth.getUser();
287
- if (!user) {
288
- return {
289
- success: false,
290
- error: new Error("User not authenticated")
291
- };
292
- }
293
- const { error } = await supabase.from("seo_records").delete().eq("id", id).eq("user_id", user.id);
294
- if (error) {
295
- return { success: false, error };
296
- }
297
- return { success: true, data: void 0 };
298
- } catch (error) {
299
- return {
300
- success: false,
301
- error: error instanceof Error ? error : new Error("Unknown error")
302
- };
303
- }
304
- }
305
-
306
1
  // src/lib/validation/seo-schema.ts
307
2
  import { z } from "zod";
308
3
  var ogTypeSchema = z.enum([
@@ -848,106 +543,15 @@ var FileStorage = class {
848
543
  }
849
544
  };
850
545
 
851
- // src/lib/storage/supabase-storage.ts
852
- var SupabaseStorage = class {
853
- constructor(supabaseUrl, supabaseKey) {
854
- this.supabaseUrl = supabaseUrl;
855
- this.supabaseKey = supabaseKey;
856
- if (typeof process !== "undefined") {
857
- process.env.NEXT_PUBLIC_SUPABASE_URL = supabaseUrl;
858
- process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY = supabaseKey;
859
- }
860
- }
861
- async isAvailable() {
862
- try {
863
- const result = await getSEORecords();
864
- return result.success;
865
- } catch {
866
- return false;
867
- }
868
- }
869
- async getRecords() {
870
- const result = await getSEORecords();
871
- if (!result.success) {
872
- throw new Error(result.error?.message || "Failed to get records");
873
- }
874
- return result.data;
875
- }
876
- async getRecordById(id) {
877
- const result = await getSEORecordById(id);
878
- if (!result.success) {
879
- if (result.error?.message?.includes("not found")) {
880
- return null;
881
- }
882
- throw new Error(result.error?.message || "Failed to get record");
883
- }
884
- return result.data || null;
885
- }
886
- async getRecordByRoute(routePath) {
887
- const result = await getSEORecordByRoute(routePath);
888
- if (!result.success) {
889
- if (result.error?.message?.includes("not found")) {
890
- return null;
891
- }
892
- throw new Error(result.error?.message || "Failed to get record");
893
- }
894
- return result.data || null;
895
- }
896
- async createRecord(record) {
897
- const result = await createSEORecord(record);
898
- if (!result.success) {
899
- throw new Error(result.error?.message || "Failed to create record");
900
- }
901
- return result.data;
902
- }
903
- async updateRecord(record) {
904
- const result = await updateSEORecord(record);
905
- if (!result.success) {
906
- throw new Error(result.error?.message || "Failed to update record");
907
- }
908
- return result.data;
909
- }
910
- async deleteRecord(id) {
911
- const result = await deleteSEORecord(id);
912
- if (!result.success) {
913
- throw new Error(result.error?.message || "Failed to delete record");
914
- }
915
- }
916
- };
917
-
918
546
  // src/lib/storage/storage-factory.ts
919
547
  function createStorageAdapter(config) {
920
- switch (config.type) {
921
- case "file":
922
- return new FileStorage(config.filePath || "seo-records.json");
923
- case "supabase":
924
- if (!config.supabaseUrl || !config.supabaseKey) {
925
- throw new Error("Supabase URL and key are required for Supabase storage");
926
- }
927
- return new SupabaseStorage(config.supabaseUrl, config.supabaseKey);
928
- case "memory":
929
- return new FileStorage(":memory:");
930
- default:
931
- throw new Error(`Unsupported storage type: ${config.type}`);
932
- }
548
+ const filePath = config?.filePath || process.env.SEO_CONSOLE_STORAGE_PATH || "seo-records.json";
549
+ return new FileStorage(filePath);
933
550
  }
934
551
  function detectStorageConfig() {
935
- if (process.env.NEXT_PUBLIC_SUPABASE_URL && process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY) {
936
- return {
937
- type: "supabase",
938
- supabaseUrl: process.env.NEXT_PUBLIC_SUPABASE_URL,
939
- supabaseKey: process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY
940
- };
941
- }
942
- if (process.env.SEO_CONSOLE_STORAGE_PATH) {
943
- return {
944
- type: "file",
945
- filePath: process.env.SEO_CONSOLE_STORAGE_PATH
946
- };
947
- }
948
552
  return {
949
553
  type: "file",
950
- filePath: "seo-records.json"
554
+ filePath: process.env.SEO_CONSOLE_STORAGE_PATH || "seo-records.json"
951
555
  };
952
556
  }
953
557
 
@@ -964,16 +568,10 @@ async function useGenerateMetadata(options = {}) {
964
568
  let record = null;
965
569
  try {
966
570
  const storageConfig = detectStorageConfig();
967
- if (storageConfig.type === "file" || storageConfig.type === "memory") {
968
- const storage = createStorageAdapter(storageConfig);
969
- record = await storage.getRecordByRoute(routePath);
970
- } else {
971
- const result = await getSEORecordByRoute(routePath);
972
- record = result.success ? result.data || null : null;
973
- }
571
+ const storage = createStorageAdapter(storageConfig);
572
+ record = await storage.getRecordByRoute(routePath);
974
573
  } catch (error) {
975
- const result = await getSEORecordByRoute(routePath);
976
- record = result.success ? result.data || null : null;
574
+ console.warn("Failed to load SEO record from storage:", error);
977
575
  }
978
576
  if (!record) {
979
577
  return {
@@ -1456,23 +1054,16 @@ async function validatePublicAccess(url) {
1456
1054
  }
1457
1055
  export {
1458
1056
  crawlSiteForSEO,
1459
- createSEORecord,
1460
1057
  createSEORecordSchema,
1461
- deleteSEORecord,
1462
1058
  discoverNextJSRoutes,
1463
1059
  extractMetadataFromURL,
1464
1060
  generateRobotsTxt,
1465
1061
  generateSitemapFromRecords,
1466
1062
  generateSitemapXML,
1467
- getSEORecords as getAllSEORecords,
1468
1063
  getRoutePathFromParams,
1469
- getSEORecordById,
1470
- getSEORecordByRoute,
1471
- getSEORecords,
1472
1064
  metadataToSEORecord,
1473
1065
  seoRecordsToSitemapEntries,
1474
1066
  updateRobotsTxtWithSitemap,
1475
- updateSEORecord,
1476
1067
  updateSEORecordSchema,
1477
1068
  useGenerateMetadata,
1478
1069
  validateCrawlability,