@vicacha-devs/strapi-plugin-seo 0.0.0-stage → 2.0.12

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 (81) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +84 -2
  3. package/dist/admin/components/CMEditView/RightLinksCompo/SeoChecks/AlternativeTextCheck/index.d.ts +9 -0
  4. package/dist/admin/components/CMEditView/RightLinksCompo/SeoChecks/CanonicalUrlCheck/index.d.ts +7 -0
  5. package/dist/admin/components/CMEditView/RightLinksCompo/SeoChecks/KeywordDensityCheck/index.d.ts +7 -0
  6. package/dist/admin/components/CMEditView/RightLinksCompo/SeoChecks/LastUpdatedAtCheck/index.d.ts +7 -0
  7. package/dist/admin/components/CMEditView/RightLinksCompo/SeoChecks/MetaDescriptionCheck/index.d.ts +7 -0
  8. package/dist/admin/components/CMEditView/RightLinksCompo/SeoChecks/MetaRobotCheck/index.d.ts +7 -0
  9. package/dist/admin/components/CMEditView/RightLinksCompo/SeoChecks/MetaTitleCheck/index.d.ts +7 -0
  10. package/dist/admin/components/CMEditView/RightLinksCompo/SeoChecks/OpenGraphCheck/index.d.ts +7 -0
  11. package/dist/admin/components/CMEditView/RightLinksCompo/SeoChecks/SEOAccordion/index.d.ts +10 -0
  12. package/dist/admin/components/CMEditView/RightLinksCompo/SeoChecks/StructuredDataCheck/index.d.ts +7 -0
  13. package/dist/admin/components/CMEditView/RightLinksCompo/SeoChecks/WordCountCheck/index.d.ts +7 -0
  14. package/dist/admin/components/CMEditView/RightLinksCompo/SeoChecks/index.d.ts +10 -0
  15. package/dist/admin/components/CMEditView/RightLinksCompo/Summary/BrowserPreview/KeywordCheck/index.d.ts +7 -0
  16. package/dist/admin/components/CMEditView/RightLinksCompo/Summary/BrowserPreview/MetaChecks/index.d.ts +8 -0
  17. package/dist/admin/components/CMEditView/RightLinksCompo/Summary/BrowserPreview/Serp/index.d.ts +6 -0
  18. package/dist/admin/components/CMEditView/RightLinksCompo/Summary/BrowserPreview/index.d.ts +6 -0
  19. package/dist/admin/components/CMEditView/RightLinksCompo/Summary/OpenGraphPreview/Facebook/index.d.ts +8 -0
  20. package/dist/admin/components/CMEditView/RightLinksCompo/Summary/OpenGraphPreview/LinkedIn/index.d.ts +8 -0
  21. package/dist/admin/components/CMEditView/RightLinksCompo/Summary/OpenGraphPreview/X/index.d.ts +8 -0
  22. package/dist/admin/components/CMEditView/RightLinksCompo/Summary/OpenGraphPreview/index.d.ts +6 -0
  23. package/dist/admin/components/CMEditView/RightLinksCompo/Summary/PreviewChecks/index.d.ts +6 -0
  24. package/dist/admin/components/CMEditView/RightLinksCompo/Summary/index.d.ts +4 -0
  25. package/dist/admin/components/CMEditView/RightLinksCompo/Summary/reducer.d.ts +2 -0
  26. package/dist/admin/components/CMEditView/RightLinksCompo/index.d.ts +1 -0
  27. package/dist/admin/components/CMEditView/utils/checks.d.ts +14 -0
  28. package/dist/admin/components/CMEditView/utils/getRegularImageAltTexts.d.ts +5 -0
  29. package/dist/admin/components/CMEditView/utils/getRichTextAndBlocksFields.d.ts +10 -0
  30. package/dist/admin/components/CMEditView/utils/getRichTextData.d.ts +2 -0
  31. package/dist/admin/components/HomePage/Header/index.d.ts +5 -0
  32. package/dist/admin/components/HomePage/Main/EmptyComponentLayout/illo.d.ts +1 -0
  33. package/dist/admin/components/HomePage/Main/SettingsModal/index.d.ts +8 -0
  34. package/dist/admin/components/HomePage/Main/index.d.ts +6 -0
  35. package/dist/admin/components/Initializer.d.ts +5 -0
  36. package/dist/admin/hooks/useSettingsApi.d.ts +5 -0
  37. package/dist/admin/index-C8tiCtgn.cjs +3490 -0
  38. package/dist/admin/index-CJ64dp6B.js +3473 -0
  39. package/dist/admin/index-CZ4VBOGS.cjs +589 -0
  40. package/dist/admin/index-DgvE6ytW.js +571 -0
  41. package/dist/admin/index.cjs +5 -0
  42. package/dist/admin/index.d.ts +18 -0
  43. package/dist/admin/index.js +5 -0
  44. package/dist/admin/index.mjs +5 -0
  45. package/dist/admin/pages/App/index.d.ts +2 -0
  46. package/dist/admin/pages/HomePage/index.d.ts +2 -0
  47. package/dist/admin/permissions.d.ts +10 -0
  48. package/dist/admin/pluginId.d.ts +1 -0
  49. package/dist/admin/translations/ar.json.d.ts +133 -0
  50. package/dist/admin/translations/en.json.d.ts +133 -0
  51. package/dist/admin/translations/es.json.d.ts +133 -0
  52. package/dist/admin/translations/fr.json.d.ts +133 -0
  53. package/dist/admin/translations/pt-BR.json.d.ts +133 -0
  54. package/dist/admin/translations/tr.json.d.ts +133 -0
  55. package/dist/admin/utils/getTrad.d.ts +1 -0
  56. package/dist/admin/utils/prefixPluginTranslations.d.ts +1 -0
  57. package/dist/package.json +3 -0
  58. package/dist/server/bootstrap.d.ts +5 -0
  59. package/dist/server/components/open-graph.json.d.ts +36 -0
  60. package/dist/server/components/seo.json.d.ts +52 -0
  61. package/dist/server/config/index.d.ts +5 -0
  62. package/dist/server/controllers/index.d.ts +16 -0
  63. package/dist/server/controllers/seo.d.ts +13 -0
  64. package/dist/server/controllers/settings.d.ts +16 -0
  65. package/dist/server/destroy.d.ts +5 -0
  66. package/dist/server/index.cjs +416 -0
  67. package/dist/server/index.d.ts +83 -0
  68. package/dist/server/index.js +416 -0
  69. package/dist/server/index.mjs +416 -0
  70. package/dist/server/register.d.ts +5 -0
  71. package/dist/server/routes/index.d.ts +35 -0
  72. package/dist/server/routes/seo.d.ts +16 -0
  73. package/dist/server/routes/settings.d.ts +16 -0
  74. package/dist/server/services/index.d.ts +19 -0
  75. package/dist/server/services/seo.d.ts +12 -0
  76. package/dist/server/services/settings.d.ts +10 -0
  77. package/dist/shared/index.cjs +17 -0
  78. package/dist/shared/index.d.ts +1 -0
  79. package/dist/shared/index.js +17 -0
  80. package/dist/shared/index.mjs +17 -0
  81. package/package.json +100 -3
