strapi-sitemap-generator 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. package/README.md +27 -0
  2. package/dist/_chunks/App-Bvbv7t_S.mjs +25065 -0
  3. package/dist/_chunks/App-D449cQR3.js +25105 -0
  4. package/dist/_chunks/en-BptFMppp.mjs +7 -0
  5. package/dist/_chunks/en-CZAGT--R.js +7 -0
  6. package/dist/admin/index.js +67 -0
  7. package/dist/admin/index.mjs +68 -0
  8. package/dist/admin/src/components/Initializer.d.ts +5 -0
  9. package/dist/admin/src/components/PluginIcon.d.ts +2 -0
  10. package/dist/admin/src/index.d.ts +14 -0
  11. package/dist/admin/src/pages/App.d.ts +2 -0
  12. package/dist/admin/src/pages/HomePage.d.ts +2 -0
  13. package/dist/admin/src/pluginId.d.ts +1 -0
  14. package/dist/admin/src/utils/getTranslation.d.ts +2 -0
  15. package/dist/server/index.js +338 -0
  16. package/dist/server/index.mjs +339 -0
  17. package/dist/server/src/bootstrap.d.ts +5 -0
  18. package/dist/server/src/config/index.d.ts +5 -0
  19. package/dist/server/src/content-types/index.d.ts +2 -0
  20. package/dist/server/src/controllers/controller.d.ts +34 -0
  21. package/dist/server/src/controllers/index.d.ts +12 -0
  22. package/dist/server/src/destroy.d.ts +5 -0
  23. package/dist/server/src/index.d.ts +95 -0
  24. package/dist/server/src/middlewares/index.d.ts +2 -0
  25. package/dist/server/src/policies/index.d.ts +2 -0
  26. package/dist/server/src/register.d.ts +5 -0
  27. package/dist/server/src/routes/admin/index.d.ts +12 -0
  28. package/dist/server/src/routes/content-api/index.d.ts +13 -0
  29. package/dist/server/src/routes/index.d.ts +26 -0
  30. package/dist/server/src/services/index.d.ts +38 -0
  31. package/dist/server/src/services/service.d.ts +55 -0
  32. package/package.json +78 -0
