strapi-plugin-blogseo 1.1.0 → 1.2.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.
@@ -78,6 +78,7 @@ const routes = {
78
78
  };
79
79
  const PLUGIN_ID = "blogseo";
80
80
  const STRAPI_TOKEN_NAME = "BlogSEO";
81
+ const PENDING_TOKEN_NAME = "BlogSEO (connecting)";
81
82
  const DEFAULT_BLOGSEO_API_URL = "https://app.blogseo.io";
82
83
  const service = ({ strapi }) => {
83
84
  const store = () => strapi.store({ type: "plugin", name: PLUGIN_ID });
@@ -115,6 +116,24 @@ const service = ({ strapi }) => {
115
116
  "strapi_stage",
116
117
  "strapi_assignee"
117
118
  ]);
119
+ const MAX_COMPONENT_DEPTH = 3;
120
+ const expandAttribute = (attribute, depth, visited) => {
121
+ if (attribute.type !== "component" || typeof attribute.component !== "string") return attribute;
122
+ const componentUid = attribute.component;
123
+ const componentSchema = strapi.components[componentUid];
124
+ const canExpand = componentSchema && depth < MAX_COMPONENT_DEPTH && !visited.has(componentUid);
125
+ const childAttributes = canExpand ? expandAttributes(componentSchema.attributes ?? {}, depth + 1, new Set(visited).add(componentUid)) : {};
126
+ return {
127
+ type: "component",
128
+ required: attribute.required,
129
+ component: { repeatable: attribute.repeatable ?? false, attributes: childAttributes }
130
+ };
131
+ };
132
+ const expandAttributes = (attributes, depth, visited) => Object.fromEntries(
133
+ Object.entries(attributes).filter(
134
+ ([name, attribute]) => !systemAttributeNames.has(name) && !attribute.private
135
+ ).map(([name, attribute]) => [name, expandAttribute(attribute, depth, visited)])
136
+ );
118
137
  return Object.entries(strapi.contentTypes).filter(([uid, schema]) => uid.startsWith("api::") && schema.kind === "collectionType").map(([uid, schema]) => ({
119
138
  uid,
120
139
  apiID: schema.info?.singularName ?? uid.split(".").pop() ?? uid,
@@ -125,11 +144,7 @@ const service = ({ strapi }) => {
125
144
  kind: schema.kind,
126
145
  draftAndPublish: schema.options?.draftAndPublish ?? false,
127
146
  pluginOptions: schema.pluginOptions ?? {},
128
- attributes: Object.fromEntries(
129
- Object.entries(schema.attributes ?? {}).filter(
130
- ([name, attribute]) => !systemAttributeNames.has(name) && !attribute.private
131
- )
132
- )
147
+ attributes: expandAttributes(schema.attributes ?? {}, 0, /* @__PURE__ */ new Set())
133
148
  }
134
149
  }));
135
150
  },
