@get-bb/plugin-sdk 0.4.8 → 0.4.10
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/README.md +43 -2
- package/bundled-types/bb-plugin-sdk-app.d.ts +319 -27
- package/bundled-types/bb-plugin-sdk-internal-file-navigation-validation.d.ts +42 -0
- package/bundled-types/bb-plugin-sdk-internal-host-policy.d.ts +45 -8
- package/bundled-types/bb-plugin-sdk-internal-plugin-app-collector.d.ts +3 -1
- package/bundled-types/bb-plugin-sdk-provider-bridge.d.ts +2791 -4936
- package/bundled-types/bb-plugin-sdk-testing-app.d.ts +35 -2
- package/bundled-types/bb-plugin-sdk.d.ts +1341 -429
- package/dist/app.js +12 -0
- package/dist/internal/file-navigation-validation.js +135 -0
- package/dist/internal/host-policy.js +104 -0
- package/dist/internal/plugin-app-collector.js +58 -1
- package/dist/provider-bridge.js +3477 -4881
- package/dist/testing/app.js +403 -1
- package/dist/testing/index.js +104 -1
- package/package.json +11 -4
package/dist/app.js
CHANGED
|
@@ -3,13 +3,19 @@ var runtime = globalThis.__bbPluginRuntime?.pluginSdkApp ?? {};
|
|
|
3
3
|
var definePluginApp = runtime.definePluginApp;
|
|
4
4
|
var ThreadChat = runtime.ThreadChat;
|
|
5
5
|
var Markdown = runtime.Markdown;
|
|
6
|
+
var experimental_FileLink = runtime.experimental_FileLink;
|
|
7
|
+
var experimental_UrlLink = runtime.experimental_UrlLink;
|
|
6
8
|
var experimental_NewThreadComposer = runtime.experimental_NewThreadComposer;
|
|
9
|
+
var experimental_SourceCode = runtime.experimental_SourceCode;
|
|
10
|
+
var experimental_Diff = runtime.experimental_Diff;
|
|
7
11
|
var useRpc = runtime.useRpc;
|
|
8
12
|
var useRealtime = runtime.useRealtime;
|
|
9
13
|
var useRealtimeConnectionState = runtime.useRealtimeConnectionState;
|
|
10
14
|
var useSettings = runtime.useSettings;
|
|
11
15
|
var useBbContext = runtime.useBbContext;
|
|
12
16
|
var useBbNavigate = runtime.useBbNavigate;
|
|
17
|
+
var experimental_useAppPanel = runtime.experimental_useAppPanel;
|
|
18
|
+
var experimental_useFixedTabTarget = runtime.experimental_useFixedTabTarget;
|
|
13
19
|
var useComposer = runtime.useComposer;
|
|
14
20
|
var useComposerView = runtime.useComposerView;
|
|
15
21
|
var experimental_useSidebarThreads = runtime.experimental_useSidebarThreads;
|
|
@@ -20,7 +26,13 @@ export {
|
|
|
20
26
|
Markdown,
|
|
21
27
|
ThreadChat,
|
|
22
28
|
definePluginApp,
|
|
29
|
+
experimental_Diff,
|
|
30
|
+
experimental_FileLink,
|
|
23
31
|
experimental_NewThreadComposer,
|
|
32
|
+
experimental_SourceCode,
|
|
33
|
+
experimental_UrlLink,
|
|
34
|
+
experimental_useAppPanel,
|
|
35
|
+
experimental_useFixedTabTarget,
|
|
24
36
|
experimental_useSidebarThreadActions,
|
|
25
37
|
experimental_useSidebarThreadPullRequest,
|
|
26
38
|
experimental_useSidebarThreadSplit,
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
// src/internal/file-navigation-validation.ts
|
|
2
|
+
var FILE_PATH_MAX_LENGTH = 32768;
|
|
3
|
+
var WINDOWS_DRIVE_ABSOLUTE_PATH = /^[A-Za-z]:[\\/]/u;
|
|
4
|
+
var WINDOWS_UNC_ABSOLUTE_PATH = /^\\\\/u;
|
|
5
|
+
function isJsonObject(value) {
|
|
6
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
7
|
+
return false;
|
|
8
|
+
}
|
|
9
|
+
const prototype = Object.getPrototypeOf(value);
|
|
10
|
+
return prototype === Object.prototype || prototype === null;
|
|
11
|
+
}
|
|
12
|
+
function hasExactKeys(value, keys) {
|
|
13
|
+
const actualKeys = Object.keys(value);
|
|
14
|
+
return actualKeys.length === keys.length && keys.every((key) => Object.prototype.hasOwnProperty.call(value, key));
|
|
15
|
+
}
|
|
16
|
+
function isNonEmptyIdentity(value) {
|
|
17
|
+
return typeof value === "string" && value.length > 0 && value.length <= FILE_PATH_MAX_LENGTH && value.trim() === value;
|
|
18
|
+
}
|
|
19
|
+
function hasControlCharacter(value) {
|
|
20
|
+
for (const character of value) {
|
|
21
|
+
const codePoint = character.codePointAt(0);
|
|
22
|
+
if (codePoint !== void 0 && codePoint < 32) return true;
|
|
23
|
+
}
|
|
24
|
+
return false;
|
|
25
|
+
}
|
|
26
|
+
function hasUnpairedSurrogate(value) {
|
|
27
|
+
for (let index = 0; index < value.length; index += 1) {
|
|
28
|
+
const codeUnit = value.charCodeAt(index);
|
|
29
|
+
if (codeUnit >= 55296 && codeUnit <= 56319) {
|
|
30
|
+
if (index + 1 >= value.length) return true;
|
|
31
|
+
const nextCodeUnit = value.charCodeAt(index + 1);
|
|
32
|
+
if (nextCodeUnit < 56320 || nextCodeUnit > 57343) return true;
|
|
33
|
+
index += 1;
|
|
34
|
+
} else if (codeUnit >= 56320 && codeUnit <= 57343) {
|
|
35
|
+
return true;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
return false;
|
|
39
|
+
}
|
|
40
|
+
function isValidPathSegment(segment) {
|
|
41
|
+
return segment.length > 0 && segment !== "." && segment !== "..";
|
|
42
|
+
}
|
|
43
|
+
function isPositiveSafeInteger(value) {
|
|
44
|
+
return typeof value === "number" && Number.isSafeInteger(value) && value > 0;
|
|
45
|
+
}
|
|
46
|
+
function isValidRelativeFilePath(value) {
|
|
47
|
+
if (typeof value !== "string" || value.length === 0 || value.length > FILE_PATH_MAX_LENGTH || value.trim() !== value || value.includes("\\") || hasControlCharacter(value) || hasUnpairedSurrogate(value)) {
|
|
48
|
+
return false;
|
|
49
|
+
}
|
|
50
|
+
return value.split("/").every(isValidPathSegment);
|
|
51
|
+
}
|
|
52
|
+
function isValidAbsoluteHostFilePath(value) {
|
|
53
|
+
if (typeof value !== "string" || value.length === 0 || value.length > FILE_PATH_MAX_LENGTH || value.trim() !== value || hasControlCharacter(value) || hasUnpairedSurrogate(value)) {
|
|
54
|
+
return false;
|
|
55
|
+
}
|
|
56
|
+
if (value.startsWith("/") && !value.startsWith("//")) {
|
|
57
|
+
const segments = value.slice(1).split("/");
|
|
58
|
+
return segments.length > 0 && segments.every(isValidPathSegment);
|
|
59
|
+
}
|
|
60
|
+
if (WINDOWS_DRIVE_ABSOLUTE_PATH.test(value)) {
|
|
61
|
+
const segments = value.slice(3).split(/[\\/]/u);
|
|
62
|
+
return segments.length > 0 && segments.every(isValidPathSegment);
|
|
63
|
+
}
|
|
64
|
+
if (WINDOWS_UNC_ABSOLUTE_PATH.test(value)) {
|
|
65
|
+
const segments = value.slice(2).split(/[\\/]/u);
|
|
66
|
+
return segments.length >= 3 && segments.every(isValidPathSegment);
|
|
67
|
+
}
|
|
68
|
+
return false;
|
|
69
|
+
}
|
|
70
|
+
function normalizeExperimentalLiveFileTarget(value) {
|
|
71
|
+
if (!isJsonObject(value) || typeof value.kind !== "string") return null;
|
|
72
|
+
switch (value.kind) {
|
|
73
|
+
case "workspace":
|
|
74
|
+
if (!hasExactKeys(value, ["kind", "environmentId", "path"]) || !isNonEmptyIdentity(value.environmentId) || !isValidRelativeFilePath(value.path)) {
|
|
75
|
+
return null;
|
|
76
|
+
}
|
|
77
|
+
return {
|
|
78
|
+
kind: value.kind,
|
|
79
|
+
environmentId: value.environmentId,
|
|
80
|
+
path: value.path
|
|
81
|
+
};
|
|
82
|
+
case "host":
|
|
83
|
+
if (!hasExactKeys(value, ["kind", "hostId", "path"]) || !isNonEmptyIdentity(value.hostId) || !isValidAbsoluteHostFilePath(value.path)) {
|
|
84
|
+
return null;
|
|
85
|
+
}
|
|
86
|
+
return { kind: value.kind, hostId: value.hostId, path: value.path };
|
|
87
|
+
case "thread-storage":
|
|
88
|
+
if (!hasExactKeys(value, ["kind", "threadId", "path"]) || !isNonEmptyIdentity(value.threadId) || !isValidRelativeFilePath(value.path)) {
|
|
89
|
+
return null;
|
|
90
|
+
}
|
|
91
|
+
return { kind: value.kind, threadId: value.threadId, path: value.path };
|
|
92
|
+
default:
|
|
93
|
+
return null;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
function normalizeExperimentalFileLocation(value) {
|
|
97
|
+
if (value === null) return null;
|
|
98
|
+
if (!isJsonObject(value) || typeof value.kind !== "string") return void 0;
|
|
99
|
+
switch (value.kind) {
|
|
100
|
+
case "line":
|
|
101
|
+
if (!hasExactKeys(value, ["kind", "line", "column"]) || !isPositiveSafeInteger(value.line) || value.column !== null && !isPositiveSafeInteger(value.column)) {
|
|
102
|
+
return void 0;
|
|
103
|
+
}
|
|
104
|
+
return {
|
|
105
|
+
kind: value.kind,
|
|
106
|
+
line: value.line,
|
|
107
|
+
column: value.column
|
|
108
|
+
};
|
|
109
|
+
case "range":
|
|
110
|
+
if (!hasExactKeys(value, ["kind", "startLine", "endLine"]) || !isPositiveSafeInteger(value.startLine) || !isPositiveSafeInteger(value.endLine) || value.endLine < value.startLine) {
|
|
111
|
+
return void 0;
|
|
112
|
+
}
|
|
113
|
+
return {
|
|
114
|
+
kind: value.kind,
|
|
115
|
+
startLine: value.startLine,
|
|
116
|
+
endLine: value.endLine
|
|
117
|
+
};
|
|
118
|
+
default:
|
|
119
|
+
return void 0;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
function normalizeExperimentalFileOpenOptions(value) {
|
|
123
|
+
if (!isJsonObject(value) || !hasExactKeys(value, ["target", "location"])) {
|
|
124
|
+
return null;
|
|
125
|
+
}
|
|
126
|
+
const target = normalizeExperimentalLiveFileTarget(value.target);
|
|
127
|
+
const location = normalizeExperimentalFileLocation(value.location);
|
|
128
|
+
if (target === null || location === void 0) return null;
|
|
129
|
+
return { target, location };
|
|
130
|
+
}
|
|
131
|
+
export {
|
|
132
|
+
normalizeExperimentalFileLocation,
|
|
133
|
+
normalizeExperimentalFileOpenOptions,
|
|
134
|
+
normalizeExperimentalLiveFileTarget
|
|
135
|
+
};
|
|
@@ -54,6 +54,7 @@ var PLUGIN_AGENT_DYNAMIC_INSTRUCTIONS_MAX_CHARS = 4096;
|
|
|
54
54
|
var PLUGIN_AGENT_TOOL_PARAMETERS_MAX_BYTES = 128 * 1024;
|
|
55
55
|
var MENTION_PROVIDER_ID_PATTERN = /^[a-zA-Z0-9_-]+$/;
|
|
56
56
|
var PROVIDER_ID_PATTERN = /^[a-z0-9][a-z0-9-]{1,63}$/;
|
|
57
|
+
var PLUGIN_PROVIDER_BRIDGE_OPTIONS_MAX_BYTES = 64 * 1024;
|
|
57
58
|
var SETTING_KEY_PATTERN = /^[a-zA-Z0-9_-]+$/;
|
|
58
59
|
var settingsBaseFields = {
|
|
59
60
|
label: z2.string().min(1),
|
|
@@ -255,6 +256,70 @@ function validateProviderLiteralArray(args) {
|
|
|
255
256
|
}
|
|
256
257
|
return Object.freeze(normalized);
|
|
257
258
|
}
|
|
259
|
+
function normalizeProviderBridgeOptions(providerId, value) {
|
|
260
|
+
const active = /* @__PURE__ */ new Set();
|
|
261
|
+
function visit(current, path) {
|
|
262
|
+
if (current === null || typeof current === "string" || typeof current === "boolean") {
|
|
263
|
+
return current;
|
|
264
|
+
}
|
|
265
|
+
if (typeof current === "number") {
|
|
266
|
+
if (!Number.isFinite(current)) {
|
|
267
|
+
throw new Error(
|
|
268
|
+
`provider "${providerId}" experimental_bridgeOptions${path} must be finite JSON`
|
|
269
|
+
);
|
|
270
|
+
}
|
|
271
|
+
return current;
|
|
272
|
+
}
|
|
273
|
+
if (typeof current !== "object") {
|
|
274
|
+
throw new Error(
|
|
275
|
+
`provider "${providerId}" experimental_bridgeOptions${path} must be JSON`
|
|
276
|
+
);
|
|
277
|
+
}
|
|
278
|
+
if (active.has(current)) {
|
|
279
|
+
throw new Error(
|
|
280
|
+
`provider "${providerId}" experimental_bridgeOptions must not contain cycles`
|
|
281
|
+
);
|
|
282
|
+
}
|
|
283
|
+
active.add(current);
|
|
284
|
+
try {
|
|
285
|
+
if (Array.isArray(current)) {
|
|
286
|
+
const normalized3 = current.map(
|
|
287
|
+
(entry, index) => visit(entry, `${path}[${index}]`)
|
|
288
|
+
);
|
|
289
|
+
Object.freeze(normalized3);
|
|
290
|
+
return normalized3;
|
|
291
|
+
}
|
|
292
|
+
const prototype = Object.getPrototypeOf(current);
|
|
293
|
+
if (prototype !== Object.prototype && prototype !== null) {
|
|
294
|
+
throw new Error(
|
|
295
|
+
`provider "${providerId}" experimental_bridgeOptions${path} must contain only plain JSON objects`
|
|
296
|
+
);
|
|
297
|
+
}
|
|
298
|
+
const normalized2 = Object.fromEntries(
|
|
299
|
+
Object.entries(current).map(([key, entry]) => [
|
|
300
|
+
key,
|
|
301
|
+
visit(entry, `${path}.${key}`)
|
|
302
|
+
])
|
|
303
|
+
);
|
|
304
|
+
Object.freeze(normalized2);
|
|
305
|
+
return normalized2;
|
|
306
|
+
} finally {
|
|
307
|
+
active.delete(current);
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
const normalized = visit(value, "");
|
|
311
|
+
if (normalized === null || Array.isArray(normalized) || typeof normalized !== "object") {
|
|
312
|
+
throw new Error(
|
|
313
|
+
`provider "${providerId}" experimental_bridgeOptions must be an object`
|
|
314
|
+
);
|
|
315
|
+
}
|
|
316
|
+
if (Buffer.byteLength(JSON.stringify(normalized), "utf8") > PLUGIN_PROVIDER_BRIDGE_OPTIONS_MAX_BYTES) {
|
|
317
|
+
throw new Error(
|
|
318
|
+
`provider "${providerId}" experimental_bridgeOptions exceeds ${PLUGIN_PROVIDER_BRIDGE_OPTIONS_MAX_BYTES} bytes`
|
|
319
|
+
);
|
|
320
|
+
}
|
|
321
|
+
return normalized;
|
|
322
|
+
}
|
|
258
323
|
function validatePluginProviderDeclaration(declaration) {
|
|
259
324
|
if (typeof declaration !== "object" || declaration === null) {
|
|
260
325
|
throw new Error("provider declaration must be an object");
|
|
@@ -292,6 +357,24 @@ function validatePluginProviderDeclaration(declaration) {
|
|
|
292
357
|
if (typeof capabilities !== "object" || capabilities === null) {
|
|
293
358
|
throw new Error(`provider "${id}" capabilities must be an object`);
|
|
294
359
|
}
|
|
360
|
+
const experimentalProviderHealth = capabilities.experimental_providerHealth ?? false;
|
|
361
|
+
const experimentalProviderUsage = capabilities.experimental_providerUsage ?? false;
|
|
362
|
+
const experimentalProviderInstallation = capabilities.experimental_providerInstallation ?? false;
|
|
363
|
+
if (typeof experimentalProviderHealth !== "boolean") {
|
|
364
|
+
throw new Error(
|
|
365
|
+
`provider "${id}" capabilities.experimental_providerHealth must be a boolean`
|
|
366
|
+
);
|
|
367
|
+
}
|
|
368
|
+
if (typeof experimentalProviderUsage !== "boolean") {
|
|
369
|
+
throw new Error(
|
|
370
|
+
`provider "${id}" capabilities.experimental_providerUsage must be a boolean`
|
|
371
|
+
);
|
|
372
|
+
}
|
|
373
|
+
if (typeof experimentalProviderInstallation !== "boolean") {
|
|
374
|
+
throw new Error(
|
|
375
|
+
`provider "${id}" capabilities.experimental_providerInstallation must be a boolean`
|
|
376
|
+
);
|
|
377
|
+
}
|
|
295
378
|
const booleanCapabilityFields = [
|
|
296
379
|
"supportsServiceTier",
|
|
297
380
|
"supportsNativeUserQuestion",
|
|
@@ -313,6 +396,9 @@ function validatePluginProviderDeclaration(declaration) {
|
|
|
313
396
|
);
|
|
314
397
|
}
|
|
315
398
|
const normalizedCapabilities = Object.freeze({
|
|
399
|
+
experimental_providerHealth: experimentalProviderHealth,
|
|
400
|
+
experimental_providerUsage: experimentalProviderUsage,
|
|
401
|
+
experimental_providerInstallation: experimentalProviderInstallation,
|
|
316
402
|
supportsServiceTier: capabilities.supportsServiceTier,
|
|
317
403
|
supportsNativeUserQuestion: capabilities.supportsNativeUserQuestion,
|
|
318
404
|
fork: capabilities.fork,
|
|
@@ -342,10 +428,27 @@ function validatePluginProviderDeclaration(declaration) {
|
|
|
342
428
|
allowed: PLUGIN_PROVIDER_COMPOSER_ACTION_VALUES,
|
|
343
429
|
requireNonEmpty: false
|
|
344
430
|
});
|
|
431
|
+
const bridgeOptions = declaration.experimental_bridgeOptions === void 0 ? void 0 : normalizeProviderBridgeOptions(
|
|
432
|
+
id,
|
|
433
|
+
declaration.experimental_bridgeOptions
|
|
434
|
+
);
|
|
435
|
+
const visibility = declaration.experimental_visibility ?? "always";
|
|
436
|
+
if (visibility !== "always" && visibility !== "installed") {
|
|
437
|
+
throw new Error(
|
|
438
|
+
`provider "${id}" experimental_visibility must be "always" or "installed"`
|
|
439
|
+
);
|
|
440
|
+
}
|
|
441
|
+
if (visibility === "installed" && !normalizedCapabilities.experimental_providerHealth) {
|
|
442
|
+
throw new Error(
|
|
443
|
+
`provider "${id}" experimental_visibility "installed" requires experimental_providerHealth`
|
|
444
|
+
);
|
|
445
|
+
}
|
|
345
446
|
return Object.freeze({
|
|
346
447
|
id,
|
|
347
448
|
displayName,
|
|
348
449
|
...icon === void 0 ? {} : { icon },
|
|
450
|
+
...bridgeOptions === void 0 ? {} : { experimental_bridgeOptions: bridgeOptions },
|
|
451
|
+
experimental_visibility: visibility,
|
|
349
452
|
capabilities: normalizedCapabilities,
|
|
350
453
|
composerActions
|
|
351
454
|
});
|
|
@@ -608,6 +711,7 @@ export {
|
|
|
608
711
|
PLUGIN_AGENT_TOOL_PARAMETERS_MAX_BYTES,
|
|
609
712
|
PLUGIN_HTTP_METHODS,
|
|
610
713
|
PLUGIN_MENTION_TRIGGER_VALUES,
|
|
714
|
+
PLUGIN_PROVIDER_BRIDGE_OPTIONS_MAX_BYTES,
|
|
611
715
|
PLUGIN_PROVIDER_COMPOSER_ACTION_VALUES,
|
|
612
716
|
PLUGIN_PROVIDER_DISPLAY_NAME_MAX_CHARS,
|
|
613
717
|
PLUGIN_PROVIDER_PERMISSION_MODE_VALUES,
|
|
@@ -217,6 +217,8 @@ function collectPluginAppRegistrations(definition, onComposerCustomizationReject
|
|
|
217
217
|
threadLists: [],
|
|
218
218
|
threadHeaderActions: [],
|
|
219
219
|
fileOpeners: [],
|
|
220
|
+
sourceCodeRenderers: [],
|
|
221
|
+
diffRenderers: [],
|
|
220
222
|
messageDirectives: [],
|
|
221
223
|
messageActions: [],
|
|
222
224
|
providerIcons: [],
|
|
@@ -234,6 +236,8 @@ function collectPluginAppRegistrations(definition, onComposerCustomizationReject
|
|
|
234
236
|
threadList: /* @__PURE__ */ new Set(),
|
|
235
237
|
threadHeaderAction: /* @__PURE__ */ new Set(),
|
|
236
238
|
fileOpener: /* @__PURE__ */ new Set(),
|
|
239
|
+
sourceCodeRenderer: /* @__PURE__ */ new Set(),
|
|
240
|
+
diffRenderer: /* @__PURE__ */ new Set(),
|
|
237
241
|
messageDirective: /* @__PURE__ */ new Set(),
|
|
238
242
|
messageAction: /* @__PURE__ */ new Set(),
|
|
239
243
|
providerIcon: /* @__PURE__ */ new Set(),
|
|
@@ -272,6 +276,7 @@ function collectPluginAppRegistrations(definition, onComposerCustomizationReject
|
|
|
272
276
|
const kind = "slots.navPanel";
|
|
273
277
|
const id = requireSlotId(kind, registration?.id);
|
|
274
278
|
requireUniqueId(kind, seenIds.navPanel, id);
|
|
279
|
+
const panelId = id;
|
|
275
280
|
const path = requireNonEmptyString(kind, "path", registration.path);
|
|
276
281
|
if (!PLUGIN_SLOT_ID_PATTERN.test(path)) {
|
|
277
282
|
throw new Error(
|
|
@@ -307,8 +312,25 @@ function collectPluginAppRegistrations(definition, onComposerCustomizationReject
|
|
|
307
312
|
`${fixedTabKind}: "layout" must be "padded" or "flush" when set`
|
|
308
313
|
);
|
|
309
314
|
}
|
|
315
|
+
const fixedTabPanelId = requireNonEmptyString(
|
|
316
|
+
fixedTabKind,
|
|
317
|
+
"panelId",
|
|
318
|
+
fixedTab?.panelId
|
|
319
|
+
);
|
|
320
|
+
if (fixedTabPanelId !== panelId) {
|
|
321
|
+
throw new Error(
|
|
322
|
+
`${fixedTabKind}: "panelId" must match its containing navPanel id ${JSON.stringify(panelId)}`
|
|
323
|
+
);
|
|
324
|
+
}
|
|
325
|
+
const experimentalTarget = fixedTab?.experimental_target;
|
|
326
|
+
if (experimentalTarget !== void 0 && (typeof experimentalTarget !== "object" || experimentalTarget === null || typeof Reflect.get(experimentalTarget, "validate") !== "function")) {
|
|
327
|
+
throw new Error(
|
|
328
|
+
`${fixedTabKind}: "experimental_target.validate" must be a function when set`
|
|
329
|
+
);
|
|
330
|
+
}
|
|
310
331
|
return {
|
|
311
332
|
id: id2,
|
|
333
|
+
panelId: fixedTabPanelId,
|
|
312
334
|
title: requireNonEmptyString(
|
|
313
335
|
fixedTabKind,
|
|
314
336
|
"title",
|
|
@@ -320,7 +342,10 @@ function collectPluginAppRegistrations(definition, onComposerCustomizationReject
|
|
|
320
342
|
fixedTab?.icon
|
|
321
343
|
),
|
|
322
344
|
component: requireComponent(fixedTabKind, fixedTab?.component),
|
|
323
|
-
...layout === void 0 ? {} : { layout }
|
|
345
|
+
...layout === void 0 ? {} : { layout },
|
|
346
|
+
...experimentalTarget === void 0 ? {} : {
|
|
347
|
+
experimental_target: experimentalTarget
|
|
348
|
+
}
|
|
324
349
|
};
|
|
325
350
|
});
|
|
326
351
|
})();
|
|
@@ -453,6 +478,38 @@ function collectPluginAppRegistrations(definition, onComposerCustomizationReject
|
|
|
453
478
|
component: requireComponent(kind, registration.component)
|
|
454
479
|
});
|
|
455
480
|
},
|
|
481
|
+
experimental_sourceCodeRenderer(registration) {
|
|
482
|
+
const kind = "slots.experimental_sourceCodeRenderer";
|
|
483
|
+
const id = requireSlotId(kind, registration?.id);
|
|
484
|
+
requireUniqueId(kind, seenIds.sourceCodeRenderer, id);
|
|
485
|
+
const description = requireOptionalString(
|
|
486
|
+
kind,
|
|
487
|
+
"description",
|
|
488
|
+
registration.description
|
|
489
|
+
);
|
|
490
|
+
collected.sourceCodeRenderers.push({
|
|
491
|
+
id,
|
|
492
|
+
title: requireNonEmptyString(kind, "title", registration.title),
|
|
493
|
+
...description !== void 0 ? { description } : {},
|
|
494
|
+
component: requireComponent(kind, registration.component)
|
|
495
|
+
});
|
|
496
|
+
},
|
|
497
|
+
experimental_diffRenderer(registration) {
|
|
498
|
+
const kind = "slots.experimental_diffRenderer";
|
|
499
|
+
const id = requireSlotId(kind, registration?.id);
|
|
500
|
+
requireUniqueId(kind, seenIds.diffRenderer, id);
|
|
501
|
+
const description = requireOptionalString(
|
|
502
|
+
kind,
|
|
503
|
+
"description",
|
|
504
|
+
registration.description
|
|
505
|
+
);
|
|
506
|
+
collected.diffRenderers.push({
|
|
507
|
+
id,
|
|
508
|
+
title: requireNonEmptyString(kind, "title", registration.title),
|
|
509
|
+
...description !== void 0 ? { description } : {},
|
|
510
|
+
component: requireComponent(kind, registration.component)
|
|
511
|
+
});
|
|
512
|
+
},
|
|
456
513
|
messageDirective(registration) {
|
|
457
514
|
const kind = "slots.messageDirective";
|
|
458
515
|
const id = requireMessageDirectiveId(kind, registration?.id);
|