@qkix/strapi-plugin-better-blocks 0.23.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/LICENSE +21 -0
- package/README.md +795 -0
- package/dist/_chunks/en-BcPniuRQ.js +1 -0
- package/dist/_chunks/en-DYxpcVy9.mjs +4 -0
- package/dist/admin/index.js +1933 -0
- package/dist/admin/index.mjs +17091 -0
- package/dist/admin/src/components/BlocksInput/Blocks/Audio.d.ts +6 -0
- package/dist/admin/src/components/BlocksInput/Blocks/AudioEditorModal.d.ts +21 -0
- package/dist/admin/src/components/BlocksInput/Blocks/Button.d.ts +11 -0
- package/dist/admin/src/components/BlocksInput/Blocks/ButtonEditorModal.d.ts +17 -0
- package/dist/admin/src/components/BlocksInput/Blocks/Callout.d.ts +21 -0
- package/dist/admin/src/components/BlocksInput/Blocks/Code.d.ts +18 -0
- package/dist/admin/src/components/BlocksInput/Blocks/Details.d.ts +12 -0
- package/dist/admin/src/components/BlocksInput/Blocks/Diagram.d.ts +15 -0
- package/dist/admin/src/components/BlocksInput/Blocks/Embed.d.ts +22 -0
- package/dist/admin/src/components/BlocksInput/Blocks/EmbedEditorModal.d.ts +27 -0
- package/dist/admin/src/components/BlocksInput/Blocks/Heading.d.ts +14 -0
- package/dist/admin/src/components/BlocksInput/Blocks/HorizontalLine.d.ts +10 -0
- package/dist/admin/src/components/BlocksInput/Blocks/Image.d.ts +5 -0
- package/dist/admin/src/components/BlocksInput/Blocks/Link.d.ts +3 -0
- package/dist/admin/src/components/BlocksInput/Blocks/List.d.ts +3 -0
- package/dist/admin/src/components/BlocksInput/Blocks/Math.d.ts +17 -0
- package/dist/admin/src/components/BlocksInput/Blocks/MediaEmbed.d.ts +7 -0
- package/dist/admin/src/components/BlocksInput/Blocks/Paragraph.d.ts +3 -0
- package/dist/admin/src/components/BlocksInput/Blocks/Quote.d.ts +3 -0
- package/dist/admin/src/components/BlocksInput/Blocks/SocialEmbed.d.ts +8 -0
- package/dist/admin/src/components/BlocksInput/Blocks/SocialEmbedEditorModal.d.ts +41 -0
- package/dist/admin/src/components/BlocksInput/Blocks/SourceEditorModal.d.ts +19 -0
- package/dist/admin/src/components/BlocksInput/Blocks/Table.d.ts +14 -0
- package/dist/admin/src/components/BlocksInput/Blocks/TableGridPicker.d.ts +20 -0
- package/dist/admin/src/components/BlocksInput/Blocks/TableIcons.d.ts +31 -0
- package/dist/admin/src/components/BlocksInput/Blocks/TableToolbar.d.ts +14 -0
- package/dist/admin/src/components/BlocksInput/Blocks/Video.d.ts +6 -0
- package/dist/admin/src/components/BlocksInput/Blocks/VideoEditorModal.d.ts +29 -0
- package/dist/admin/src/components/BlocksInput/Blocks/embedProviders.d.ts +43 -0
- package/dist/admin/src/components/BlocksInput/Blocks/muxClient.d.ts +40 -0
- package/dist/admin/src/components/BlocksInput/Blocks/socialFrame.d.ts +13 -0
- package/dist/admin/src/components/BlocksInput/Blocks/tableGrid.d.ts +90 -0
- package/dist/admin/src/components/BlocksInput/Blocks/tableOperations.d.ts +124 -0
- package/dist/admin/src/components/BlocksInput/Blocks/videoProviders.d.ts +37 -0
- package/dist/admin/src/components/BlocksInput/BlocksContent.d.ts +7 -0
- package/dist/admin/src/components/BlocksInput/BlocksEditor.d.ts +71 -0
- package/dist/admin/src/components/BlocksInput/BlocksToolbar.d.ts +27 -0
- package/dist/admin/src/components/BlocksInput/EditorLayout.d.ts +10 -0
- package/dist/admin/src/components/BlocksInput/EmojiPicker.d.ts +5 -0
- package/dist/admin/src/components/BlocksInput/FindReplace.d.ts +11 -0
- package/dist/admin/src/components/BlocksInput/FloatingSelectionToolbar.d.ts +11 -0
- package/dist/admin/src/components/BlocksInput/FontModifiersIcons.d.ts +32 -0
- package/dist/admin/src/components/BlocksInput/InlineColorPicker.d.ts +3 -0
- package/dist/admin/src/components/BlocksInput/MenuScrollbar.d.ts +30 -0
- package/dist/admin/src/components/BlocksInput/Modifiers.d.ts +16 -0
- package/dist/admin/src/components/BlocksInput/SlashCommands.d.ts +3 -0
- package/dist/admin/src/components/BlocksInput/SpecialCharPicker.d.ts +5 -0
- package/dist/admin/src/components/BlocksInput/WordCount.d.ts +3 -0
- package/dist/admin/src/components/BlocksInput/plugins/withAutoTransform.d.ts +3 -0
- package/dist/admin/src/components/BlocksInput/plugins/withLinks.d.ts +8 -0
- package/dist/admin/src/components/BlocksInput/plugins/withMarkdownPaste.d.ts +3 -0
- package/dist/admin/src/components/BlocksInput/plugins/withStrapiSchema.d.ts +6 -0
- package/dist/admin/src/components/BlocksInput/utils/constants.d.ts +13 -0
- package/dist/admin/src/components/BlocksInput/utils/conversions.d.ts +14 -0
- package/dist/admin/src/components/BlocksInput/utils/enterKey.d.ts +6 -0
- package/dist/admin/src/components/BlocksInput/utils/links.d.ts +12 -0
- package/dist/admin/src/components/BlocksInput/utils/optionsDefaults.d.ts +28 -0
- package/dist/admin/src/components/BlocksInput/utils/optionsParser.d.ts +34 -0
- package/dist/admin/src/components/BlocksInput/utils/parseMarkdownToSlate.d.ts +2 -0
- package/dist/admin/src/components/BlocksInput/utils/prefixFileUrlWithBackendUrl.d.ts +8 -0
- package/dist/admin/src/components/BlocksInput/utils/shiki.d.ts +29 -0
- package/dist/admin/src/components/BlocksInput/utils/shortcuts.d.ts +25 -0
- package/dist/admin/src/components/BlocksInput/utils/types.d.ts +404 -0
- package/dist/admin/src/components/Initializer.d.ts +5 -0
- package/dist/admin/src/components/Input.d.ts +45 -0
- package/dist/admin/src/components/PluginIcon.d.ts +3 -0
- package/dist/admin/src/hooks/useDragAndDrop.d.ts +51 -0
- package/dist/admin/src/hooks/useKeyboardDragAndDrop.d.ts +14 -0
- package/dist/admin/src/index.d.ts +10 -0
- package/dist/admin/src/pages/App.d.ts +3 -0
- package/dist/admin/src/pages/HomePage.d.ts +3 -0
- package/dist/admin/src/pluginId.d.ts +1 -0
- package/dist/admin/src/utils/getTranslation.d.ts +2 -0
- package/dist/server/index.js +1 -0
- package/dist/server/index.mjs +393 -0
- package/dist/server/src/bootstrap.d.ts +5 -0
- package/dist/server/src/config/index.d.ts +94 -0
- package/dist/server/src/content-types/index.d.ts +2 -0
- package/dist/server/src/controllers/controller.d.ts +12 -0
- package/dist/server/src/controllers/index.d.ts +14 -0
- package/dist/server/src/controllers/oembed.d.ts +12 -0
- package/dist/server/src/destroy.d.ts +5 -0
- package/dist/server/src/index.d.ts +125 -0
- package/dist/server/src/middlewares/index.d.ts +2 -0
- package/dist/server/src/policies/index.d.ts +2 -0
- package/dist/server/src/register.d.ts +5 -0
- package/dist/server/src/routes/admin.d.ts +9 -0
- package/dist/server/src/routes/content-api.d.ts +9 -0
- package/dist/server/src/routes/index.d.ts +25 -0
- package/dist/server/src/services/index.d.ts +14 -0
- package/dist/server/src/services/oembed.d.ts +27 -0
- package/dist/server/src/services/service.d.ts +7 -0
- package/package.json +131 -0
|
@@ -0,0 +1,393 @@
|
|
|
1
|
+
const g = ({ strapi: t }) => {
|
|
2
|
+
}, k = ({ strapi: t }) => {
|
|
3
|
+
}, y = ({ strapi: t }) => {
|
|
4
|
+
t.customFields.register({
|
|
5
|
+
name: "better-blocks",
|
|
6
|
+
plugin: "better-blocks",
|
|
7
|
+
type: "json",
|
|
8
|
+
inputSize: {
|
|
9
|
+
default: 12,
|
|
10
|
+
isResizable: !1
|
|
11
|
+
}
|
|
12
|
+
});
|
|
13
|
+
}, w = {
|
|
14
|
+
default: {
|
|
15
|
+
/**
|
|
16
|
+
* Defaults for the collapsible Details / Summary block.
|
|
17
|
+
* Override in the consuming app via config/plugins.{js,ts}:
|
|
18
|
+
*
|
|
19
|
+
* 'better-blocks': {
|
|
20
|
+
* enabled: true,
|
|
21
|
+
* config: {
|
|
22
|
+
* details: {
|
|
23
|
+
* defaultSummary: 'Show more',
|
|
24
|
+
* style: 'custom', // 'github' | 'custom'
|
|
25
|
+
* },
|
|
26
|
+
* },
|
|
27
|
+
* }
|
|
28
|
+
*/
|
|
29
|
+
details: {
|
|
30
|
+
defaultSummary: "Click to expand",
|
|
31
|
+
style: "github"
|
|
32
|
+
},
|
|
33
|
+
/**
|
|
34
|
+
* Defaults for the WordPress-style Button block. `defaultStyle` is applied to
|
|
35
|
+
* a freshly inserted button; authors can then override it per-button.
|
|
36
|
+
* `presets` are brand variants offered in the editor's "Style preset" picker;
|
|
37
|
+
* override any of them to match your design system.
|
|
38
|
+
*/
|
|
39
|
+
button: {
|
|
40
|
+
defaultStyle: {
|
|
41
|
+
backgroundColor: "#4945ff",
|
|
42
|
+
textColor: "#ffffff",
|
|
43
|
+
borderRadius: "4px",
|
|
44
|
+
padding: "12px 24px",
|
|
45
|
+
fontSize: "16px",
|
|
46
|
+
fontWeight: "600"
|
|
47
|
+
},
|
|
48
|
+
presets: {
|
|
49
|
+
primary: {
|
|
50
|
+
backgroundColor: "#4945ff",
|
|
51
|
+
textColor: "#ffffff",
|
|
52
|
+
border: "none"
|
|
53
|
+
},
|
|
54
|
+
secondary: {
|
|
55
|
+
backgroundColor: "#dcdce4",
|
|
56
|
+
textColor: "#32324d",
|
|
57
|
+
border: "none"
|
|
58
|
+
},
|
|
59
|
+
outline: {
|
|
60
|
+
backgroundColor: "transparent",
|
|
61
|
+
textColor: "#4945ff",
|
|
62
|
+
border: "2px solid #4945ff"
|
|
63
|
+
},
|
|
64
|
+
filled: {
|
|
65
|
+
backgroundColor: "#32324d",
|
|
66
|
+
textColor: "#ffffff",
|
|
67
|
+
border: "none"
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
},
|
|
71
|
+
/**
|
|
72
|
+
* Social media embed block. The editor fetches each post's official embed
|
|
73
|
+
* via the server oEmbed proxy (`GET /better-blocks/oembed`), so no platform
|
|
74
|
+
* tokens ever reach the browser. Instagram and Facebook require a Facebook
|
|
75
|
+
* app access token; the other platforms work without one.
|
|
76
|
+
*
|
|
77
|
+
* 'better-blocks': {
|
|
78
|
+
* config: {
|
|
79
|
+
* social: {
|
|
80
|
+
* platforms: ['twitter', 'tiktok', 'pinterest'],
|
|
81
|
+
* instagram: { accessToken: env('FB_OEMBED_TOKEN') },
|
|
82
|
+
* facebook: { accessToken: env('FB_OEMBED_TOKEN') },
|
|
83
|
+
* },
|
|
84
|
+
* },
|
|
85
|
+
* }
|
|
86
|
+
*/
|
|
87
|
+
social: {
|
|
88
|
+
enabled: !0,
|
|
89
|
+
platforms: [
|
|
90
|
+
"twitter",
|
|
91
|
+
"instagram",
|
|
92
|
+
"facebook",
|
|
93
|
+
"tiktok",
|
|
94
|
+
"linkedin",
|
|
95
|
+
"pinterest"
|
|
96
|
+
],
|
|
97
|
+
cache: !0,
|
|
98
|
+
cacheTTL: 86400,
|
|
99
|
+
// seconds (24h)
|
|
100
|
+
instagram: { accessToken: void 0 },
|
|
101
|
+
facebook: { accessToken: void 0 }
|
|
102
|
+
}
|
|
103
|
+
},
|
|
104
|
+
validator(t = {}) {
|
|
105
|
+
const o = t?.details?.style;
|
|
106
|
+
if (o && o !== "github" && o !== "custom")
|
|
107
|
+
throw new Error(
|
|
108
|
+
`[better-blocks] config.details.style must be "github" or "custom" (received "${o}")`
|
|
109
|
+
);
|
|
110
|
+
}
|
|
111
|
+
}, C = {}, v = ({ strapi: t }) => ({
|
|
112
|
+
index(o) {
|
|
113
|
+
o.body = t.plugin("better-blocks").service("service").getWelcomeMessage();
|
|
114
|
+
},
|
|
115
|
+
/**
|
|
116
|
+
* Exposes the plugin config (config/plugins.js merged with server defaults) to
|
|
117
|
+
* the admin panel, so blocks like Details can honour admin-level settings.
|
|
118
|
+
*/
|
|
119
|
+
getConfig(o) {
|
|
120
|
+
o.body = {
|
|
121
|
+
details: t.plugin("better-blocks").config("details", {
|
|
122
|
+
defaultSummary: "Click to expand",
|
|
123
|
+
style: "github"
|
|
124
|
+
}),
|
|
125
|
+
button: t.plugin("better-blocks").config("button", {
|
|
126
|
+
defaultStyle: {
|
|
127
|
+
backgroundColor: "#4945ff",
|
|
128
|
+
textColor: "#ffffff",
|
|
129
|
+
borderRadius: "4px",
|
|
130
|
+
padding: "12px 24px",
|
|
131
|
+
fontSize: "16px",
|
|
132
|
+
fontWeight: "600"
|
|
133
|
+
},
|
|
134
|
+
presets: {
|
|
135
|
+
primary: {
|
|
136
|
+
backgroundColor: "#4945ff",
|
|
137
|
+
textColor: "#ffffff",
|
|
138
|
+
border: "none"
|
|
139
|
+
},
|
|
140
|
+
secondary: {
|
|
141
|
+
backgroundColor: "#dcdce4",
|
|
142
|
+
textColor: "#32324d",
|
|
143
|
+
border: "none"
|
|
144
|
+
},
|
|
145
|
+
outline: {
|
|
146
|
+
backgroundColor: "transparent",
|
|
147
|
+
textColor: "#4945ff",
|
|
148
|
+
border: "2px solid #4945ff"
|
|
149
|
+
},
|
|
150
|
+
filled: {
|
|
151
|
+
backgroundColor: "#32324d",
|
|
152
|
+
textColor: "#ffffff",
|
|
153
|
+
border: "none"
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}),
|
|
157
|
+
social: (() => {
|
|
158
|
+
const e = t.plugin("better-blocks").config("social", {
|
|
159
|
+
enabled: !0,
|
|
160
|
+
platforms: [
|
|
161
|
+
"twitter",
|
|
162
|
+
"instagram",
|
|
163
|
+
"facebook",
|
|
164
|
+
"tiktok",
|
|
165
|
+
"linkedin",
|
|
166
|
+
"pinterest"
|
|
167
|
+
]
|
|
168
|
+
});
|
|
169
|
+
return {
|
|
170
|
+
enabled: e.enabled !== !1,
|
|
171
|
+
platforms: e.platforms ?? [],
|
|
172
|
+
instagramConfigured: !!e.instagram?.accessToken,
|
|
173
|
+
facebookConfigured: !!e.facebook?.accessToken
|
|
174
|
+
};
|
|
175
|
+
})()
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
}), x = [
|
|
179
|
+
"twitter",
|
|
180
|
+
"instagram",
|
|
181
|
+
"facebook",
|
|
182
|
+
"tiktok",
|
|
183
|
+
"linkedin",
|
|
184
|
+
"pinterest"
|
|
185
|
+
], $ = ({ strapi: t }) => ({
|
|
186
|
+
/**
|
|
187
|
+
* GET /better-blocks/oembed?url=...&platform=...
|
|
188
|
+
* Proxies the platform oEmbed request server-side and returns the normalised
|
|
189
|
+
* payload used by the social-embed block.
|
|
190
|
+
*/
|
|
191
|
+
async fetch(o) {
|
|
192
|
+
const { url: e, platform: i } = o.query;
|
|
193
|
+
if (!e || typeof e != "string")
|
|
194
|
+
return o.badRequest('Missing required "url" query parameter.');
|
|
195
|
+
const r = i && x.includes(i) ? i : void 0;
|
|
196
|
+
try {
|
|
197
|
+
o.body = await t.plugin("better-blocks").service("oembed").fetch(e, r);
|
|
198
|
+
} catch (n) {
|
|
199
|
+
const a = n instanceof Error ? n.message : "oEmbed request failed.";
|
|
200
|
+
return o.badRequest(a);
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
}), T = {
|
|
204
|
+
controller: v,
|
|
205
|
+
oembed: $
|
|
206
|
+
}, E = {}, R = {}, L = [
|
|
207
|
+
{
|
|
208
|
+
method: "GET",
|
|
209
|
+
path: "/",
|
|
210
|
+
// name of the controller file & the method.
|
|
211
|
+
handler: "controller.index",
|
|
212
|
+
config: {
|
|
213
|
+
policies: []
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
], _ = [
|
|
217
|
+
{
|
|
218
|
+
method: "GET",
|
|
219
|
+
path: "/config",
|
|
220
|
+
// name of the controller file & the method.
|
|
221
|
+
handler: "controller.getConfig",
|
|
222
|
+
config: {
|
|
223
|
+
policies: []
|
|
224
|
+
}
|
|
225
|
+
},
|
|
226
|
+
{
|
|
227
|
+
method: "GET",
|
|
228
|
+
path: "/oembed",
|
|
229
|
+
// Social oEmbed proxy — fetches a post's embed payload server-side.
|
|
230
|
+
handler: "oembed.fetch",
|
|
231
|
+
config: {
|
|
232
|
+
policies: ["admin::isAuthenticatedAdmin"]
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
], S = {
|
|
236
|
+
"content-api": {
|
|
237
|
+
type: "content-api",
|
|
238
|
+
routes: L
|
|
239
|
+
},
|
|
240
|
+
admin: {
|
|
241
|
+
type: "admin",
|
|
242
|
+
routes: _
|
|
243
|
+
}
|
|
244
|
+
}, U = ({ strapi: t }) => ({
|
|
245
|
+
getWelcomeMessage() {
|
|
246
|
+
return "Welcome to Strapi 🚀";
|
|
247
|
+
}
|
|
248
|
+
}), I = [
|
|
249
|
+
{
|
|
250
|
+
platform: "twitter",
|
|
251
|
+
re: /(?:twitter\.com|x\.com)\/[^/]+\/status(?:es)?\/\d+/i
|
|
252
|
+
},
|
|
253
|
+
{ platform: "instagram", re: /instagram\.com\/(?:p|reel|tv)\//i },
|
|
254
|
+
{ platform: "tiktok", re: /tiktok\.com\/@[^/]+\/video\/\d+/i },
|
|
255
|
+
{ platform: "facebook", re: /facebook\.com\//i },
|
|
256
|
+
{ platform: "linkedin", re: /linkedin\.com\//i },
|
|
257
|
+
{ platform: "pinterest", re: /(?:pinterest\.[a-z.]+|pin\.it)\//i }
|
|
258
|
+
], b = (t) => {
|
|
259
|
+
const o = I.find(({ re: e }) => e.test(t));
|
|
260
|
+
return o ? o.platform : null;
|
|
261
|
+
}, A = (t, o, e) => {
|
|
262
|
+
const i = encodeURIComponent(o);
|
|
263
|
+
switch (t) {
|
|
264
|
+
case "twitter":
|
|
265
|
+
return `https://publish.twitter.com/oembed?url=${i}&omit_script=true&dnt=true`;
|
|
266
|
+
case "tiktok":
|
|
267
|
+
return `https://www.tiktok.com/oembed?url=${i}`;
|
|
268
|
+
case "pinterest":
|
|
269
|
+
return `https://www.pinterest.com/oembed.json?url=${i}`;
|
|
270
|
+
case "instagram": {
|
|
271
|
+
const r = e.instagram?.accessToken;
|
|
272
|
+
return r ? `https://graph.facebook.com/v17.0/instagram_oembed?url=${i}&access_token=${encodeURIComponent(
|
|
273
|
+
r
|
|
274
|
+
)}&omitscript=true` : null;
|
|
275
|
+
}
|
|
276
|
+
case "facebook": {
|
|
277
|
+
const r = e.facebook?.accessToken;
|
|
278
|
+
return r ? `https://graph.facebook.com/v17.0/oembed_post?url=${i}&access_token=${encodeURIComponent(
|
|
279
|
+
r
|
|
280
|
+
)}&omitscript=true` : null;
|
|
281
|
+
}
|
|
282
|
+
case "linkedin":
|
|
283
|
+
return null;
|
|
284
|
+
default:
|
|
285
|
+
return null;
|
|
286
|
+
}
|
|
287
|
+
}, P = async (t) => {
|
|
288
|
+
if (!/^https?:\/\/pin\.it\//i.test(t)) return t;
|
|
289
|
+
try {
|
|
290
|
+
const e = (await fetch(t, { redirect: "follow" })).url || t;
|
|
291
|
+
return /pinterest\.[a-z.]+\/pin\//i.test(e) ? e : t;
|
|
292
|
+
} catch {
|
|
293
|
+
return t;
|
|
294
|
+
}
|
|
295
|
+
}, q = (t) => {
|
|
296
|
+
const o = t.match(
|
|
297
|
+
/(?:urn:li:)?(ugcPost|activity|share)[:-](\d{10,})/i
|
|
298
|
+
);
|
|
299
|
+
if (!o) return null;
|
|
300
|
+
const i = `urn:li:${o[1].toLowerCase() === "ugcpost" ? "ugcPost" : o[1].toLowerCase()}:${o[2]}`, r = `https://www.linkedin.com/embed/feed/update/${encodeURIComponent(i)}`;
|
|
301
|
+
return {
|
|
302
|
+
platform: "linkedin",
|
|
303
|
+
url: t,
|
|
304
|
+
html: `<iframe src="${r}" height="600" width="100%" frameborder="0" allowfullscreen title="Embedded LinkedIn post" loading="lazy"></iframe>`,
|
|
305
|
+
providerName: "LinkedIn",
|
|
306
|
+
width: 504,
|
|
307
|
+
height: 600
|
|
308
|
+
};
|
|
309
|
+
}, z = (t) => t.replace(/<script\b[^>]*>[\s\S]*?<\/script>/gi, "").trim(), M = (t, o, e) => ({
|
|
310
|
+
platform: t,
|
|
311
|
+
url: o,
|
|
312
|
+
html: typeof e.html == "string" && z(e.html) || null,
|
|
313
|
+
title: typeof e.title == "string" ? e.title : void 0,
|
|
314
|
+
author: typeof e.author_name == "string" ? e.author_name : void 0,
|
|
315
|
+
authorUrl: typeof e.author_url == "string" ? e.author_url : void 0,
|
|
316
|
+
thumbnailUrl: typeof e.thumbnail_url == "string" ? e.thumbnail_url : void 0,
|
|
317
|
+
providerName: typeof e.provider_name == "string" ? e.provider_name : void 0,
|
|
318
|
+
width: typeof e.width == "number" ? e.width : void 0,
|
|
319
|
+
height: typeof e.height == "number" ? e.height : void 0
|
|
320
|
+
}), h = /* @__PURE__ */ new Map(), W = ({ strapi: t }) => {
|
|
321
|
+
const o = () => t.plugin("better-blocks").config("social", {});
|
|
322
|
+
return {
|
|
323
|
+
detectPlatform: b,
|
|
324
|
+
/**
|
|
325
|
+
* Fetch (and cache) the normalised oEmbed for `url`. `platform` may be
|
|
326
|
+
* passed to skip auto-detection. Throws on an unsupported/unconfigured
|
|
327
|
+
* platform or a failed upstream request.
|
|
328
|
+
*/
|
|
329
|
+
async fetch(e, i) {
|
|
330
|
+
const r = o();
|
|
331
|
+
if (r.enabled === !1)
|
|
332
|
+
throw new Error("Social embeds are disabled in plugin config.");
|
|
333
|
+
const n = i ?? b(e);
|
|
334
|
+
if (!n)
|
|
335
|
+
throw new Error(`Unsupported or unrecognised social URL: ${e}`);
|
|
336
|
+
const a = r.platforms;
|
|
337
|
+
if (Array.isArray(a) && !a.includes(n))
|
|
338
|
+
throw new Error(
|
|
339
|
+
`Platform "${n}" is not enabled in plugin config.`
|
|
340
|
+
);
|
|
341
|
+
const f = r.cache !== !1, u = (r.cacheTTL ?? 86400) * 1e3, p = `${n}:${e}`;
|
|
342
|
+
if (f) {
|
|
343
|
+
const c = h.get(p);
|
|
344
|
+
if (c && c.expires > Date.now()) return c.data;
|
|
345
|
+
}
|
|
346
|
+
let s = null;
|
|
347
|
+
if (n === "linkedin") {
|
|
348
|
+
if (s = q(e), !s)
|
|
349
|
+
throw new Error(
|
|
350
|
+
"Could not derive a LinkedIn embed from this URL. Paste the post embed code instead."
|
|
351
|
+
);
|
|
352
|
+
} else {
|
|
353
|
+
const c = await P(e), m = A(n, c, r);
|
|
354
|
+
if (!m)
|
|
355
|
+
throw new Error(
|
|
356
|
+
`oEmbed for "${n}" requires an access token. Configure config.social.${n}.accessToken, or paste the embed code instead.`
|
|
357
|
+
);
|
|
358
|
+
const l = await fetch(m, {
|
|
359
|
+
headers: { Accept: "application/json" }
|
|
360
|
+
});
|
|
361
|
+
if (!l.ok)
|
|
362
|
+
throw new Error(
|
|
363
|
+
`oEmbed request to ${n} failed (HTTP ${l.status}).`
|
|
364
|
+
);
|
|
365
|
+
const d = await l.json();
|
|
366
|
+
if (typeof d.error == "string")
|
|
367
|
+
throw new Error(`${n} could not embed this URL: ${d.error}`);
|
|
368
|
+
if (s = M(n, c, d), !s.html)
|
|
369
|
+
throw new Error(
|
|
370
|
+
`${n} returned no embed markup for this URL. Check the post is public, or paste the embed code instead.`
|
|
371
|
+
);
|
|
372
|
+
}
|
|
373
|
+
return f && u > 0 && h.set(p, { expires: Date.now() + u, data: s }), s;
|
|
374
|
+
}
|
|
375
|
+
};
|
|
376
|
+
}, j = {
|
|
377
|
+
service: U,
|
|
378
|
+
oembed: W
|
|
379
|
+
}, D = {
|
|
380
|
+
register: y,
|
|
381
|
+
bootstrap: g,
|
|
382
|
+
destroy: k,
|
|
383
|
+
config: w,
|
|
384
|
+
controllers: T,
|
|
385
|
+
routes: S,
|
|
386
|
+
services: j,
|
|
387
|
+
contentTypes: C,
|
|
388
|
+
policies: R,
|
|
389
|
+
middlewares: E
|
|
390
|
+
};
|
|
391
|
+
export {
|
|
392
|
+
D as default
|
|
393
|
+
};
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
declare const _default: {
|
|
2
|
+
default: {
|
|
3
|
+
/**
|
|
4
|
+
* Defaults for the collapsible Details / Summary block.
|
|
5
|
+
* Override in the consuming app via config/plugins.{js,ts}:
|
|
6
|
+
*
|
|
7
|
+
* 'better-blocks': {
|
|
8
|
+
* enabled: true,
|
|
9
|
+
* config: {
|
|
10
|
+
* details: {
|
|
11
|
+
* defaultSummary: 'Show more',
|
|
12
|
+
* style: 'custom', // 'github' | 'custom'
|
|
13
|
+
* },
|
|
14
|
+
* },
|
|
15
|
+
* }
|
|
16
|
+
*/
|
|
17
|
+
details: {
|
|
18
|
+
defaultSummary: string;
|
|
19
|
+
style: string;
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* Defaults for the WordPress-style Button block. `defaultStyle` is applied to
|
|
23
|
+
* a freshly inserted button; authors can then override it per-button.
|
|
24
|
+
* `presets` are brand variants offered in the editor's "Style preset" picker;
|
|
25
|
+
* override any of them to match your design system.
|
|
26
|
+
*/
|
|
27
|
+
button: {
|
|
28
|
+
defaultStyle: {
|
|
29
|
+
backgroundColor: string;
|
|
30
|
+
textColor: string;
|
|
31
|
+
borderRadius: string;
|
|
32
|
+
padding: string;
|
|
33
|
+
fontSize: string;
|
|
34
|
+
fontWeight: string;
|
|
35
|
+
};
|
|
36
|
+
presets: {
|
|
37
|
+
primary: {
|
|
38
|
+
backgroundColor: string;
|
|
39
|
+
textColor: string;
|
|
40
|
+
border: string;
|
|
41
|
+
};
|
|
42
|
+
secondary: {
|
|
43
|
+
backgroundColor: string;
|
|
44
|
+
textColor: string;
|
|
45
|
+
border: string;
|
|
46
|
+
};
|
|
47
|
+
outline: {
|
|
48
|
+
backgroundColor: string;
|
|
49
|
+
textColor: string;
|
|
50
|
+
border: string;
|
|
51
|
+
};
|
|
52
|
+
filled: {
|
|
53
|
+
backgroundColor: string;
|
|
54
|
+
textColor: string;
|
|
55
|
+
border: string;
|
|
56
|
+
};
|
|
57
|
+
};
|
|
58
|
+
};
|
|
59
|
+
/**
|
|
60
|
+
* Social media embed block. The editor fetches each post's official embed
|
|
61
|
+
* via the server oEmbed proxy (`GET /better-blocks/oembed`), so no platform
|
|
62
|
+
* tokens ever reach the browser. Instagram and Facebook require a Facebook
|
|
63
|
+
* app access token; the other platforms work without one.
|
|
64
|
+
*
|
|
65
|
+
* 'better-blocks': {
|
|
66
|
+
* config: {
|
|
67
|
+
* social: {
|
|
68
|
+
* platforms: ['twitter', 'tiktok', 'pinterest'],
|
|
69
|
+
* instagram: { accessToken: env('FB_OEMBED_TOKEN') },
|
|
70
|
+
* facebook: { accessToken: env('FB_OEMBED_TOKEN') },
|
|
71
|
+
* },
|
|
72
|
+
* },
|
|
73
|
+
* }
|
|
74
|
+
*/
|
|
75
|
+
social: {
|
|
76
|
+
enabled: boolean;
|
|
77
|
+
platforms: string[];
|
|
78
|
+
cache: boolean;
|
|
79
|
+
cacheTTL: number;
|
|
80
|
+
instagram: {
|
|
81
|
+
accessToken: any;
|
|
82
|
+
};
|
|
83
|
+
facebook: {
|
|
84
|
+
accessToken: any;
|
|
85
|
+
};
|
|
86
|
+
};
|
|
87
|
+
};
|
|
88
|
+
validator(config?: {
|
|
89
|
+
details?: {
|
|
90
|
+
style?: string;
|
|
91
|
+
};
|
|
92
|
+
}): void;
|
|
93
|
+
};
|
|
94
|
+
export default _default;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { Core } from '@strapi/strapi';
|
|
2
|
+
declare const controller: ({ strapi }: {
|
|
3
|
+
strapi: Core.Strapi;
|
|
4
|
+
}) => {
|
|
5
|
+
index(ctx: any): void;
|
|
6
|
+
/**
|
|
7
|
+
* Exposes the plugin config (config/plugins.js merged with server defaults) to
|
|
8
|
+
* the admin panel, so blocks like Details can honour admin-level settings.
|
|
9
|
+
*/
|
|
10
|
+
getConfig(ctx: any): void;
|
|
11
|
+
};
|
|
12
|
+
export default controller;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
declare const _default: {
|
|
2
|
+
controller: ({ strapi }: {
|
|
3
|
+
strapi: import("@strapi/types/dist/core").Strapi;
|
|
4
|
+
}) => {
|
|
5
|
+
index(ctx: any): void;
|
|
6
|
+
getConfig(ctx: any): void;
|
|
7
|
+
};
|
|
8
|
+
oembed: ({ strapi }: {
|
|
9
|
+
strapi: import("@strapi/types/dist/core").Strapi;
|
|
10
|
+
}) => {
|
|
11
|
+
fetch(ctx: any): Promise<any>;
|
|
12
|
+
};
|
|
13
|
+
};
|
|
14
|
+
export default _default;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { Core } from '@strapi/strapi';
|
|
2
|
+
declare const oembed: ({ strapi }: {
|
|
3
|
+
strapi: Core.Strapi;
|
|
4
|
+
}) => {
|
|
5
|
+
/**
|
|
6
|
+
* GET /better-blocks/oembed?url=...&platform=...
|
|
7
|
+
* Proxies the platform oEmbed request server-side and returns the normalised
|
|
8
|
+
* payload used by the social-embed block.
|
|
9
|
+
*/
|
|
10
|
+
fetch(ctx: any): Promise<any>;
|
|
11
|
+
};
|
|
12
|
+
export default oembed;
|
|
@@ -0,0 +1,125 @@
|
|
|
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
|
+
details: {
|
|
14
|
+
defaultSummary: string;
|
|
15
|
+
style: string;
|
|
16
|
+
};
|
|
17
|
+
button: {
|
|
18
|
+
defaultStyle: {
|
|
19
|
+
backgroundColor: string;
|
|
20
|
+
textColor: string;
|
|
21
|
+
borderRadius: string;
|
|
22
|
+
padding: string;
|
|
23
|
+
fontSize: string;
|
|
24
|
+
fontWeight: string;
|
|
25
|
+
};
|
|
26
|
+
presets: {
|
|
27
|
+
primary: {
|
|
28
|
+
backgroundColor: string;
|
|
29
|
+
textColor: string;
|
|
30
|
+
border: string;
|
|
31
|
+
};
|
|
32
|
+
secondary: {
|
|
33
|
+
backgroundColor: string;
|
|
34
|
+
textColor: string;
|
|
35
|
+
border: string;
|
|
36
|
+
};
|
|
37
|
+
outline: {
|
|
38
|
+
backgroundColor: string;
|
|
39
|
+
textColor: string;
|
|
40
|
+
border: string;
|
|
41
|
+
};
|
|
42
|
+
filled: {
|
|
43
|
+
backgroundColor: string;
|
|
44
|
+
textColor: string;
|
|
45
|
+
border: string;
|
|
46
|
+
};
|
|
47
|
+
};
|
|
48
|
+
};
|
|
49
|
+
social: {
|
|
50
|
+
enabled: boolean;
|
|
51
|
+
platforms: string[];
|
|
52
|
+
cache: boolean;
|
|
53
|
+
cacheTTL: number;
|
|
54
|
+
instagram: {
|
|
55
|
+
accessToken: any;
|
|
56
|
+
};
|
|
57
|
+
facebook: {
|
|
58
|
+
accessToken: any;
|
|
59
|
+
};
|
|
60
|
+
};
|
|
61
|
+
};
|
|
62
|
+
validator(config?: {
|
|
63
|
+
details?: {
|
|
64
|
+
style?: string;
|
|
65
|
+
};
|
|
66
|
+
}): void;
|
|
67
|
+
};
|
|
68
|
+
controllers: {
|
|
69
|
+
controller: ({ strapi }: {
|
|
70
|
+
strapi: import("@strapi/types/dist/core").Strapi;
|
|
71
|
+
}) => {
|
|
72
|
+
index(ctx: any): void;
|
|
73
|
+
getConfig(ctx: any): void;
|
|
74
|
+
};
|
|
75
|
+
oembed: ({ strapi }: {
|
|
76
|
+
strapi: import("@strapi/types/dist/core").Strapi;
|
|
77
|
+
}) => {
|
|
78
|
+
fetch(ctx: any): Promise<any>;
|
|
79
|
+
};
|
|
80
|
+
};
|
|
81
|
+
routes: {
|
|
82
|
+
'content-api': {
|
|
83
|
+
type: string;
|
|
84
|
+
routes: {
|
|
85
|
+
method: string;
|
|
86
|
+
path: string;
|
|
87
|
+
handler: string;
|
|
88
|
+
/**
|
|
89
|
+
* Plugin server methods
|
|
90
|
+
*/
|
|
91
|
+
config: {
|
|
92
|
+
policies: any[];
|
|
93
|
+
};
|
|
94
|
+
}[];
|
|
95
|
+
};
|
|
96
|
+
admin: {
|
|
97
|
+
type: string;
|
|
98
|
+
routes: {
|
|
99
|
+
method: string;
|
|
100
|
+
path: string;
|
|
101
|
+
handler: string;
|
|
102
|
+
config: {
|
|
103
|
+
policies: string[];
|
|
104
|
+
};
|
|
105
|
+
}[];
|
|
106
|
+
};
|
|
107
|
+
};
|
|
108
|
+
services: {
|
|
109
|
+
service: ({ strapi }: {
|
|
110
|
+
strapi: import("@strapi/types/dist/core").Strapi;
|
|
111
|
+
}) => {
|
|
112
|
+
getWelcomeMessage(): string;
|
|
113
|
+
};
|
|
114
|
+
oembed: ({ strapi }: {
|
|
115
|
+
strapi: import("@strapi/types/dist/core").Strapi;
|
|
116
|
+
}) => {
|
|
117
|
+
detectPlatform: (url: string) => import("./services/oembed").SocialPlatform;
|
|
118
|
+
fetch(url: string, platform?: import("./services/oembed").SocialPlatform): Promise<import("./services/oembed").NormalisedOEmbed>;
|
|
119
|
+
};
|
|
120
|
+
};
|
|
121
|
+
contentTypes: {};
|
|
122
|
+
policies: {};
|
|
123
|
+
middlewares: {};
|
|
124
|
+
};
|
|
125
|
+
export default _default;
|