@@ -0,0 +1,339 @@
1
+ const bootstrap = ({ strapi }) => {
2
+ };
3
+ const destroy = ({ strapi }) => {
4
+ };
5
+ const register = ({ strapi }) => {
6
+ };
7
+ const config = {
8
+ default: {},
9
+ validator() {
10
+ }
11
+ };
12
+ const contentTypes = {};
13
+ const controller = ({ strapi }) => ({
14
+ /**
15
+ * Generate sitemap XML
16
+ * Public endpoint for serving sitemap.xml
17
+ */
18
+ async generateXml(ctx) {
19
+ try {
20
+ const service2 = strapi.plugin("strapi-sitemap-generator").service("service");
21
+ const xml = await service2.generateXML();
22
+ ctx.type = "application/xml";
23
+ ctx.body = xml;
24
+ } catch (error) {
25
+ ctx.throw(500, `Failed to generate sitemap: ${error.message}`);
26
+ }
27
+ },
28
+ /**
29
+ * Get sitemap data as JSON
30
+ * Admin endpoint for preview
31
+ */
32
+ async getSitemapData(ctx) {
33
+ try {
34
+ const service2 = strapi.plugin("strapi-sitemap-generator").service("service");
35
+ const data = await service2.getSitemapData();
36
+ ctx.body = data;
37
+ } catch (error) {
38
+ ctx.throw(500, `Failed to get sitemap data: ${error.message}`);
39
+ }
40
+ },
41
+ /**
42
+ * (Removed) Download sitemap.xml - not needed, engines fetch XML via public URL
43
+ */
44
+ /**
45
+ * Get all available content types
46
+ * Admin endpoint for content type discovery
47
+ */
48
+ async getContentTypes(ctx) {
49
+ try {
50
+ const service2 = strapi.plugin("strapi-sitemap-generator").service("service");
51
+ const contentTypes2 = await service2.discoverContentTypes();
52
+ ctx.body = { data: contentTypes2 };
53
+ } catch (error) {
54
+ ctx.throw(500, `Failed to discover content types: ${error.message}`);
55
+ }
56
+ },
57
+ /**
58
+ * Get current plugin configuration
59
+ * Admin endpoint for loading settings
60
+ */
61
+ async getConfig(ctx) {
62
+ try {
63
+ const service2 = strapi.plugin("strapi-sitemap-generator").service("service");
64
+ const config2 = await service2.getConfig();
65
+ ctx.body = config2;
66
+ } catch (error) {
67
+ ctx.throw(500, `Failed to get config: ${error.message}`);
68
+ }
69
+ },
70
+ /**
71
+ * Update plugin configuration
72
+ * Admin endpoint for saving settings
73
+ */
74
+ async updateConfig(ctx) {
75
+ try {
76
+ const service2 = strapi.plugin("strapi-sitemap-generator").service("service");
77
+ const config2 = await service2.updateConfig(ctx.request.body);
78
+ ctx.body = config2;
79
+ } catch (error) {
80
+ ctx.throw(500, `Failed to update config: ${error.message}`);
81
+ }
82
+ }
83
+ });
84
+ const controllers = {
85
+ controller
86
+ };
87
+ const middlewares = {};
88
+ const policies = {};
89
+ const contentAPIRoutes = {
90
+ type: "content-api",
91
+ routes: [
92
+ {
93
+ method: "GET",
94
+ path: "/sitemap.xml",
95
+ handler: "controller.generateXml",
96
+ config: {
97
+ auth: false,
98
+ policies: []
99
+ }
100
+ }
101
+ ]
102
+ };
103
+ const adminAPIRoutes = {
104
+ type: "admin",
105
+ routes: [
106
+ {
107
+ method: "GET",
108
+ path: "/data",
109
+ handler: "controller.getSitemapData",
110
+ config: {
111
+ policies: []
112
+ }
113
+ },
114
+ {
115
+ method: "GET",
116
+ path: "/content-types",
117
+ handler: "controller.getContentTypes",
118
+ config: {
119
+ policies: []
120
+ }
121
+ },
122
+ {
123
+ method: "GET",
124
+ path: "/config",
125
+ handler: "controller.getConfig",
126
+ config: {
127
+ policies: []
128
+ }
129
+ },
130
+ {
131
+ method: "PUT",
132
+ path: "/config",
133
+ handler: "controller.updateConfig",
134
+ config: {
135
+ policies: []
136
+ }
137
+ }
138
+ ]
139
+ };
140
+ const routes = {
141
+ "content-api": contentAPIRoutes,
142
+ admin: adminAPIRoutes
143
+ };
144
+ const service = ({ strapi }) => ({
145
+ /**
146
+ * Discover ALL content types with slug fields
147
+ */
148
+ async discoverContentTypes() {
149
+ const contentTypes2 = [];
150
+ const allContentTypes = strapi.contentTypes;
151
+ for (const [uid, contentType] of Object.entries(allContentTypes)) {
152
+ if (!uid.startsWith("api::")) continue;
153
+ const schema = contentType;
154
+ const attributes = schema.attributes || {};
155
+ const hasSlug = "slug" in attributes;
156
+ if (hasSlug) {
157
+ contentTypes2.push({
158
+ uid,
159
+ singularName: schema.info?.singularName || uid.split(".").pop(),
160
+ pluralName: schema.info?.pluralName || uid.split(".").pop(),
161
+ displayName: schema.info?.displayName || uid,
162
+ hasPublishedAt: "publishedAt" in attributes
163
+ });
164
+ }
165
+ }
166
+ return contentTypes2;
167
+ },
168
+ /**
169
+ * Get content type info
170
+ */
171
+ async getContentTypeInfo(uid) {
172
+ const contentType = strapi.contentTypes[uid];
173
+ const attributes = contentType.attributes || {};
174
+ return {
175
+ singularName: contentType.info?.singularName || uid.split(".").pop(),
176
+ pluralName: contentType.info?.pluralName || uid.split(".").pop(),
177
+ displayName: contentType.info?.displayName || uid,
178
+ hasPublishedAt: "publishedAt" in attributes
179
+ };
180
+ },
181
+ /**
182
+ * Generate sitemap XML from user-selected content types
183
+ */
184
+ async generateXML() {
185
+ const config2 = await this.getConfig();
186
+ const {
187
+ baseUrl = "https://example.com",
188
+ selectedContentTypes = [],
189
+ customPaths = {},
190
+ customPriorities = {},
191
+ customChangefreq = {}
192
+ } = config2;
193
+ strapi.log.info(`[Sitemap] Generating sitemap with ${selectedContentTypes.length} selected content types`);
194
+ strapi.log.info(`[Sitemap] Selected types:`, selectedContentTypes);
195
+ let xml = '<?xml version="1.0" encoding="UTF-8"?>\n';
196
+ xml += '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">\n';
197
+ if (selectedContentTypes.length === 0) {
198
+ strapi.log.warn("[Sitemap] No content types selected for sitemap generation");
199
+ xml += "</urlset>";
200
+ return xml;
201
+ }
202
+ for (const uid of selectedContentTypes) {
203
+ try {
204
+ const contentType = await this.getContentTypeInfo(uid);
205
+ strapi.log.info(`[Sitemap] Processing content type: ${uid}`);
206
+ const entries = await strapi.entityService.findMany(uid);
207
+ strapi.log.info(`[Sitemap] Found ${entries?.length || 0} entries for ${uid}`);
208
+ if (entries && Array.isArray(entries) && entries.length > 0) {
209
+ const basePath = customPaths[uid] || `/${contentType.pluralName}`;
210
+ const priority = customPriorities[uid] || 0.7;
211
+ const changefreq = customChangefreq[uid] || "monthly";
212
+ entries.forEach((entry) => {
213
+ if (entry.slug) {
214
+ xml += this.generateUrlEntry({
215
+ loc: `${baseUrl}${basePath}/${entry.slug}`,
216
+ lastmod: entry.updatedAt ? new Date(entry.updatedAt).toISOString().split("T")[0] : (/* @__PURE__ */ new Date()).toISOString().split("T")[0],
217
+ priority,
218
+ changefreq
219
+ });
220
+ }
221
+ });
222
+ }
223
+ } catch (error) {
224
+ strapi.log.error(`[Sitemap] Failed to fetch entries for ${uid}:`, error.message);
225
+ strapi.log.error(`[Sitemap] Error details:`, error);
226
+ }
227
+ }
228
+ xml += "</urlset>";
229
+ strapi.log.info(`[Sitemap] Sitemap generation complete`);
230
+ return xml;
231
+ },
232
+ generateUrlEntry({ loc, lastmod, priority, changefreq }) {
233
+ let entry = " <url>\n";
234
+ entry += ` <loc>${this.escapeXml(loc)}</loc>
235
+ `;
236
+ if (lastmod) entry += ` <lastmod>${lastmod}</lastmod>
237
+ `;
238
+ if (changefreq) entry += ` <changefreq>${changefreq}</changefreq>
239
+ `;
240
+ if (priority) entry += ` <priority>${priority}</priority>
241
+ `;
242
+ entry += " </url>\n";
243
+ return entry;
244
+ },
245
+ escapeXml(unsafe) {
246
+ return unsafe.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&apos;");
247
+ },
248
+ /**
249
+ * Get structured sitemap data for frontend display
250
+ */
251
+ async getSitemapData() {
252
+ const config2 = await this.getConfig();
253
+ const {
254
+ baseUrl = "https://example.com",
255
+ selectedContentTypes = [],
256
+ customPaths = {}
257
+ } = config2;
258
+ strapi.log.info(`[Sitemap] Getting sitemap data for ${selectedContentTypes.length} content types`);
259
+ const data = {
260
+ entries: {},
261
+ meta: {
262
+ totalUrls: 0,
263
+ lastGenerated: (/* @__PURE__ */ new Date()).toISOString(),
264
+ contentTypes: []
265
+ }
266
+ };
267
+ if (selectedContentTypes.length === 0) {
268
+ strapi.log.warn("[Sitemap] No content types selected - returning empty sitemap data");
269
+ return data;
270
+ }
271
+ for (const uid of selectedContentTypes) {
272
+ try {
273
+ const contentType = await this.getContentTypeInfo(uid);
274
+ strapi.log.info(`[Sitemap] Fetching data for ${uid}`);
275
+ const entries = await strapi.entityService.findMany(uid);
276
+ strapi.log.info(`[Sitemap] Found ${entries?.length || 0} entries for ${uid}`);
277
+ if (entries && Array.isArray(entries) && entries.length > 0) {
278
+ const basePath = customPaths[uid] || `/${contentType.pluralName}`;
279
+ data.entries[uid] = entries.filter((entry) => entry.slug).map((entry) => ({
280
+ url: `${baseUrl}${basePath}/${entry.slug}`,
281
+ title: entry.title || entry.name || entry.slug,
282
+ lastmod: entry.updatedAt
283
+ }));
284
+ data.meta.contentTypes.push({
285
+ uid,
286
+ displayName: contentType.displayName,
287
+ count: data.entries[uid].length
288
+ });
289
+ data.meta.totalUrls += data.entries[uid].length;
290
+ }
291
+ } catch (error) {
292
+ strapi.log.error(`[Sitemap] Failed to fetch ${uid}:`, error.message);
293
+ strapi.log.error(`[Sitemap] Error details:`, error);
294
+ }
295
+ }
296
+ strapi.log.info(`[Sitemap] Total URLs in sitemap: ${data.meta.totalUrls}`);
297
+ return data;
298
+ },
299
+ /**
300
+ * Get plugin configuration
301
+ */
302
+ async getConfig() {
303
+ const pluginStore = strapi.store({ type: "plugin", name: "strapi-sitemap-generator" });
304
+ const config2 = await pluginStore.get({ key: "config" });
305
+ return config2 || {
306
+ baseUrl: "https://example.com",
307
+ selectedContentTypes: [],
308
+ customPaths: {},
309
+ customPriorities: {},
310
+ customChangefreq: {}
311
+ };
312
+ },
313
+ /**
314
+ * Update plugin configuration
315
+ */
316
+ async updateConfig(newConfig) {
317
+ const pluginStore = strapi.store({ type: "plugin", name: "strapi-sitemap-generator" });
318
+ await pluginStore.set({ key: "config", value: newConfig });
319
+ return newConfig;
320
+ }
321
+ });
322
+ const services = {
323
+ service
324
+ };
325
+ const index = {
326
+ register,
327
+ bootstrap,
328
+ destroy,
329
+ config,
330
+ controllers,
331
+ routes,
332
+ services,
333
+ contentTypes,
334
+ policies,
335
+ middlewares
336
+ };
337
+ export {
338
+ index as default
339
+ };
@@ -0,0 +1,5 @@
1
+ import type { Core } from '@strapi/types';
2
+ declare const bootstrap: ({ strapi }: {
3
+ strapi: Core.Strapi;
4
+ }) => void;
5
+ export default bootstrap;
@@ -0,0 +1,5 @@
1
+ declare const _default: {
2
+ default: {};
3
+ validator(): void;
4
+ };
5
+ export default _default;
@@ -0,0 +1,2 @@
1
+ declare const _default: {};
2
+ export default _default;
@@ -0,0 +1,34 @@
1
+ import type { Core } from '@strapi/types';
2
+ declare const controller: ({ strapi }: {
3
+ strapi: Core.Strapi;
4
+ }) => {
5
+ /**
6
+ * Generate sitemap XML
7
+ * Public endpoint for serving sitemap.xml
8
+ */
9
+ generateXml(ctx: any): Promise<void>;
10
+ /**
11
+ * Get sitemap data as JSON
12
+ * Admin endpoint for preview
13
+ */
14
+ getSitemapData(ctx: any): Promise<void>;
15
+ /**
16
+ * (Removed) Download sitemap.xml - not needed, engines fetch XML via public URL
17
+ */
18
+ /**
19
+ * Get all available content types
20
+ * Admin endpoint for content type discovery
21
+ */
22
+ getContentTypes(ctx: any): Promise<void>;
23
+ /**
24
+ * Get current plugin configuration
25
+ * Admin endpoint for loading settings
26
+ */
27
+ getConfig(ctx: any): Promise<void>;
28
+ /**
29
+ * Update plugin configuration
30
+ * Admin endpoint for saving settings
31
+ */
32
+ updateConfig(ctx: any): Promise<void>;
33
+ };
34
+ export default controller;
@@ -0,0 +1,12 @@
1
+ declare const _default: {
2
+ controller: ({ strapi }: {
3
+ strapi: import("@strapi/types/dist/core").Strapi;
4
+ }) => {
5
+ generateXml(ctx: any): Promise<void>;
6
+ getSitemapData(ctx: any): Promise<void>;
7
+ getContentTypes(ctx: any): Promise<void>;
8
+ getConfig(ctx: any): Promise<void>;
9
+ updateConfig(ctx: any): Promise<void>;
10
+ };
11
+ };
12
+ export default _default;
@@ -0,0 +1,5 @@
1
+ import type { Core } from '@strapi/strapi';
2
+ declare const destroy: ({ strapi }: {
3
+ strapi: Core.Strapi;
4
+ }) => void;
5
+ export default destroy;
@@ -0,0 +1,95 @@
1
+ declare const _default: {
2
+ register: ({ strapi }: {
3
+ strapi: import("@strapi/types/dist/core").Strapi;
4
+ }) => void;
5
+ bootstrap: ({ strapi }: {
6
+ strapi: import("@strapi/types/dist/core").Strapi;
7
+ }) => void;
8
+ destroy: ({ strapi }: {
9
+ strapi: import("@strapi/types/dist/core").Strapi;
10
+ }) => void;
11
+ config: {
12
+ default: {};
13
+ validator(): void;
14
+ };
15
+ controllers: {
16
+ controller: ({ strapi }: {
17
+ strapi: import("@strapi/types/dist/core").Strapi;
18
+ }) => {
19
+ generateXml(ctx: any): Promise<void>;
20
+ getSitemapData(ctx: any): Promise<void>;
21
+ getContentTypes(ctx: any): Promise<void>;
22
+ getConfig(ctx: any): Promise<void>;
23
+ updateConfig(ctx: any): Promise<void>;
24
+ };
25
+ };
26
+ routes: {
27
+ 'content-api': {
28
+ type: string;
29
+ routes: {
30
+ method: string;
31
+ path: string;
32
+ handler: string;
33
+ config: {
34
+ auth: boolean;
35
+ policies: never[];
36
+ };
37
+ }[];
38
+ };
39
+ /**
40
+ * Plugin server methods
41
+ */
42
+ admin: {
43
+ type: string;
44
+ routes: {
45
+ method: string;
46
+ path: string;
47
+ handler: string;
48
+ config: {
49
+ policies: never[];
50
+ };
51
+ }[];
52
+ };
53
+ };
54
+ services: {
55
+ service: ({ strapi }: {
56
+ strapi: import("@strapi/types/dist/core").Strapi;
57
+ }) => {
58
+ discoverContentTypes(): Promise<{
59
+ uid: string;
60
+ singularName: any;
61
+ pluralName: any;
62
+ displayName: any;
63
+ hasPublishedAt: boolean;
64
+ }[]>;
65
+ getContentTypeInfo(uid: string): Promise<{
66
+ singularName: any;
67
+ pluralName: any;
68
+ displayName: any;
69
+ hasPublishedAt: boolean;
70
+ }>;
71
+ generateXML(): Promise<string>;
72
+ generateUrlEntry({ loc, lastmod, priority, changefreq }: {
73
+ loc: string;
74
+ lastmod?: string | undefined;
75
+ priority?: number | undefined;
76
+ changefreq?: string | undefined;
77
+ }): string;
78
+ escapeXml(unsafe: string): string;
79
+ getSitemapData(): Promise<{
80
+ entries: Record<string, any[]>;
81
+ meta: {
82
+ totalUrls: number;
83
+ lastGenerated: string;
84
+ contentTypes: any[];
85
+ };
86
+ }>;
87
+ getConfig(): Promise<any>;
88
+ updateConfig(newConfig: any): Promise<any>;
89
+ };
90
+ };
91
+ contentTypes: {};
92
+ policies: {};
93
+ middlewares: {};
94
+ };
95
+ export default _default;
@@ -0,0 +1,2 @@
1
+ declare const _default: {};
2
+ export default _default;
@@ -0,0 +1,2 @@
1
+ declare const _default: {};
2
+ export default _default;
@@ -0,0 +1,5 @@
1
+ import type { Core } from '@strapi/strapi';
2
+ declare const register: ({ strapi }: {
3
+ strapi: Core.Strapi;
4
+ }) => void;
5
+ export default register;
@@ -0,0 +1,12 @@
1
+ declare const _default: {
2
+ type: string;
3
+ routes: {
4
+ method: string;
5
+ path: string;
6
+ handler: string;
7
+ config: {
8
+ policies: never[];
9
+ };
10
+ }[];
11
+ };
12
+ export default _default;
@@ -0,0 +1,13 @@
1
+ declare const _default: {
2
+ type: string;
3
+ routes: {
4
+ method: string;
5
+ path: string;
6
+ handler: string;
7
+ config: {
8
+ auth: boolean;
9
+ policies: never[];
10
+ };
11
+ }[];
12
+ };
13
+ export default _default;
@@ -0,0 +1,26 @@
1
+ declare const routes: {
2
+ 'content-api': {
3
+ type: string;
4
+ routes: {
5
+ method: string;
6
+ path: string;
7
+ handler: string;
8
+ config: {
9
+ auth: boolean;
10
+ policies: never[];
11
+ };
12
+ }[];
13
+ };
14
+ admin: {
15
+ type: string;
16
+ routes: {
17
+ method: string;
18
+ path: string;
19
+ handler: string;
20
+ config: {
21
+ policies: never[];
22
+ };
23
+ }[];
24
+ };
25
+ };
26
+ export default routes;
@@ -0,0 +1,38 @@
1
+ declare const _default: {
2
+ service: ({ strapi }: {
3
+ strapi: import("@strapi/types/dist/core").Strapi;
4
+ }) => {
5
+ discoverContentTypes(): Promise<{
6
+ uid: string;
7
+ singularName: any;
8
+ pluralName: any;
9
+ displayName: any;
10
+ hasPublishedAt: boolean;
11
+ }[]>;
12
+ getContentTypeInfo(uid: string): Promise<{
13
+ singularName: any;
14
+ pluralName: any;
15
+ displayName: any;
16
+ hasPublishedAt: boolean;
17
+ }>;
18
+ generateXML(): Promise<string>;
19
+ generateUrlEntry({ loc, lastmod, priority, changefreq }: {
20
+ loc: string;
21
+ lastmod?: string | undefined;
22
+ priority?: number | undefined;
23
+ changefreq?: string | undefined;
24
+ }): string;
25
+ escapeXml(unsafe: string): string;
26
+ getSitemapData(): Promise<{
27
+ entries: Record<string, any[]>;
28
+ meta: {
29
+ totalUrls: number;
30
+ lastGenerated: string;
31
+ contentTypes: any[];
32
+ };
33
+ }>;
34
+ getConfig(): Promise<any>;
35
+ updateConfig(newConfig: any): Promise<any>;
36
+ };
37
+ };
38
+ export default _default;
@@ -0,0 +1,55 @@
1
+ import type { Core } from '@strapi/types';
2
+ declare const service: ({ strapi }: {
3
+ strapi: Core.Strapi;
4
+ }) => {
5
+ /**
6
+ * Discover ALL content types with slug fields
7
+ */
8
+ discoverContentTypes(): Promise<{
9
+ uid: string;
10
+ singularName: any;
11
+ pluralName: any;
12
+ displayName: any;
13
+ hasPublishedAt: boolean;
14
+ }[]>;
15
+ /**
16
+ * Get content type info
17
+ */
18
+ getContentTypeInfo(uid: string): Promise<{
19
+ singularName: any;
20
+ pluralName: any;
21
+ displayName: any;
22
+ hasPublishedAt: boolean;
23
+ }>;
24
+ /**
25
+ * Generate sitemap XML from user-selected content types
26
+ */
27
+ generateXML(): Promise<string>;
28
+ generateUrlEntry({ loc, lastmod, priority, changefreq }: {
29
+ loc: string;
30
+ lastmod?: string;
31
+ priority?: number;
32
+ changefreq?: string;
33
+ }): string;
34
+ escapeXml(unsafe: string): string;
35
+ /**
36
+ * Get structured sitemap data for frontend display
37
+ */
38
+ getSitemapData(): Promise<{
39
+ entries: Record<string, any[]>;
40
+ meta: {
41
+ totalUrls: number;
42
+ lastGenerated: string;
43
+ contentTypes: any[];
44
+ };
45
+ }>;
46
+ /**
47
+ * Get plugin configuration
48
+ */
49
+ getConfig(): Promise<any>;
50
+ /**
51
+ * Update plugin configuration
52
+ */
53
+ updateConfig(newConfig: any): Promise<any>;
54
+ };
55
+ export default service;