@standhigher/puck-page-builder 0.8.1 → 0.10.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/README.md +25 -0
- package/dist/{chunk-PUTYZI7B.js → chunk-PFCWXLWN.js} +117 -2
- package/dist/extensions.d.ts +18 -183
- package/dist/extensions.js +15 -3
- package/dist/index.d.ts +199 -9
- package/dist/index.js +484 -132
- package/dist/registry-eNtkEC6o.d.ts +221 -0
- package/dist/renderer.d.ts +1 -1
- package/dist/runtime.d.ts +2 -1
- package/dist/runtime.js +15 -3
- package/package.json +1 -1
- package/src/styles.css +12 -1
package/README.md
CHANGED
|
@@ -44,6 +44,31 @@ const page = <WebRenderer document={migration.data} registry={registry} />;
|
|
|
44
44
|
| `@standhigher/puck-page-builder/schema` | schema-specific types and migration helpers |
|
|
45
45
|
| `@standhigher/puck-page-builder/styles.css` | Builder and Web renderer styles |
|
|
46
46
|
|
|
47
|
+
## Editor policies and field validation
|
|
48
|
+
|
|
49
|
+
Blocks can declare portable interaction and cardinality rules. `required` keeps at least one instance; `singleton` prevents a second instance. Hosts can supplement those declarations with `PageDocumentEditorShell`'s `policy` prop, including globally disabling add, delete, duplicate, or drag operations. Deletion through the packaged editor always opens its built-in confirmation dialog before changing the document.
|
|
50
|
+
|
|
51
|
+
```tsx
|
|
52
|
+
const notice = {
|
|
53
|
+
// ...the normal BlockDefinition fields
|
|
54
|
+
policy: { singleton: true, allowDuplicate: false },
|
|
55
|
+
fields: {
|
|
56
|
+
title: { field: "acme.text", control: "text", required: true, validation: { maxLength: 80 } },
|
|
57
|
+
color: { field: "acme.color", control: "color" }
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
<PageDocumentEditorShell
|
|
62
|
+
initialDocument={document}
|
|
63
|
+
registry={registry}
|
|
64
|
+
policy={{ operations: { allowDrag: false } }}
|
|
65
|
+
/>
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Built-in field controls are `text` (single line), `textarea` (multi-line), `url`, and `color`. Their validation runs in the editor before save or publish; custom fields may continue using a block's `validate` function. `validateFieldValue` is exported from `/extensions` when a host needs the same validation outside the editor.
|
|
69
|
+
|
|
70
|
+
Theme values remain deliberately token-based: template theme → page theme → variant theme → block style. A block resets an inherited token by setting its local token explicitly (for example `{ radius: "0" }`), so no incompatible persisted style-reset shape is needed.
|
|
71
|
+
|
|
47
72
|
## Runtime and DataSource boundary
|
|
48
73
|
|
|
49
74
|
The package can register DataSources but does not automatically resolve `block.binding`, call a Live data source, or inject its result into `WebRenderer`. Implement authorization, data resolution, caching, error handling and temporary render-data projection in the host application's server-side Runtime. Do not persist tokens, credentials or resolved private data in `PageDocument`.
|
|
@@ -1,3 +1,54 @@
|
|
|
1
|
+
// src/core/extensions/validation.ts
|
|
2
|
+
var hexColor = /^#(?:[\da-f]{3}|[\da-f]{4}|[\da-f]{6}|[\da-f]{8})$/i;
|
|
3
|
+
function stringLength(value) {
|
|
4
|
+
return Array.from(value).length;
|
|
5
|
+
}
|
|
6
|
+
function isSafeUrl(value, config) {
|
|
7
|
+
if (value.startsWith("/")) return config.validation?.allowRelativeUrl !== false && !value.startsWith("//");
|
|
8
|
+
try {
|
|
9
|
+
const url = new URL(value);
|
|
10
|
+
if (url.username || url.password) return false;
|
|
11
|
+
if ((config.validation?.allowedUrlProtocols ?? ["https:", "http:"]).includes(url.protocol)) return true;
|
|
12
|
+
const editorRunsLocally = typeof window !== "undefined" && (window.location.hostname === "localhost" || window.location.hostname === "127.0.0.1" || window.location.hostname === "[::1]");
|
|
13
|
+
return config.validation?.allowLocalhost === true && editorRunsLocally && url.protocol === "http:" && (url.hostname === "localhost" || url.hostname === "127.0.0.1" || url.hostname === "[::1]");
|
|
14
|
+
} catch {
|
|
15
|
+
return false;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
function validateFieldValue(config, value) {
|
|
19
|
+
const control = config.control;
|
|
20
|
+
if (!control && !config.required && !config.validation) return [];
|
|
21
|
+
if (value === void 0 && !config.required) return [];
|
|
22
|
+
if (typeof value !== "string") return [{ path: "", message: "\u5FC5\u987B\u662F\u5B57\u7B26\u4E32\u3002" }];
|
|
23
|
+
const issues = [];
|
|
24
|
+
if (config.required && value.trim().length === 0) issues.push({ path: "", message: "\u6B64\u5B57\u6BB5\u4E3A\u5FC5\u586B\u9879\u3002" });
|
|
25
|
+
if (control === "text" && /[\r\n]/.test(value)) issues.push({ path: "", message: "\u5FC5\u987B\u4E3A\u5355\u884C\u6587\u672C\u3002" });
|
|
26
|
+
if (config.validation?.minLength !== void 0 && stringLength(value) < config.validation.minLength) issues.push({ path: "", message: `\u81F3\u5C11\u9700\u8981 ${config.validation.minLength} \u4E2A\u5B57\u7B26\u3002` });
|
|
27
|
+
if (config.validation?.maxLength !== void 0 && stringLength(value) > config.validation.maxLength) issues.push({ path: "", message: `\u6700\u591A\u5141\u8BB8 ${config.validation.maxLength} \u4E2A\u5B57\u7B26\u3002` });
|
|
28
|
+
if (value && control === "url" && !isSafeUrl(value, config)) issues.push({ path: "", message: "\u5FC5\u987B\u662F\u7AD9\u5185\u76F8\u5BF9\u8DEF\u5F84\u6216\u5141\u8BB8\u7684 HTTP(S) URL\u3002" });
|
|
29
|
+
if (value && control === "color" && !hexColor.test(value)) issues.push({ path: "", message: "\u5FC5\u987B\u662F\u5341\u516D\u8FDB\u5236\u989C\u8272\uFF0C\u4F8B\u5982 #005BD3\u3002" });
|
|
30
|
+
return issues;
|
|
31
|
+
}
|
|
32
|
+
function validateBlockPolicy(policy) {
|
|
33
|
+
if (!policy) return null;
|
|
34
|
+
for (const key of ["minInstances", "maxInstances"]) {
|
|
35
|
+
const value = policy[key];
|
|
36
|
+
if (value !== void 0 && (!Number.isInteger(value) || value < 0)) return `${key} \u5FC5\u987B\u662F\u5927\u4E8E\u6216\u7B49\u4E8E 0 \u7684\u6574\u6570`;
|
|
37
|
+
}
|
|
38
|
+
const minimum = Math.max(policy.required ? 1 : 0, policy.minInstances ?? 0);
|
|
39
|
+
const maximum = Math.min(policy.singleton ? 1 : Infinity, policy.maxInstances ?? Infinity);
|
|
40
|
+
return minimum > maximum ? "minInstances \u4E0D\u80FD\u5927\u4E8E maxInstances" : null;
|
|
41
|
+
}
|
|
42
|
+
function mergeBlockPolicies(...policies) {
|
|
43
|
+
return Object.assign({}, ...policies);
|
|
44
|
+
}
|
|
45
|
+
function minimumBlockInstances(policy) {
|
|
46
|
+
return Math.max(policy?.required ? 1 : 0, policy?.minInstances ?? 0);
|
|
47
|
+
}
|
|
48
|
+
function maximumBlockInstances(policy) {
|
|
49
|
+
return Math.min(policy?.singleton ? 1 : Infinity, policy?.maxInstances ?? Infinity);
|
|
50
|
+
}
|
|
51
|
+
|
|
1
52
|
// src/core/extensions/registry.ts
|
|
2
53
|
var ExtensionRegistryError = class extends Error {
|
|
3
54
|
constructor(code, message) {
|
|
@@ -163,7 +214,11 @@ var ExtensionRegistry = class _ExtensionRegistry {
|
|
|
163
214
|
const templateItems = [];
|
|
164
215
|
const slots = /* @__PURE__ */ new Map();
|
|
165
216
|
for (const extension of resolved) {
|
|
166
|
-
for (const block of extension.blocks ?? [])
|
|
217
|
+
for (const block of extension.blocks ?? []) {
|
|
218
|
+
assertTargets(block.targets, `Block ${block.type}`);
|
|
219
|
+
const policyIssue = validateBlockPolicy(block.policy);
|
|
220
|
+
if (policyIssue) throw new ExtensionRegistryError("invalid-block-policy", `Block ${block.type} \u7684\u7B56\u7565\u65E0\u6548\uFF1A${policyIssue}`);
|
|
221
|
+
}
|
|
167
222
|
register(blockItems, extension.blocks, extension.name, blocks, "Block");
|
|
168
223
|
register(fieldItems, extension.fields, extension.name, fields, "Field");
|
|
169
224
|
register(actionItems, extension.actions, extension.name, actions, "Action");
|
|
@@ -204,10 +259,70 @@ function createTemplateRegistry(templates, blocks = []) {
|
|
|
204
259
|
return TemplateRegistry.create(registered, blocks);
|
|
205
260
|
}
|
|
206
261
|
|
|
262
|
+
// src/core/extensions/document-validation.ts
|
|
263
|
+
var coreBlockProps = {
|
|
264
|
+
"core.text": ["content"],
|
|
265
|
+
"core.image": ["src", "alt"]
|
|
266
|
+
};
|
|
267
|
+
function supportsTarget(block, target) {
|
|
268
|
+
return block.targets.includes("all") || block.targets.includes(target);
|
|
269
|
+
}
|
|
270
|
+
function validateBlock(document, index, registry) {
|
|
271
|
+
const block = document.blocks[index];
|
|
272
|
+
const path = `blocks[${index}]`;
|
|
273
|
+
const definition = registry.getBlock(block.type);
|
|
274
|
+
const coreProps = coreBlockProps[block.type];
|
|
275
|
+
if (!definition && !coreProps) return [{ path, message: `\u672A\u6CE8\u518C\u533A\u5757\uFF1A${block.type}` }];
|
|
276
|
+
if (!definition) {
|
|
277
|
+
return Object.keys(block.props).filter((key) => !coreProps.includes(key)).map((key) => ({ path: `${path}.props.${key}`, message: "\u4E0D\u5141\u8BB8\u4FDD\u5B58\u672A\u77E5\u5B57\u6BB5\u3002" }));
|
|
278
|
+
}
|
|
279
|
+
const issues = [];
|
|
280
|
+
if (block.version !== definition.version) issues.push({ path: `${path}.version`, message: `\u533A\u5757\u7248\u672C\u5FC5\u987B\u4E3A ${definition.version}\u3002` });
|
|
281
|
+
if (!supportsTarget(definition, document.target)) issues.push({ path, message: `\u533A\u5757\u4E0D\u652F\u6301 ${document.target} target\u3002` });
|
|
282
|
+
if (definition.variants?.length && !definition.variants.some((variant) => variant.id === block.variant)) issues.push({ path: `${path}.variant`, message: `\u4E0D\u652F\u6301\u7684 variant\uFF1A${block.variant}\u3002` });
|
|
283
|
+
const allowedProps = /* @__PURE__ */ new Set([...Object.keys(definition.defaultProps), ...Object.keys(definition.fields)]);
|
|
284
|
+
for (const key of Object.keys(block.props)) {
|
|
285
|
+
if (!allowedProps.has(key)) issues.push({ path: `${path}.props.${key}`, message: "\u4E0D\u5141\u8BB8\u4FDD\u5B58\u672A\u77E5\u5B57\u6BB5\u3002" });
|
|
286
|
+
}
|
|
287
|
+
for (const [name, field] of Object.entries(definition.fields)) {
|
|
288
|
+
for (const issue of validateFieldValue(field, block.props[name])) {
|
|
289
|
+
issues.push({ ...issue, path: issue.path ? `${path}.props.${name}.${issue.path}` : `${path}.props.${name}` });
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
for (const issue of definition.validate?.(block.props) ?? []) {
|
|
293
|
+
const suffix = issue.path.startsWith("props.") ? issue.path.slice("props.".length) : issue.path;
|
|
294
|
+
issues.push({ ...issue, path: `${path}.props.${suffix}` });
|
|
295
|
+
}
|
|
296
|
+
if (block.binding) {
|
|
297
|
+
const source = registry.getDataSource(block.binding.source);
|
|
298
|
+
if (!source) issues.push({ path: `${path}.binding.source`, message: `\u672A\u6CE8\u518C\u6570\u636E\u6E90\uFF1A${block.binding.source}` });
|
|
299
|
+
else {
|
|
300
|
+
if (!definition.dataSources?.includes(source.key)) issues.push({ path: `${path}.binding.source`, message: "\u533A\u5757\u672A\u6388\u6743\u4F7F\u7528\u6B64\u6570\u636E\u6E90\u3002" });
|
|
301
|
+
for (const issue of source.validateParams?.(block.binding.params ?? {}) ?? []) {
|
|
302
|
+
issues.push({ ...issue, path: issue.path ? `${path}.binding.params.${issue.path}` : `${path}.binding.params` });
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
return issues;
|
|
307
|
+
}
|
|
308
|
+
function validatePageDocumentWithRegistry(document, registry) {
|
|
309
|
+
const issues = [];
|
|
310
|
+
if (document.templateId && !registry.getTemplate(document.templateId)) issues.push({ path: "templateId", message: `\u672A\u6CE8\u518C\u6A21\u677F\uFF1A${document.templateId}` });
|
|
311
|
+
if (document.templateId && document.templateVersion !== registry.getTemplate(document.templateId)?.version) issues.push({ path: "templateVersion", message: "\u6A21\u677F\u7248\u672C\u4E0E\u5DF2\u6CE8\u518C\u6A21\u677F\u4E0D\u4E00\u81F4\u3002" });
|
|
312
|
+
document.blocks.forEach((_, index) => issues.push(...validateBlock(document, index, registry)));
|
|
313
|
+
return issues;
|
|
314
|
+
}
|
|
315
|
+
|
|
207
316
|
export {
|
|
317
|
+
validateFieldValue,
|
|
318
|
+
validateBlockPolicy,
|
|
319
|
+
mergeBlockPolicies,
|
|
320
|
+
minimumBlockInstances,
|
|
321
|
+
maximumBlockInstances,
|
|
208
322
|
ExtensionRegistryError,
|
|
209
323
|
TemplateRegistry,
|
|
210
324
|
ExtensionRegistry,
|
|
211
325
|
createExtensionRegistry,
|
|
212
|
-
createTemplateRegistry
|
|
326
|
+
createTemplateRegistry,
|
|
327
|
+
validatePageDocumentWithRegistry
|
|
213
328
|
};
|
package/dist/extensions.d.ts
CHANGED
|
@@ -1,188 +1,23 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
import {
|
|
1
|
+
import { h as ExtensionRegistry, V as ValidationIssue, c as BlockPolicy, F as FieldConfig } from './registry-eNtkEC6o.js';
|
|
2
|
+
export { B as BlockDefinition, a as BlockEditorProps, b as BlockOperation, d as BlockVariantDefinition, D as DataSourceDefinition, E as EditorAction, e as EditorActionPosition, f as EditorOperationPolicy, g as ExtensionActionContext, i as ExtensionRegistryError, j as ExtensionRegistryErrorCode, k as ExtensionRegistryOptions, l as ExtensionTarget, m as FieldDefinition, n as FieldProps, o as FieldValidation, L as LifecycleHooks, P as PageBuilderExtension, R as RendererDefinition, T as TemplateDefinition, p as TemplateRegistry, q as TemplateSource, U as UISlotContribution, r as UISlotName, s as createExtensionRegistry, t as createTemplateRegistry } from './registry-eNtkEC6o.js';
|
|
3
|
+
import { PageDocument } from './schema.js';
|
|
4
|
+
import 'react';
|
|
5
|
+
import './theme.js';
|
|
4
6
|
|
|
5
|
-
type ExtensionTarget = RenderTarget | "all";
|
|
6
|
-
type EditorActionPosition = "left" | "center" | "right";
|
|
7
|
-
type UISlotName = "toolbar.left" | "toolbar.center" | "toolbar.right" | "inspector.content";
|
|
8
|
-
type ValidationIssue = {
|
|
9
|
-
path: string;
|
|
10
|
-
message: string;
|
|
11
|
-
};
|
|
12
|
-
type FieldConfig = {
|
|
13
|
-
field: string;
|
|
14
|
-
label?: string;
|
|
15
|
-
/** Product-facing editor metadata. Custom field components remain supported. */
|
|
16
|
-
control?: "text" | "textarea" | "url";
|
|
17
|
-
description?: string;
|
|
18
|
-
group?: string;
|
|
19
|
-
required?: boolean;
|
|
20
|
-
};
|
|
21
|
-
type FieldProps<T = unknown> = {
|
|
22
|
-
value: T;
|
|
23
|
-
onChange(value: T): void;
|
|
24
|
-
};
|
|
25
7
|
/**
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
8
|
+
* Validates a structurally valid PageDocument against a concrete extension
|
|
9
|
+
* registry. Hosts should use it at draft and publish boundaries after
|
|
10
|
+
* migratePageDocument so unregistered blocks and undeclared props cannot
|
|
11
|
+
* enter persistent storage.
|
|
29
12
|
*/
|
|
30
|
-
|
|
31
|
-
blockId: string;
|
|
32
|
-
selected: boolean;
|
|
33
|
-
onPropsChange(props: Record<string, JsonValue>): void;
|
|
34
|
-
};
|
|
35
|
-
interface BlockDefinition<P = Record<string, unknown>> {
|
|
36
|
-
type: string;
|
|
37
|
-
version: number;
|
|
38
|
-
label: string;
|
|
39
|
-
category: string;
|
|
40
|
-
targets: ExtensionTarget[];
|
|
41
|
-
defaultProps: P;
|
|
42
|
-
fields: Record<string, FieldConfig>;
|
|
43
|
-
render: Partial<Record<RenderTarget, ComponentType<P>>> & {
|
|
44
|
-
/** Optional edit-mode renderer. WebRenderer never uses this surface. */
|
|
45
|
-
editor?: ComponentType<BlockEditorProps<P>>;
|
|
46
|
-
};
|
|
47
|
-
defaultVariant?: string;
|
|
48
|
-
variants?: BlockVariantDefinition[];
|
|
49
|
-
dataSources?: string[];
|
|
50
|
-
validate?: (props: P) => ValidationIssue[];
|
|
51
|
-
}
|
|
52
|
-
interface BlockVariantDefinition {
|
|
53
|
-
id: string;
|
|
54
|
-
label: string;
|
|
55
|
-
theme?: ThemeTokens;
|
|
56
|
-
}
|
|
57
|
-
interface FieldDefinition<T = unknown> {
|
|
58
|
-
type: string;
|
|
59
|
-
component: ComponentType<FieldProps<T>>;
|
|
60
|
-
normalize?: (value: T) => T;
|
|
61
|
-
validate?: (value: T) => ValidationIssue[];
|
|
62
|
-
}
|
|
63
|
-
type ExtensionActionContext = {
|
|
64
|
-
document: PageDocument;
|
|
65
|
-
pageId: string;
|
|
66
|
-
notify?(message: string): void;
|
|
67
|
-
};
|
|
68
|
-
interface EditorAction {
|
|
69
|
-
id: string;
|
|
70
|
-
label: string;
|
|
71
|
-
position: EditorActionPosition;
|
|
72
|
-
order?: number;
|
|
73
|
-
variant?: "default" | "primary" | "danger";
|
|
74
|
-
hidden?: (context: ExtensionActionContext) => boolean;
|
|
75
|
-
disabled?: (context: ExtensionActionContext) => boolean;
|
|
76
|
-
execute(context: ExtensionActionContext): Promise<void> | void;
|
|
77
|
-
}
|
|
78
|
-
interface RendererDefinition {
|
|
79
|
-
id: string;
|
|
80
|
-
target: RenderTarget;
|
|
81
|
-
render(document: PageDocument): ReactNode | string;
|
|
82
|
-
}
|
|
83
|
-
/**
|
|
84
|
-
* `P` defaults to `any` so an extension may contribute a narrower, validated
|
|
85
|
-
* parameter type while the framework-independent registry remains generic.
|
|
86
|
-
*/
|
|
87
|
-
interface DataSourceDefinition<P = any, R = unknown> {
|
|
88
|
-
key: string;
|
|
89
|
-
mock: (params: P) => Promise<R>;
|
|
90
|
-
live: (params: P) => Promise<R>;
|
|
91
|
-
validateParams?: (params: P) => ValidationIssue[];
|
|
92
|
-
}
|
|
93
|
-
type TemplateSource = "built-in" | "marketplace" | "custom";
|
|
94
|
-
interface TemplateDefinition {
|
|
95
|
-
id: string;
|
|
96
|
-
version: number;
|
|
97
|
-
name: string;
|
|
98
|
-
target: RenderTarget;
|
|
99
|
-
source: TemplateSource;
|
|
100
|
-
thumbnail?: string;
|
|
101
|
-
create(): PageDocument;
|
|
102
|
-
/** Block types that must be registered before this template can be used. */
|
|
103
|
-
requiredBlocks?: string[];
|
|
104
|
-
theme?: ThemeTokens;
|
|
105
|
-
}
|
|
106
|
-
interface LifecycleHooks {
|
|
107
|
-
onChange?(document: PageDocument): void;
|
|
108
|
-
beforeSave?(document: PageDocument): Promise<PageDocument>;
|
|
109
|
-
afterSave?(result: unknown): Promise<void>;
|
|
110
|
-
beforePublish?(document: PageDocument): Promise<PageDocument>;
|
|
111
|
-
afterPublish?(result: unknown): Promise<void>;
|
|
112
|
-
onError?(error: Error): void;
|
|
113
|
-
}
|
|
114
|
-
interface UISlotContribution {
|
|
115
|
-
id: string;
|
|
116
|
-
slot: UISlotName;
|
|
117
|
-
order?: number;
|
|
118
|
-
component: ComponentType;
|
|
119
|
-
}
|
|
120
|
-
interface PageBuilderExtension {
|
|
121
|
-
/** Namespaced, stable extension identifier, such as `besttrack.tracking`. */
|
|
122
|
-
name: string;
|
|
123
|
-
version: string;
|
|
124
|
-
order?: number;
|
|
125
|
-
dependsOn?: string[];
|
|
126
|
-
blocks?: BlockDefinition[];
|
|
127
|
-
fields?: FieldDefinition[];
|
|
128
|
-
actions?: EditorAction[];
|
|
129
|
-
renderers?: RendererDefinition[];
|
|
130
|
-
dataSources?: DataSourceDefinition[];
|
|
131
|
-
templates?: TemplateDefinition[];
|
|
132
|
-
hooks?: LifecycleHooks;
|
|
133
|
-
slots?: UISlotContribution[];
|
|
134
|
-
}
|
|
135
|
-
type ExtensionRegistryOptions = {
|
|
136
|
-
disabled?: string[];
|
|
137
|
-
};
|
|
13
|
+
declare function validatePageDocumentWithRegistry(document: PageDocument, registry: ExtensionRegistry): ValidationIssue[];
|
|
138
14
|
|
|
139
|
-
|
|
140
|
-
declare
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
};
|
|
147
|
-
/** Immutable template view with explicit source and block dependency validation. */
|
|
148
|
-
declare class TemplateRegistry {
|
|
149
|
-
private readonly templateMap;
|
|
150
|
-
private constructor();
|
|
151
|
-
get templates(): readonly Registered<TemplateDefinition>[];
|
|
152
|
-
get(id: string): Registered<TemplateDefinition> | undefined;
|
|
153
|
-
static create(templates: readonly Registered<TemplateDefinition>[], blocks: readonly BlockDefinition[]): TemplateRegistry;
|
|
154
|
-
}
|
|
155
|
-
/** Immutable compiled view of all enabled extensions. */
|
|
156
|
-
declare class ExtensionRegistry {
|
|
157
|
-
readonly extensions: readonly PageBuilderExtension[];
|
|
158
|
-
private readonly blockMap;
|
|
159
|
-
private readonly fieldMap;
|
|
160
|
-
private readonly actionMap;
|
|
161
|
-
private readonly rendererMap;
|
|
162
|
-
private readonly dataSourceMap;
|
|
163
|
-
private readonly templateMap;
|
|
164
|
-
readonly templateRegistry: TemplateRegistry;
|
|
165
|
-
private readonly slotMap;
|
|
166
|
-
private readonly hooks;
|
|
167
|
-
private constructor();
|
|
168
|
-
get blocks(): readonly Registered<BlockDefinition<Record<string, unknown>>>[];
|
|
169
|
-
get fields(): readonly Registered<FieldDefinition<unknown>>[];
|
|
170
|
-
get actions(): readonly Registered<EditorAction>[];
|
|
171
|
-
get renderers(): readonly Registered<RendererDefinition>[];
|
|
172
|
-
get dataSources(): readonly Registered<DataSourceDefinition<any, unknown>>[];
|
|
173
|
-
get templates(): readonly Registered<TemplateDefinition>[];
|
|
174
|
-
getBlock(type: string): Registered<BlockDefinition<Record<string, unknown>>> | undefined;
|
|
175
|
-
getField(type: string): Registered<FieldDefinition<unknown>> | undefined;
|
|
176
|
-
getAction(id: string): Registered<EditorAction> | undefined;
|
|
177
|
-
getRenderer(id: string): Registered<RendererDefinition> | undefined;
|
|
178
|
-
getDataSource(key: string): Registered<DataSourceDefinition<any, unknown>> | undefined;
|
|
179
|
-
getTemplate(id: string): Registered<TemplateDefinition> | undefined;
|
|
180
|
-
getSlot(slot: UISlotName): readonly Registered<UISlotContribution>[];
|
|
181
|
-
notifyChange(document: PageDocument): void;
|
|
182
|
-
notifyError(error: Error): void;
|
|
183
|
-
static create(extensions: PageBuilderExtension[], options?: ExtensionRegistryOptions): ExtensionRegistry;
|
|
184
|
-
}
|
|
185
|
-
declare function createExtensionRegistry(extensions: PageBuilderExtension[], options?: ExtensionRegistryOptions): ExtensionRegistry;
|
|
186
|
-
declare function createTemplateRegistry(templates: TemplateDefinition[], blocks?: BlockDefinition[]): TemplateRegistry;
|
|
15
|
+
/** Validates the portable built-in controls without relying on browser-only APIs. */
|
|
16
|
+
declare function validateFieldValue(config: FieldConfig, value: unknown): ValidationIssue[];
|
|
17
|
+
/** Returns a diagnostic for an invalid declaration, or `null` when it is usable. */
|
|
18
|
+
declare function validateBlockPolicy(policy: BlockPolicy | undefined): string | null;
|
|
19
|
+
declare function mergeBlockPolicies(...policies: Array<BlockPolicy | undefined>): BlockPolicy;
|
|
20
|
+
declare function minimumBlockInstances(policy: BlockPolicy | undefined): number;
|
|
21
|
+
declare function maximumBlockInstances(policy: BlockPolicy | undefined): number;
|
|
187
22
|
|
|
188
|
-
export {
|
|
23
|
+
export { BlockPolicy, ExtensionRegistry, FieldConfig, ValidationIssue, maximumBlockInstances, mergeBlockPolicies, minimumBlockInstances, validateBlockPolicy, validateFieldValue, validatePageDocumentWithRegistry };
|
package/dist/extensions.js
CHANGED
|
@@ -3,12 +3,24 @@ import {
|
|
|
3
3
|
ExtensionRegistryError,
|
|
4
4
|
TemplateRegistry,
|
|
5
5
|
createExtensionRegistry,
|
|
6
|
-
createTemplateRegistry
|
|
7
|
-
|
|
6
|
+
createTemplateRegistry,
|
|
7
|
+
maximumBlockInstances,
|
|
8
|
+
mergeBlockPolicies,
|
|
9
|
+
minimumBlockInstances,
|
|
10
|
+
validateBlockPolicy,
|
|
11
|
+
validateFieldValue,
|
|
12
|
+
validatePageDocumentWithRegistry
|
|
13
|
+
} from "./chunk-PFCWXLWN.js";
|
|
8
14
|
export {
|
|
9
15
|
ExtensionRegistry,
|
|
10
16
|
ExtensionRegistryError,
|
|
11
17
|
TemplateRegistry,
|
|
12
18
|
createExtensionRegistry,
|
|
13
|
-
createTemplateRegistry
|
|
19
|
+
createTemplateRegistry,
|
|
20
|
+
maximumBlockInstances,
|
|
21
|
+
mergeBlockPolicies,
|
|
22
|
+
minimumBlockInstances,
|
|
23
|
+
validateBlockPolicy,
|
|
24
|
+
validateFieldValue,
|
|
25
|
+
validatePageDocumentWithRegistry
|
|
14
26
|
};
|