@@ -139,11 +154,10 @@ const service = ({ strapi }) => {
139
154
  serverUrl
140
155
  }) {
141
156
  const previous = await getState();
142
- if (previous.strapiTokenId) await apiTokens().revoke(previous.strapiTokenId).catch(() => null);
143
- const leftover = await apiTokens().getByName(STRAPI_TOKEN_NAME);
144
- if (leftover) await apiTokens().revoke(leftover.id).catch(() => null);
157
+ const pendingLeftover = await apiTokens().getByName(PENDING_TOKEN_NAME);
158
+ if (pendingLeftover) await apiTokens().revoke(pendingLeftover.id).catch(() => null);
145
159
  const created = await apiTokens().create({
146
- name: STRAPI_TOKEN_NAME,
160
+ name: PENDING_TOKEN_NAME,
147
161
  description: "Token used by BlogSEO to publish articles into this Strapi instance.",
148
162
  type: "full-access",
149
163
  lifespan: null
@@ -170,6 +184,11 @@ const service = ({ strapi }) => {
170
184
  await apiTokens().revoke(created.id).catch(() => null);
171
185
  throw new Error(json.error ?? "BlogSEO rejected the connection. Double-check your connection key.");
172
186
  }
187
+ if (previous.strapiTokenId) await apiTokens().revoke(previous.strapiTokenId).catch(() => null);
188
+ const supersededToken = await apiTokens().getByName(STRAPI_TOKEN_NAME).catch(() => null);
189
+ if (supersededToken && supersededToken.id !== created.id)
190
+ await apiTokens().revoke(supersededToken.id).catch(() => null);
191
+ await apiTokens().update(created.id, { name: STRAPI_TOKEN_NAME }).catch(() => null);
173
192
  const nextState = {
174
193
  connected: true,
175
194
  apiKey,
@@ -76,6 +76,7 @@ const routes = {
76
76
  };
77
77
  const PLUGIN_ID = "blogseo";
78
78
  const STRAPI_TOKEN_NAME = "BlogSEO";
79
+ const PENDING_TOKEN_NAME = "BlogSEO (connecting)";
79
80
  const DEFAULT_BLOGSEO_API_URL = "https://app.blogseo.io";
80
81
  const service = ({ strapi }) => {
81
82
  const store = () => strapi.store({ type: "plugin", name: PLUGIN_ID });
@@ -113,6 +114,24 @@ const service = ({ strapi }) => {
113
114
  "strapi_stage",
114
115
  "strapi_assignee"
115
116
  ]);
117
+ const MAX_COMPONENT_DEPTH = 3;
118
+ const expandAttribute = (attribute, depth, visited) => {
119
+ if (attribute.type !== "component" || typeof attribute.component !== "string") return attribute;
120
+ const componentUid = attribute.component;
121
+ const componentSchema = strapi.components[componentUid];
122
+ const canExpand = componentSchema && depth < MAX_COMPONENT_DEPTH && !visited.has(componentUid);
123
+ const childAttributes = canExpand ? expandAttributes(componentSchema.attributes ?? {}, depth + 1, new Set(visited).add(componentUid)) : {};
124
+ return {
125
+ type: "component",
126
+ required: attribute.required,
127
+ component: { repeatable: attribute.repeatable ?? false, attributes: childAttributes }
128
+ };
129
+ };
130
+ const expandAttributes = (attributes, depth, visited) => Object.fromEntries(
131
+ Object.entries(attributes).filter(
132
+ ([name, attribute]) => !systemAttributeNames.has(name) && !attribute.private
133
+ ).map(([name, attribute]) => [name, expandAttribute(attribute, depth, visited)])
134
+ );
116
135
  return Object.entries(strapi.contentTypes).filter(([uid, schema]) => uid.startsWith("api::") && schema.kind === "collectionType").map(([uid, schema]) => ({
117
136
  uid,
118
137
  apiID: schema.info?.singularName ?? uid.split(".").pop() ?? uid,
@@ -123,11 +142,7 @@ const service = ({ strapi }) => {
123
142
  kind: schema.kind,
124
143
  draftAndPublish: schema.options?.draftAndPublish ?? false,
125
144
  pluginOptions: schema.pluginOptions ?? {},
126
- attributes: Object.fromEntries(
127
- Object.entries(schema.attributes ?? {}).filter(
128
- ([name, attribute]) => !systemAttributeNames.has(name) && !attribute.private
129
- )
130
- )
145
+ attributes: expandAttributes(schema.attributes ?? {}, 0, /* @__PURE__ */ new Set())
131
146
  }
132
147
  }));
133
148
  },
@@ -137,11 +152,10 @@ const service = ({ strapi }) => {
137
152
  serverUrl
138
153
  }) {
139
154
  const previous = await getState();
140
- if (previous.strapiTokenId) await apiTokens().revoke(previous.strapiTokenId).catch(() => null);
141
- const leftover = await apiTokens().getByName(STRAPI_TOKEN_NAME);
142
- if (leftover) await apiTokens().revoke(leftover.id).catch(() => null);
155
+ const pendingLeftover = await apiTokens().getByName(PENDING_TOKEN_NAME);
156
+ if (pendingLeftover) await apiTokens().revoke(pendingLeftover.id).catch(() => null);
143
157
  const created = await apiTokens().create({
144
- name: STRAPI_TOKEN_NAME,
158
+ name: PENDING_TOKEN_NAME,
145
159
  description: "Token used by BlogSEO to publish articles into this Strapi instance.",
146
160
  type: "full-access",
147
161
  lifespan: null
@@ -168,6 +182,11 @@ const service = ({ strapi }) => {
168
182
  await apiTokens().revoke(created.id).catch(() => null);
169
183
  throw new Error(json.error ?? "BlogSEO rejected the connection. Double-check your connection key.");
170
184
  }
185
+ if (previous.strapiTokenId) await apiTokens().revoke(previous.strapiTokenId).catch(() => null);
186
+ const supersededToken = await apiTokens().getByName(STRAPI_TOKEN_NAME).catch(() => null);
187
+ if (supersededToken && supersededToken.id !== created.id)
188
+ await apiTokens().revoke(supersededToken.id).catch(() => null);
189
+ await apiTokens().update(created.id, { name: STRAPI_TOKEN_NAME }).catch(() => null);
171
190
  const nextState = {
172
191
  connected: true,
173
192
  apiKey,
@@ -73,9 +73,7 @@ declare const _default: {
73
73
  kind: any;
74
74
  draftAndPublish: any;
75
75
  pluginOptions: any;
76
- attributes: {
77
- [k: string]: unknown;
78
- };
76
+ attributes: Record<string, unknown>;
79
77
  };
80
78
  }[];
81
79
  connect({ apiKey, pluralApiId, serverUrl, }: {
@@ -22,9 +22,7 @@ declare const service: ({ strapi }: {
22
22
  kind: any;
23
23
  draftAndPublish: any;
24
24
  pluginOptions: any;
25
- attributes: {
26
- [k: string]: unknown;
27
- };
25
+ attributes: Record<string, unknown>;
28
26
  };
29
27
  }[];
30
28
  connect({ apiKey, pluralApiId, serverUrl, }: {
@@ -22,9 +22,7 @@ declare const _default: {
22
22
  kind: any;
23
23
  draftAndPublish: any;
24
24
  pluginOptions: any;
25
- attributes: {
26
- [k: string]: unknown;
27
- };
25
+ attributes: Record<string, unknown>;
28
26
  };
29
27
  }[];
30
28
  connect({ apiKey, pluralApiId, serverUrl, }: {
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "1.1.0",
2
+ "version": "1.2.0",
3
3
  "keywords": [
4
4
  "strapi",
5
5
  "strapi-plugin",