datocms-plugin-sdk 0.3.26 → 0.3.27
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/package.json +3 -3
- package/src/SiteApiSchema.ts +6419 -0
- package/src/connect.ts +527 -0
- package/src/definitions.d.ts +1 -0
- package/src/guards.ts +48 -0
- package/src/index.ts +28 -0
- package/src/types.ts +1398 -0
package/src/connect.ts
ADDED
|
@@ -0,0 +1,527 @@
|
|
|
1
|
+
import connectToParent from 'penpal/lib/connectToParent';
|
|
2
|
+
import { Field, ModelBlock } from './SiteApiSchema';
|
|
3
|
+
import {
|
|
4
|
+
AssetSource,
|
|
5
|
+
ContentAreaSidebarItem,
|
|
6
|
+
FieldExtensionOverride,
|
|
7
|
+
InitPropertiesAndMethods,
|
|
8
|
+
ItemFormSidebarPanel,
|
|
9
|
+
MainNavigationTab,
|
|
10
|
+
ManualFieldExtension,
|
|
11
|
+
OnBootMethods,
|
|
12
|
+
OnBootPropertiesAndMethods,
|
|
13
|
+
RenderAssetSourceMethods,
|
|
14
|
+
RenderAssetSourcePropertiesAndMethods,
|
|
15
|
+
RenderConfigScreenMethods,
|
|
16
|
+
RenderConfigScreenPropertiesAndMethods,
|
|
17
|
+
RenderFieldExtensionMethods,
|
|
18
|
+
RenderFieldExtensionPropertiesAndMethods,
|
|
19
|
+
RenderManualFieldExtensionConfigScreenMethods,
|
|
20
|
+
RenderManualFieldExtensionConfigScreenPropertiesAndMethods,
|
|
21
|
+
RenderModalMethods,
|
|
22
|
+
RenderModalPropertiesAndMethods,
|
|
23
|
+
RenderPageMethods,
|
|
24
|
+
RenderPagePropertiesAndMethods,
|
|
25
|
+
RenderSidebarPanelMethods,
|
|
26
|
+
RenderSidebarPanePropertiesAndMethods,
|
|
27
|
+
SettingsAreaSidebarItemGroup,
|
|
28
|
+
} from './types';
|
|
29
|
+
import {
|
|
30
|
+
isInitParent,
|
|
31
|
+
isOnBootParent,
|
|
32
|
+
isRenderAssetSourceParent,
|
|
33
|
+
isRenderConfigScreenParent,
|
|
34
|
+
isRenderFieldExtensionParent,
|
|
35
|
+
isRenderManualFieldExtensionConfigScreenParent,
|
|
36
|
+
isRenderModalParent,
|
|
37
|
+
isRenderPageParent,
|
|
38
|
+
isRenderSidebarPaneParent,
|
|
39
|
+
Parent,
|
|
40
|
+
} from './guards';
|
|
41
|
+
|
|
42
|
+
export type SizingUtilities = {
|
|
43
|
+
/**
|
|
44
|
+
* Listens for DOM changes and automatically calls `setHeight` when it detects
|
|
45
|
+
* a change. If you're using `datocms-react-ui` package, the `<Canvas />`
|
|
46
|
+
* component already takes care of calling this method for you.
|
|
47
|
+
*/
|
|
48
|
+
startAutoResizer: () => void;
|
|
49
|
+
/** Stops resizing the iframe automatically */
|
|
50
|
+
stopAutoResizer: () => void;
|
|
51
|
+
/**
|
|
52
|
+
* Triggers a change in the size of the iframe. If you don't explicitely pass
|
|
53
|
+
* a `newHeight` it will be automatically calculated using the iframe content
|
|
54
|
+
* at the moment
|
|
55
|
+
*/
|
|
56
|
+
updateHeight: (newHeight?: number) => void;
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
export type { Field, ModelBlock };
|
|
60
|
+
|
|
61
|
+
export type IntentCtx = InitPropertiesAndMethods;
|
|
62
|
+
export type OnBootCtx = OnBootPropertiesAndMethods;
|
|
63
|
+
export type FieldIntentCtx = InitPropertiesAndMethods & {
|
|
64
|
+
itemType: ModelBlock;
|
|
65
|
+
};
|
|
66
|
+
export type RenderPageCtx = RenderPagePropertiesAndMethods;
|
|
67
|
+
export type RenderModalCtx = RenderModalPropertiesAndMethods & SizingUtilities;
|
|
68
|
+
export type RenderAssetSourceCtx = RenderAssetSourcePropertiesAndMethods &
|
|
69
|
+
SizingUtilities;
|
|
70
|
+
export type RenderItemFormSidebarPanelCtx = RenderSidebarPanePropertiesAndMethods &
|
|
71
|
+
SizingUtilities;
|
|
72
|
+
export type RenderFieldExtensionCtx = RenderFieldExtensionPropertiesAndMethods &
|
|
73
|
+
SizingUtilities;
|
|
74
|
+
export type RenderManualFieldExtensionConfigScreenCtx = RenderManualFieldExtensionConfigScreenPropertiesAndMethods &
|
|
75
|
+
SizingUtilities;
|
|
76
|
+
export type RenderConfigScreenCtx = RenderConfigScreenPropertiesAndMethods &
|
|
77
|
+
SizingUtilities;
|
|
78
|
+
|
|
79
|
+
/** The full options you can pass to the `connect` function */
|
|
80
|
+
export type FullConnectParameters = {
|
|
81
|
+
/**
|
|
82
|
+
* This function will be called once at boot time and can be used to perform
|
|
83
|
+
* ie. some initial integrity checks on the configuration.
|
|
84
|
+
*
|
|
85
|
+
* @group boot
|
|
86
|
+
*/
|
|
87
|
+
onBoot: (ctx: OnBootCtx) => void;
|
|
88
|
+
/**
|
|
89
|
+
* Use this function to declare new tabs you want to add in the top-bar of the UI
|
|
90
|
+
*
|
|
91
|
+
* @group pages
|
|
92
|
+
*/
|
|
93
|
+
mainNavigationTabs: (ctx: IntentCtx) => MainNavigationTab[];
|
|
94
|
+
/**
|
|
95
|
+
* Use this function to declare new navigation sections in the Settings Area sidebar
|
|
96
|
+
*
|
|
97
|
+
* @group pages
|
|
98
|
+
*/
|
|
99
|
+
settingsAreaSidebarItemGroups: (
|
|
100
|
+
ctx: IntentCtx,
|
|
101
|
+
) => SettingsAreaSidebarItemGroup[];
|
|
102
|
+
/**
|
|
103
|
+
* Use this function to declare new navigation items in the Content Area sidebar
|
|
104
|
+
*
|
|
105
|
+
* @group pages
|
|
106
|
+
*/
|
|
107
|
+
contentAreaSidebarItems: (ctx: IntentCtx) => ContentAreaSidebarItem[];
|
|
108
|
+
/**
|
|
109
|
+
* Use this function to declare new field extensions that users will be able
|
|
110
|
+
* to install manually in some field
|
|
111
|
+
*
|
|
112
|
+
* @group manualFieldExtensions
|
|
113
|
+
*/
|
|
114
|
+
manualFieldExtensions: (ctx: IntentCtx) => ManualFieldExtension[];
|
|
115
|
+
/**
|
|
116
|
+
* Use this function to declare additional sources to be shown when users want
|
|
117
|
+
* to upload new assets
|
|
118
|
+
*
|
|
119
|
+
* @group assetSources
|
|
120
|
+
*/
|
|
121
|
+
assetSources: (ctx: IntentCtx) => AssetSource[] | void;
|
|
122
|
+
/**
|
|
123
|
+
* Use this function to declare new sidebar panels to be shown when the user
|
|
124
|
+
* edits records of a particular model
|
|
125
|
+
*
|
|
126
|
+
* @group sidebarPanels
|
|
127
|
+
*/
|
|
128
|
+
itemFormSidebarPanels: (
|
|
129
|
+
itemType: ModelBlock,
|
|
130
|
+
ctx: IntentCtx,
|
|
131
|
+
) => ItemFormSidebarPanel[];
|
|
132
|
+
/**
|
|
133
|
+
* Use this function to automatically force one or more field extensions to a
|
|
134
|
+
* particular field
|
|
135
|
+
*
|
|
136
|
+
* @group forcedFieldExtensions
|
|
137
|
+
*/
|
|
138
|
+
overrideFieldExtensions: (
|
|
139
|
+
field: Field,
|
|
140
|
+
ctx: FieldIntentCtx,
|
|
141
|
+
) => FieldExtensionOverride | void;
|
|
142
|
+
/**
|
|
143
|
+
* This function will be called when the plugin needs to render the plugin's
|
|
144
|
+
* configuration form
|
|
145
|
+
*
|
|
146
|
+
* @group configScreen
|
|
147
|
+
*/
|
|
148
|
+
renderConfigScreen: (ctx: RenderConfigScreenCtx) => void;
|
|
149
|
+
/**
|
|
150
|
+
* This function will be called when the plugin needs to render a specific
|
|
151
|
+
* page (see the `mainNavigationTabs`, `settingsAreaSidebarItemGroups` and
|
|
152
|
+
* `contentAreaSidebarItems` functions)
|
|
153
|
+
*
|
|
154
|
+
* @group pages
|
|
155
|
+
*/
|
|
156
|
+
renderPage: (pageId: string, ctx: RenderPageCtx) => void;
|
|
157
|
+
/**
|
|
158
|
+
* This function will be called when the plugin requested to open a modal (see
|
|
159
|
+
* the `openModal` function)
|
|
160
|
+
*
|
|
161
|
+
* @group modals
|
|
162
|
+
*/
|
|
163
|
+
renderModal: (modalId: string, ctx: RenderModalCtx) => void;
|
|
164
|
+
/**
|
|
165
|
+
* This function will be called when the plugin needs to render a sidebar
|
|
166
|
+
* panel (see the `itemFormSidebarPanels` function)
|
|
167
|
+
*
|
|
168
|
+
* @group sidebarPanels
|
|
169
|
+
*/
|
|
170
|
+
renderItemFormSidebarPanel: (
|
|
171
|
+
sidebarPaneId: string,
|
|
172
|
+
ctx: RenderItemFormSidebarPanelCtx,
|
|
173
|
+
) => void;
|
|
174
|
+
/**
|
|
175
|
+
* This function will be called when the user selects one of the plugin's
|
|
176
|
+
* asset sources to upload a new media file.
|
|
177
|
+
*
|
|
178
|
+
* @group assetSources
|
|
179
|
+
*/
|
|
180
|
+
renderAssetSource: (assetSourceId: string, ctx: RenderAssetSourceCtx) => void;
|
|
181
|
+
/**
|
|
182
|
+
* This function will be called when the plugin needs to render a field
|
|
183
|
+
* extension (see the `manualFieldExtensions` and `overrideFieldExtensions` functions)
|
|
184
|
+
*
|
|
185
|
+
* @group forcedFieldExtensions
|
|
186
|
+
*/
|
|
187
|
+
renderFieldExtension: (
|
|
188
|
+
fieldExtensionId: string,
|
|
189
|
+
ctx: RenderFieldExtensionCtx,
|
|
190
|
+
) => void;
|
|
191
|
+
/**
|
|
192
|
+
* This function will be called when the plugin needs to render the
|
|
193
|
+
* configuration form for installing a field extension inside a particular field
|
|
194
|
+
*
|
|
195
|
+
* @group manualFieldExtensions
|
|
196
|
+
*/
|
|
197
|
+
renderManualFieldExtensionConfigScreen: (
|
|
198
|
+
fieldExtensionId: string,
|
|
199
|
+
ctx: RenderManualFieldExtensionConfigScreenCtx,
|
|
200
|
+
) => void;
|
|
201
|
+
/**
|
|
202
|
+
* This function will be called each time the configuration object changes. It
|
|
203
|
+
* must return an object containing possible validation errors
|
|
204
|
+
*
|
|
205
|
+
* @group manualFieldExtensions
|
|
206
|
+
*/
|
|
207
|
+
validateManualFieldExtensionParameters: (
|
|
208
|
+
fieldExtensionId: string,
|
|
209
|
+
parameters: Record<string, unknown>,
|
|
210
|
+
) => Record<string, unknown> | Promise<Record<string, unknown>>;
|
|
211
|
+
};
|
|
212
|
+
|
|
213
|
+
function toMultifield<Result>(
|
|
214
|
+
fn: ((field: Field, ctx: FieldIntentCtx) => Result) | undefined,
|
|
215
|
+
) {
|
|
216
|
+
return (
|
|
217
|
+
fields: Field[],
|
|
218
|
+
ctx: InitPropertiesAndMethods,
|
|
219
|
+
): Record<string, Result> => {
|
|
220
|
+
if (!fn) {
|
|
221
|
+
return {};
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
const result: Record<string, Result> = {};
|
|
225
|
+
|
|
226
|
+
for (const field of fields) {
|
|
227
|
+
const itemType = ctx.itemTypes[
|
|
228
|
+
field.relationships.item_type.data.id
|
|
229
|
+
] as ModelBlock;
|
|
230
|
+
result[field.id] = fn(field, { ...ctx, itemType });
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
return result;
|
|
234
|
+
};
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
238
|
+
type AsyncReturnType<T extends (...args: any) => any> = T extends (
|
|
239
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
240
|
+
...args: any
|
|
241
|
+
) => Promise<infer U>
|
|
242
|
+
? U
|
|
243
|
+
: // eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
244
|
+
T extends (...args: any) => infer U
|
|
245
|
+
? U
|
|
246
|
+
: // eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
247
|
+
any;
|
|
248
|
+
|
|
249
|
+
const buildRenderUtils = (parent: { setHeight: (number: number) => void }) => {
|
|
250
|
+
let oldHeight: null | number = null;
|
|
251
|
+
|
|
252
|
+
const updateHeight = (height?: number) => {
|
|
253
|
+
const realHeight =
|
|
254
|
+
height === undefined
|
|
255
|
+
? Math.ceil(document.documentElement.getBoundingClientRect().height)
|
|
256
|
+
: height;
|
|
257
|
+
|
|
258
|
+
if (realHeight !== oldHeight) {
|
|
259
|
+
parent.setHeight(realHeight);
|
|
260
|
+
oldHeight = realHeight;
|
|
261
|
+
}
|
|
262
|
+
};
|
|
263
|
+
|
|
264
|
+
let autoResizingActive = false;
|
|
265
|
+
let mutationObserver: MutationObserver | null = null;
|
|
266
|
+
|
|
267
|
+
const resetHeight = () => updateHeight();
|
|
268
|
+
|
|
269
|
+
const startAutoResizer = () => {
|
|
270
|
+
updateHeight();
|
|
271
|
+
|
|
272
|
+
if (autoResizingActive) {
|
|
273
|
+
return;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
autoResizingActive = true;
|
|
277
|
+
|
|
278
|
+
mutationObserver = new MutationObserver(resetHeight);
|
|
279
|
+
|
|
280
|
+
mutationObserver.observe(window.document.body, {
|
|
281
|
+
attributes: true,
|
|
282
|
+
childList: true,
|
|
283
|
+
subtree: true,
|
|
284
|
+
characterData: true,
|
|
285
|
+
});
|
|
286
|
+
|
|
287
|
+
window.addEventListener('resize', resetHeight);
|
|
288
|
+
};
|
|
289
|
+
|
|
290
|
+
const stopAutoResizer = () => {
|
|
291
|
+
if (!autoResizingActive) {
|
|
292
|
+
return;
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
autoResizingActive = false;
|
|
296
|
+
|
|
297
|
+
if (mutationObserver) {
|
|
298
|
+
mutationObserver.disconnect();
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
window.removeEventListener('resize', resetHeight);
|
|
302
|
+
};
|
|
303
|
+
|
|
304
|
+
return { updateHeight, startAutoResizer, stopAutoResizer };
|
|
305
|
+
};
|
|
306
|
+
|
|
307
|
+
export async function connect(
|
|
308
|
+
configuration: Partial<FullConnectParameters> = {},
|
|
309
|
+
): Promise<void> {
|
|
310
|
+
const {
|
|
311
|
+
assetSources,
|
|
312
|
+
mainNavigationTabs,
|
|
313
|
+
settingsAreaSidebarItemGroups,
|
|
314
|
+
contentAreaSidebarItems,
|
|
315
|
+
manualFieldExtensions,
|
|
316
|
+
itemFormSidebarPanels,
|
|
317
|
+
} = configuration;
|
|
318
|
+
|
|
319
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
320
|
+
let listener: ((newSettings: any) => void) | null = null;
|
|
321
|
+
|
|
322
|
+
const penpalConnection = connectToParent({
|
|
323
|
+
methods: {
|
|
324
|
+
sdkVersion: () => '0.2.0',
|
|
325
|
+
implementedHooks: () =>
|
|
326
|
+
Object.fromEntries(
|
|
327
|
+
Object.entries(configuration).map(([key, value]) => {
|
|
328
|
+
if (typeof value === 'function') {
|
|
329
|
+
return [key, true];
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
return [key, value];
|
|
333
|
+
}),
|
|
334
|
+
),
|
|
335
|
+
assetSources,
|
|
336
|
+
mainNavigationTabs,
|
|
337
|
+
settingsAreaSidebarItemGroups,
|
|
338
|
+
contentAreaSidebarItems,
|
|
339
|
+
manualFieldExtensions,
|
|
340
|
+
itemFormSidebarPanels,
|
|
341
|
+
overrideFieldExtensions: toMultifield(
|
|
342
|
+
configuration.overrideFieldExtensions,
|
|
343
|
+
),
|
|
344
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
345
|
+
onChange(newSettings: any) {
|
|
346
|
+
if (listener) {
|
|
347
|
+
listener(newSettings);
|
|
348
|
+
}
|
|
349
|
+
},
|
|
350
|
+
validateManualFieldExtensionParameters:
|
|
351
|
+
configuration.validateManualFieldExtensionParameters,
|
|
352
|
+
},
|
|
353
|
+
});
|
|
354
|
+
|
|
355
|
+
const parent: Parent = await penpalConnection.promise;
|
|
356
|
+
const initialSettings = await parent.getSettings();
|
|
357
|
+
|
|
358
|
+
if (isInitParent(parent, initialSettings)) {
|
|
359
|
+
// Nothing to do. Parent calls the method they need.
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
if (isOnBootParent(parent, initialSettings)) {
|
|
363
|
+
type Settings = AsyncReturnType<OnBootMethods['getSettings']>;
|
|
364
|
+
|
|
365
|
+
const render = (settings: Settings) => {
|
|
366
|
+
if (!configuration.onBoot) {
|
|
367
|
+
return;
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
configuration.onBoot({
|
|
371
|
+
...parent,
|
|
372
|
+
...settings,
|
|
373
|
+
});
|
|
374
|
+
};
|
|
375
|
+
|
|
376
|
+
render(initialSettings as Settings);
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
if (isRenderPageParent(parent, initialSettings)) {
|
|
380
|
+
type Settings = AsyncReturnType<RenderPageMethods['getSettings']>;
|
|
381
|
+
|
|
382
|
+
const render = (settings: Settings) => {
|
|
383
|
+
if (!configuration.renderPage) {
|
|
384
|
+
return;
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
configuration.renderPage(settings.pageId, {
|
|
388
|
+
...parent,
|
|
389
|
+
...settings,
|
|
390
|
+
});
|
|
391
|
+
};
|
|
392
|
+
|
|
393
|
+
listener = render;
|
|
394
|
+
render(initialSettings as Settings);
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
if (isRenderConfigScreenParent(parent, initialSettings)) {
|
|
398
|
+
type Settings = AsyncReturnType<RenderConfigScreenMethods['getSettings']>;
|
|
399
|
+
|
|
400
|
+
const renderUtils = buildRenderUtils(parent);
|
|
401
|
+
|
|
402
|
+
const render = (settings: Settings) => {
|
|
403
|
+
if (!configuration.renderConfigScreen) {
|
|
404
|
+
return;
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
configuration.renderConfigScreen({
|
|
408
|
+
...parent,
|
|
409
|
+
...settings,
|
|
410
|
+
...renderUtils,
|
|
411
|
+
});
|
|
412
|
+
};
|
|
413
|
+
|
|
414
|
+
listener = render;
|
|
415
|
+
render(initialSettings as Settings);
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
if (isRenderModalParent(parent, initialSettings)) {
|
|
419
|
+
type Settings = AsyncReturnType<RenderModalMethods['getSettings']>;
|
|
420
|
+
|
|
421
|
+
const renderUtils = buildRenderUtils(parent);
|
|
422
|
+
|
|
423
|
+
const render = (settings: Settings) => {
|
|
424
|
+
if (!configuration.renderModal) {
|
|
425
|
+
return;
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
configuration.renderModal(settings.modalId, {
|
|
429
|
+
...parent,
|
|
430
|
+
...settings,
|
|
431
|
+
...renderUtils,
|
|
432
|
+
});
|
|
433
|
+
};
|
|
434
|
+
|
|
435
|
+
listener = render;
|
|
436
|
+
render(initialSettings as Settings);
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
if (isRenderAssetSourceParent(parent, initialSettings)) {
|
|
440
|
+
type Settings = AsyncReturnType<RenderAssetSourceMethods['getSettings']>;
|
|
441
|
+
|
|
442
|
+
const renderUtils = buildRenderUtils(parent);
|
|
443
|
+
|
|
444
|
+
const render = (settings: Settings) => {
|
|
445
|
+
if (!configuration.renderAssetSource) {
|
|
446
|
+
return;
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
configuration.renderAssetSource(settings.assetSourceId, {
|
|
450
|
+
...parent,
|
|
451
|
+
...settings,
|
|
452
|
+
...renderUtils,
|
|
453
|
+
});
|
|
454
|
+
};
|
|
455
|
+
|
|
456
|
+
listener = render;
|
|
457
|
+
render(initialSettings as Settings);
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
if (isRenderSidebarPaneParent(parent, initialSettings)) {
|
|
461
|
+
type Settings = AsyncReturnType<RenderSidebarPanelMethods['getSettings']>;
|
|
462
|
+
|
|
463
|
+
const renderUtils = buildRenderUtils(parent);
|
|
464
|
+
|
|
465
|
+
const render = (settings: Settings) => {
|
|
466
|
+
if (!configuration.renderItemFormSidebarPanel) {
|
|
467
|
+
return;
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
configuration.renderItemFormSidebarPanel(settings.sidebarPaneId, {
|
|
471
|
+
...parent,
|
|
472
|
+
...settings,
|
|
473
|
+
...renderUtils,
|
|
474
|
+
});
|
|
475
|
+
};
|
|
476
|
+
|
|
477
|
+
listener = render;
|
|
478
|
+
render(initialSettings as Settings);
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
if (isRenderFieldExtensionParent(parent, initialSettings)) {
|
|
482
|
+
type Settings = AsyncReturnType<RenderFieldExtensionMethods['getSettings']>;
|
|
483
|
+
|
|
484
|
+
const renderUtils = buildRenderUtils(parent);
|
|
485
|
+
|
|
486
|
+
const render = (settings: Settings) => {
|
|
487
|
+
if (!configuration.renderFieldExtension) {
|
|
488
|
+
return;
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
configuration.renderFieldExtension(settings.fieldExtensionId, {
|
|
492
|
+
...parent,
|
|
493
|
+
...settings,
|
|
494
|
+
...renderUtils,
|
|
495
|
+
});
|
|
496
|
+
};
|
|
497
|
+
|
|
498
|
+
listener = render;
|
|
499
|
+
render(initialSettings as Settings);
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
if (isRenderManualFieldExtensionConfigScreenParent(parent, initialSettings)) {
|
|
503
|
+
type Settings = AsyncReturnType<
|
|
504
|
+
RenderManualFieldExtensionConfigScreenMethods['getSettings']
|
|
505
|
+
>;
|
|
506
|
+
|
|
507
|
+
const renderUtils = buildRenderUtils(parent);
|
|
508
|
+
|
|
509
|
+
const render = (settings: Settings) => {
|
|
510
|
+
if (!configuration.renderManualFieldExtensionConfigScreen) {
|
|
511
|
+
return;
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
configuration.renderManualFieldExtensionConfigScreen(
|
|
515
|
+
settings.fieldExtensionId,
|
|
516
|
+
{
|
|
517
|
+
...parent,
|
|
518
|
+
...settings,
|
|
519
|
+
...renderUtils,
|
|
520
|
+
},
|
|
521
|
+
);
|
|
522
|
+
};
|
|
523
|
+
|
|
524
|
+
listener = render;
|
|
525
|
+
render(initialSettings as Settings);
|
|
526
|
+
}
|
|
527
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
declare module 'penpal/lib/connectToParent';
|
package/src/guards.ts
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import {
|
|
2
|
+
InitMethods,
|
|
3
|
+
OnBootMethods,
|
|
4
|
+
RenderPageMethods,
|
|
5
|
+
RenderFieldExtensionMethods,
|
|
6
|
+
RenderConfigScreenMethods,
|
|
7
|
+
RenderManualFieldExtensionConfigScreenMethods,
|
|
8
|
+
RenderSidebarPanelMethods,
|
|
9
|
+
RenderModalMethods,
|
|
10
|
+
RenderAssetSourceMethods,
|
|
11
|
+
} from './types';
|
|
12
|
+
|
|
13
|
+
export type Parent = { getSettings: () => Promise<{ mode: string }> };
|
|
14
|
+
|
|
15
|
+
function buildGuard<P extends Parent>(mode: string) {
|
|
16
|
+
return (parent: Parent, settings: { mode: string }): parent is P =>
|
|
17
|
+
settings.mode === mode;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export const isInitParent = buildGuard<InitMethods>('init');
|
|
21
|
+
|
|
22
|
+
export const isOnBootParent = buildGuard<OnBootMethods>('onBoot');
|
|
23
|
+
|
|
24
|
+
export const isRenderPageParent = buildGuard<RenderPageMethods>('renderPage');
|
|
25
|
+
|
|
26
|
+
export const isRenderConfigScreenParent = buildGuard<RenderConfigScreenMethods>(
|
|
27
|
+
'renderConfigScreen',
|
|
28
|
+
);
|
|
29
|
+
|
|
30
|
+
export const isRenderModalParent = buildGuard<RenderModalMethods>(
|
|
31
|
+
'renderModal',
|
|
32
|
+
);
|
|
33
|
+
|
|
34
|
+
export const isRenderSidebarPaneParent = buildGuard<RenderSidebarPanelMethods>(
|
|
35
|
+
'renderItemFormSidebarPanel',
|
|
36
|
+
);
|
|
37
|
+
|
|
38
|
+
export const isRenderFieldExtensionParent = buildGuard<RenderFieldExtensionMethods>(
|
|
39
|
+
'renderFieldExtension',
|
|
40
|
+
);
|
|
41
|
+
|
|
42
|
+
export const isRenderManualFieldExtensionConfigScreenParent = buildGuard<RenderManualFieldExtensionConfigScreenMethods>(
|
|
43
|
+
'renderManualFieldExtensionConfigScreen',
|
|
44
|
+
);
|
|
45
|
+
|
|
46
|
+
export const isRenderAssetSourceParent = buildGuard<RenderAssetSourceMethods>(
|
|
47
|
+
'renderAssetSource',
|
|
48
|
+
);
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Account,
|
|
3
|
+
Field,
|
|
4
|
+
Item,
|
|
5
|
+
ModelBlock,
|
|
6
|
+
Plugin,
|
|
7
|
+
Site,
|
|
8
|
+
SsoUser,
|
|
9
|
+
Upload,
|
|
10
|
+
User,
|
|
11
|
+
Role,
|
|
12
|
+
} from './SiteApiSchema';
|
|
13
|
+
|
|
14
|
+
export type {
|
|
15
|
+
Account,
|
|
16
|
+
Field,
|
|
17
|
+
Item,
|
|
18
|
+
ModelBlock,
|
|
19
|
+
Plugin,
|
|
20
|
+
Site,
|
|
21
|
+
SsoUser,
|
|
22
|
+
Upload,
|
|
23
|
+
User,
|
|
24
|
+
Role,
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
export * from './connect';
|
|
28
|
+
export * from './types';
|