@@ -0,0 +1,416 @@
1
+ const bootstrap = async ({ strapi }) => {
2
+ const actions = [
3
+ {
4
+ section: "plugins",
5
+ displayName: "Access the SEO plugin",
6
+ uid: "read",
7
+ pluginName: "seo"
8
+ },
9
+ {
10
+ section: "plugins",
11
+ displayName: "Manage SEO plugin settings",
12
+ uid: "settings.update",
13
+ pluginName: "seo"
14
+ }
15
+ ];
16
+ await strapi.admin.services.permission.actionProvider.registerMany(actions);
17
+ };
18
+ const config = {
19
+ default: {},
20
+ validator() {
21
+ }
22
+ };
23
+ const seoController = ({ strapi }) => ({
24
+ findSeoComponent(ctx) {
25
+ ctx.body = strapi.plugin("seo").service("seo").getSeoComponent();
26
+ return ctx.body;
27
+ },
28
+ findContentTypes(ctx) {
29
+ ctx.body = strapi.plugin("seo").service("seo").getContentTypes();
30
+ return ctx.body;
31
+ },
32
+ async createSeoComponent(ctx) {
33
+ const previousWatching = strapi.reload?.isWatching;
34
+ if (strapi.reload) {
35
+ strapi.reload.isWatching = false;
36
+ }
37
+ try {
38
+ const data = await strapi.plugin("seo").service("seo").createSeoComponent();
39
+ if (!data) {
40
+ if (strapi.reload && previousWatching !== void 0) {
41
+ strapi.reload.isWatching = previousWatching;
42
+ }
43
+ ctx.status = 500;
44
+ ctx.body = { error: "Failed to create SEO component" };
45
+ return ctx.body;
46
+ }
47
+ if (typeof strapi.reload === "function") {
48
+ setImmediate(() => strapi.reload());
49
+ }
50
+ ctx.body = data;
51
+ return data;
52
+ } catch (error) {
53
+ if (strapi.reload && previousWatching !== void 0) {
54
+ strapi.reload.isWatching = previousWatching;
55
+ }
56
+ strapi.log?.error?.(String(error));
57
+ if (typeof ctx.throw === "function") {
58
+ ctx.throw(500, error);
59
+ }
60
+ ctx.status = 500;
61
+ ctx.body = { error: "Failed to create SEO component" };
62
+ return ctx.body;
63
+ }
64
+ }
65
+ });
66
+ const isPlainRecord$1 = (value) => Boolean(value) && typeof value === "object" && !Array.isArray(value);
67
+ const settingsController = ({ strapi }) => {
68
+ const getSettingsService = () => strapi.plugin("seo").service("settings");
69
+ const getSettings = async (ctx) => {
70
+ try {
71
+ const result = await getSettingsService().getSettings();
72
+ ctx.body = result;
73
+ return result;
74
+ } catch (err) {
75
+ ctx.throw(500, err);
76
+ }
77
+ };
78
+ const setSettings = async (ctx) => {
79
+ const { body } = ctx.request ?? {};
80
+ if (!isPlainRecord$1(body)) {
81
+ if (typeof ctx.badRequest === "function") {
82
+ return ctx.badRequest("Invalid SEO settings payload");
83
+ }
84
+ return ctx.throw(400, "Invalid SEO settings payload");
85
+ }
86
+ try {
87
+ const settingsService2 = getSettingsService();
88
+ await settingsService2.setSettings(body);
89
+ const updated = await settingsService2.getSettings();
90
+ ctx.body = updated;
91
+ return updated;
92
+ } catch (err) {
93
+ ctx.throw(500, err);
94
+ }
95
+ };
96
+ return {
97
+ getSettings,
98
+ setSettings
99
+ };
100
+ };
101
+ const controllers = {
102
+ seo: seoController,
103
+ settings: settingsController
104
+ };
105
+ const destroy = (_context) => {
106
+ };
107
+ const register = (_context) => {
108
+ };
109
+ const READ_POLICIES = [
110
+ "admin::isAuthenticatedAdmin",
111
+ {
112
+ name: "admin::hasPermissions",
113
+ config: { actions: ["plugin::seo.read"] }
114
+ }
115
+ ];
116
+ const seoRoutes = {
117
+ type: "admin",
118
+ routes: [
119
+ {
120
+ method: "GET",
121
+ path: "/component",
122
+ handler: "seo.findSeoComponent",
123
+ config: {
124
+ policies: READ_POLICIES
125
+ }
126
+ },
127
+ {
128
+ method: "POST",
129
+ path: "/component",
130
+ handler: "seo.createSeoComponent",
131
+ config: {
132
+ policies: READ_POLICIES
133
+ }
134
+ },
135
+ {
136
+ method: "GET",
137
+ path: "/content-types",
138
+ handler: "seo.findContentTypes",
139
+ config: {
140
+ policies: READ_POLICIES
141
+ }
142
+ }
143
+ ]
144
+ };
145
+ const SETTINGS_POLICIES = [
146
+ "admin::isAuthenticatedAdmin",
147
+ {
148
+ name: "admin::hasPermissions",
149
+ config: { actions: ["plugin::seo.read"] }
150
+ }
151
+ ];
152
+ const settingsRoutes = {
153
+ type: "admin",
154
+ routes: [
155
+ {
156
+ method: "GET",
157
+ path: "/settings",
158
+ handler: "settings.getSettings",
159
+ config: { policies: SETTINGS_POLICIES }
160
+ },
161
+ {
162
+ method: "POST",
163
+ path: "/settings",
164
+ handler: "settings.setSettings",
165
+ config: { policies: SETTINGS_POLICIES }
166
+ }
167
+ ]
168
+ };
169
+ const routes = {
170
+ seo: seoRoutes,
171
+ settings: settingsRoutes
172
+ };
173
+ const collectionName$1 = "components_shared_open_graphs";
174
+ const info$1 = { "displayName": "openGraph", "icon": "project-diagram" };
175
+ const options$1 = {};
176
+ const attributes$1 = { "ogTitle": { "type": "string", "required": true, "maxLength": 70 }, "ogDescription": { "type": "string", "maxLength": 200, "required": true }, "ogImage": { "allowedTypes": ["images"], "type": "media", "multiple": false }, "ogUrl": { "type": "string", "required": false }, "ogType": { "type": "string", "required": false } };
177
+ const openGraph = {
178
+ collectionName: collectionName$1,
179
+ info: info$1,
180
+ options: options$1,
181
+ attributes: attributes$1
182
+ };
183
+ const collectionName = "components_shared_seos";
184
+ const info = { "displayName": "seo", "icon": "search" };
185
+ const options = {};
186
+ const attributes = { "metaTitle": { "required": true, "type": "string", "maxLength": 60 }, "metaDescription": { "type": "string", "required": true, "maxLength": 160, "minLength": 50 }, "metaImage": { "type": "media", "multiple": false, "required": false, "allowedTypes": ["images"] }, "openGraph": { "type": "component", "repeatable": false, "component": "shared.open-graph" }, "keywords": { "type": "text", "regex": "[^,]+" }, "metaRobots": { "type": "string", "regex": "[^,]+" }, "metaViewport": { "type": "string" }, "canonicalURL": { "type": "string" }, "structuredData": { "type": "json" } };
187
+ const seoContent = {
188
+ collectionName,
189
+ info,
190
+ options,
191
+ attributes
192
+ };
193
+ const BLACKLISTED_PLUGINS = [
194
+ "upload",
195
+ "i18n",
196
+ "users-permissions",
197
+ "content-releases",
198
+ "review-workflows",
199
+ "email",
200
+ "seo",
201
+ "email-designer-5"
202
+ ];
203
+ const isContentManagerVisible = (ct) => {
204
+ const pluginOptions = ct.__schema__?.pluginOptions ?? ct.pluginOptions;
205
+ return pluginOptions?.["content-manager"]?.visible !== false;
206
+ };
207
+ const shouldIncludeContentType = (name, ct) => {
208
+ if (name.startsWith("api::")) return true;
209
+ return name.startsWith("plugin::") && isContentManagerVisible(ct);
210
+ };
211
+ const resolveGlobalId = (name, ct) => {
212
+ if (ct.globalId) return ct.globalId;
213
+ return ct.info?.displayName ?? name;
214
+ };
215
+ const hasSeoComponentAttribute = (ct) => {
216
+ const seoAttr = ct.attributes?.seo;
217
+ return typeof seoAttr?.component === "string" && seoAttr.component.trim().length > 0;
218
+ };
219
+ const buildContentTypeSeoItem = (name, ct) => ({
220
+ seo: hasSeoComponentAttribute(ct),
221
+ uid: ct.uid ?? name,
222
+ kind: ct.kind ?? "collectionType",
223
+ globalId: resolveGlobalId(name, ct),
224
+ attributes: ct.attributes ?? {}
225
+ });
226
+ const isAllowedPluginContentType = (name) => {
227
+ const pluginPrefix = name.replace("plugin::", "").split(".")[0];
228
+ return !BLACKLISTED_PLUGINS.includes(pluginPrefix);
229
+ };
230
+ const seoService = ({ strapi }) => ({
231
+ getSeoComponent() {
232
+ const seoComponent = strapi.components?.["shared.seo"];
233
+ return seoComponent ? { attributes: seoComponent.attributes, category: seoComponent.category } : null;
234
+ },
235
+ getContentTypes() {
236
+ const contentTypes = strapi.contentTypes || {};
237
+ const keys = Object.keys(contentTypes);
238
+ const collectionTypes = [];
239
+ const singleTypes = [];
240
+ const plugins = [];
241
+ keys.forEach((name) => {
242
+ const ct = contentTypes[name];
243
+ if (!ct || !shouldIncludeContentType(name, ct)) return;
244
+ const object = buildContentTypeSeoItem(name, ct);
245
+ if (name.startsWith("api::")) {
246
+ const targetList = ct.kind === "collectionType" ? collectionTypes : singleTypes;
247
+ targetList.push(object);
248
+ } else if (isAllowedPluginContentType(name)) {
249
+ plugins.push(object);
250
+ }
251
+ });
252
+ return { collectionTypes, singleTypes, plugins };
253
+ },
254
+ async createSeoComponent() {
255
+ const seoComponent = await this.getSeoComponent();
256
+ if (seoComponent) {
257
+ return seoComponent;
258
+ }
259
+ if (!openGraph || !seoContent) {
260
+ return null;
261
+ }
262
+ const hasOpenGraph = Boolean(strapi.components?.["shared.open-graph"]);
263
+ try {
264
+ return await strapi.plugin("content-type-builder").services.components.createComponent({
265
+ component: {
266
+ category: "shared",
267
+ displayName: seoContent.info.displayName,
268
+ icon: seoContent.info.icon,
269
+ attributes: seoContent.attributes
270
+ },
271
+ components: hasOpenGraph ? [] : [
272
+ {
273
+ tmpUID: "shared.open-graph",
274
+ category: "shared",
275
+ displayName: openGraph.info.displayName,
276
+ icon: openGraph.info.icon,
277
+ attributes: openGraph.attributes
278
+ }
279
+ ]
280
+ });
281
+ } catch (error) {
282
+ strapi.log?.error?.(String(error));
283
+ return null;
284
+ }
285
+ }
286
+ });
287
+ const DEFAULT_SEO_CHECKS = {
288
+ metaTitle: true,
289
+ metaDescription: true,
290
+ metaRobots: true,
291
+ openGraph: true,
292
+ wordCount: true,
293
+ canonicalUrl: true,
294
+ keywordDensity: true,
295
+ structuredData: true,
296
+ alternativeText: true,
297
+ lastUpdatedAt: true
298
+ };
299
+ const FORBIDDEN_KEYS = /* @__PURE__ */ new Set(["__proto__", "prototype", "constructor"]);
300
+ const SEO_CHECK_KEYS = Object.keys(DEFAULT_SEO_CHECKS);
301
+ const isPlainRecord = (value) => Boolean(value) && typeof value === "object" && !Array.isArray(value);
302
+ const sanitizeSeoChecks = (raw) => {
303
+ const source = isPlainRecord(raw) ? raw : {};
304
+ const checks = { ...DEFAULT_SEO_CHECKS };
305
+ SEO_CHECK_KEYS.forEach((key) => {
306
+ if (typeof source[key] === "boolean") {
307
+ checks[key] = source[key];
308
+ }
309
+ });
310
+ return checks;
311
+ };
312
+ const sanitizeSeoSettingsMap = (raw) => {
313
+ const result = {};
314
+ if (!isPlainRecord(raw)) {
315
+ return result;
316
+ }
317
+ Object.keys(raw).forEach((key) => {
318
+ const trimmedKey = key.trim();
319
+ if (!trimmedKey || trimmedKey.length > 128 || FORBIDDEN_KEYS.has(trimmedKey)) {
320
+ return;
321
+ }
322
+ const entry = raw[key];
323
+ if (!isPlainRecord(entry)) {
324
+ return;
325
+ }
326
+ const fallbackName = trimmedKey.split(".").pop() || trimmedKey;
327
+ const rawName = entry.collectionName;
328
+ const collectionName2 = typeof rawName === "string" && rawName.trim().length > 0 ? rawName.trim().slice(0, 128) : fallbackName;
329
+ result[trimmedKey] = {
330
+ collectionName: collectionName2,
331
+ seoChecks: sanitizeSeoChecks(entry.seoChecks)
332
+ };
333
+ });
334
+ return result;
335
+ };
336
+ const settingsService = ({ strapi }) => {
337
+ const getPluginStore = () => {
338
+ return strapi.store({
339
+ environment: "",
340
+ type: "plugin",
341
+ name: "seo"
342
+ });
343
+ };
344
+ const createDefaultConfig = async () => {
345
+ const pluginStore = getPluginStore();
346
+ const newContentTypes = {};
347
+ const keys = Object.keys(strapi.contentTypes || {});
348
+ keys.forEach((key) => {
349
+ if (key.includes("api::") || key.includes("plugin::")) {
350
+ newContentTypes[key] = {
351
+ collectionName: key.split(".").pop() || key,
352
+ seoChecks: { ...DEFAULT_SEO_CHECKS }
353
+ };
354
+ }
355
+ });
356
+ await pluginStore.set({ key: "settings", value: newContentTypes });
357
+ return pluginStore.get({ key: "settings" });
358
+ };
359
+ const getSettings = async () => {
360
+ const pluginStore = getPluginStore();
361
+ const stored = await pluginStore.get({ key: "settings" });
362
+ if (!isPlainRecord(stored)) {
363
+ return createDefaultConfig();
364
+ }
365
+ const config2 = sanitizeSeoSettingsMap(stored);
366
+ let updated = false;
367
+ const keys = Object.keys(strapi.contentTypes || {});
368
+ keys.forEach((key) => {
369
+ if ((key.includes("api::") || key.includes("plugin::")) && !Object.prototype.hasOwnProperty.call(config2, key)) {
370
+ config2[key] = {
371
+ collectionName: key.split(".").pop() || key,
372
+ seoChecks: { ...DEFAULT_SEO_CHECKS }
373
+ };
374
+ updated = true;
375
+ }
376
+ });
377
+ if (updated) {
378
+ await pluginStore.set({ key: "settings", value: config2 });
379
+ }
380
+ return config2;
381
+ };
382
+ const setSettings = async (data) => {
383
+ const pluginStore = getPluginStore();
384
+ const sanitized = sanitizeSeoSettingsMap(data);
385
+ const existingRaw = await pluginStore.get({
386
+ key: "settings"
387
+ });
388
+ const existing = isPlainRecord(existingRaw) ? sanitizeSeoSettingsMap(existingRaw) : {};
389
+ const merged = {
390
+ ...existing,
391
+ ...sanitized
392
+ };
393
+ await pluginStore.set({ key: "settings", value: merged });
394
+ return pluginStore.get({ key: "settings" });
395
+ };
396
+ return {
397
+ getSettings,
398
+ setSettings
399
+ };
400
+ };
401
+ const services = {
402
+ seo: seoService,
403
+ settings: settingsService
404
+ };
405
+ const index = {
406
+ register,
407
+ bootstrap,
408
+ destroy,
409
+ config,
410
+ controllers,
411
+ routes,
412
+ services
413
+ };
414
+ export {
415
+ index as default
416
+ };
@@ -0,0 +1,5 @@
1
+ import { Core } from '@strapi/strapi';
2
+ declare const register: (_context: {
3
+ strapi: Core.Strapi;
4
+ }) => void;
5
+ export default register;
@@ -0,0 +1,35 @@
1
+ declare const _default: {
2
+ seo: {
3
+ type: string;
4
+ routes: {
5
+ method: string;
6
+ path: string;
7
+ handler: string;
8
+ config: {
9
+ policies: (string | {
10
+ name: string;
11
+ config: {
12
+ actions: string[];
13
+ };
14
+ })[];
15
+ };
16
+ }[];
17
+ };
18
+ settings: {
19
+ type: string;
20
+ routes: {
21
+ method: string;
22
+ path: string;
23
+ handler: string;
24
+ config: {
25
+ policies: (string | {
26
+ name: string;
27
+ config: {
28
+ actions: string[];
29
+ };
30
+ })[];
31
+ };
32
+ }[];
33
+ };
34
+ };
35
+ export default _default;
@@ -0,0 +1,16 @@
1
+ export declare const seoRoutes: {
2
+ type: string;
3
+ routes: {
4
+ method: string;
5
+ path: string;
6
+ handler: string;
7
+ config: {
8
+ policies: (string | {
9
+ name: string;
10
+ config: {
11
+ actions: string[];
12
+ };
13
+ })[];
14
+ };
15
+ }[];
16
+ };
@@ -0,0 +1,16 @@
1
+ export declare const settingsRoutes: {
2
+ type: string;
3
+ routes: {
4
+ method: string;
5
+ path: string;
6
+ handler: string;
7
+ config: {
8
+ policies: (string | {
9
+ name: string;
10
+ config: {
11
+ actions: string[];
12
+ };
13
+ })[];
14
+ };
15
+ }[];
16
+ };
@@ -0,0 +1,19 @@
1
+ declare const _default: {
2
+ seo: ({ strapi }: {
3
+ strapi: import("@strapi/strapi").Core.Strapi;
4
+ }) => {
5
+ getSeoComponent(): {
6
+ attributes: Record<string, unknown> | undefined;
7
+ category: string | undefined;
8
+ } | null;
9
+ getContentTypes(): import('../../../shared').ContentTypesResponse;
10
+ createSeoComponent(): Promise<unknown>;
11
+ };
12
+ settings: ({ strapi }: {
13
+ strapi: import("@strapi/strapi").Core.Strapi;
14
+ }) => {
15
+ getSettings: () => Promise<import('../../../shared').SeoSettingsMap>;
16
+ setSettings: (data: import('../../../shared').SeoSettingsMap) => Promise<import('../../../shared').SeoSettingsMap>;
17
+ };
18
+ };
19
+ export default _default;
@@ -0,0 +1,12 @@
1
+ import { Core } from '@strapi/strapi';
2
+ import { ContentTypesResponse } from '../../../shared';
3
+ export declare const seoService: ({ strapi }: {
4
+ strapi: Core.Strapi;
5
+ }) => {
6
+ getSeoComponent(): {
7
+ attributes: Record<string, unknown> | undefined;
8
+ category: string | undefined;
9
+ } | null;
10
+ getContentTypes(): ContentTypesResponse;
11
+ createSeoComponent(): Promise<unknown>;
12
+ };
@@ -0,0 +1,10 @@
1
+ import { Core } from '@strapi/strapi';
2
+ import { SeoChecksConfig, SeoSettingsMap } from '../../../shared';
3
+ export declare const sanitizeSeoChecks: (raw: unknown) => SeoChecksConfig;
4
+ export declare const sanitizeSeoSettingsMap: (raw: unknown) => SeoSettingsMap;
5
+ export declare const settingsService: ({ strapi }: {
6
+ strapi: Core.Strapi;
7
+ }) => {
8
+ getSettings: () => Promise<SeoSettingsMap>;
9
+ setSettings: (data: SeoSettingsMap) => Promise<SeoSettingsMap>;
10
+ };
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const PLUGIN_ID = "seo";
4
+ const DEFAULT_SEO_CHECKS = {
5
+ metaTitle: true,
6
+ metaDescription: true,
7
+ metaRobots: true,
8
+ openGraph: true,
9
+ wordCount: true,
10
+ canonicalUrl: true,
11
+ keywordDensity: true,
12
+ structuredData: true,
13
+ alternativeText: true,
14
+ lastUpdatedAt: true
15
+ };
16
+ exports.DEFAULT_SEO_CHECKS = DEFAULT_SEO_CHECKS;
17
+ exports.PLUGIN_ID = PLUGIN_ID;
@@ -0,0 +1 @@
1
+ export * from '../../shared/index.js';
@@ -0,0 +1,17 @@
1
+ const PLUGIN_ID = "seo";
2
+ const DEFAULT_SEO_CHECKS = {
3
+ metaTitle: true,
4
+ metaDescription: true,
5
+ metaRobots: true,
6
+ openGraph: true,
7
+ wordCount: true,
8
+ canonicalUrl: true,
9
+ keywordDensity: true,
10
+ structuredData: true,
11
+ alternativeText: true,
12
+ lastUpdatedAt: true
13
+ };
14
+ export {
15
+ DEFAULT_SEO_CHECKS,
16
+ PLUGIN_ID
17
+ };
@@ -0,0 +1,17 @@
1
+ const PLUGIN_ID = "seo";
2
+ const DEFAULT_SEO_CHECKS = {
3
+ metaTitle: true,
4
+ metaDescription: true,
5
+ metaRobots: true,
6
+ openGraph: true,
7
+ wordCount: true,
8
+ canonicalUrl: true,
9
+ keywordDensity: true,
10
+ structuredData: true,
11
+ alternativeText: true,
12
+ lastUpdatedAt: true
13
+ };
14
+ export {
15
+ DEFAULT_SEO_CHECKS,
16
+ PLUGIN_ID
17
+ };