@wp-typia/block-types 0.2.4 → 0.3.1
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 +309 -15
- package/dist/blocks/bindings-codegen.d.ts +13 -0
- package/dist/blocks/bindings-codegen.js +210 -0
- package/dist/blocks/bindings-core.d.ts +123 -0
- package/dist/blocks/bindings-core.js +351 -0
- package/dist/blocks/bindings.d.ts +2 -0
- package/dist/blocks/bindings.js +2 -0
- package/dist/blocks/compatibility.d.ts +296 -0
- package/dist/blocks/compatibility.js +338 -0
- package/dist/blocks/index.d.ts +3 -0
- package/dist/blocks/index.js +3 -0
- package/dist/blocks/shared/diagnostics.d.ts +13 -0
- package/dist/blocks/shared/diagnostics.js +19 -0
- package/dist/blocks/shared/object-utils.d.ts +2 -0
- package/dist/blocks/shared/object-utils.js +10 -0
- package/dist/blocks/shared/static-registration.d.ts +4 -0
- package/dist/blocks/shared/static-registration.js +32 -0
- package/dist/blocks/supports.d.ts +57 -2
- package/dist/blocks/supports.js +172 -0
- package/dist/blocks/variations.d.ts +87 -0
- package/dist/blocks/variations.js +258 -0
- package/package.json +16 -1
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import type { BlockAttributes } from "./registration.js";
|
|
2
|
+
import { type WordPressBlockApiCompatibilityDiagnostic, type WordPressBlockApiCompatibilityFeature, type WordPressBlockApiCompatibilityManifest, type WordPressCompatibilitySettings, type WordPressVersion } from "./compatibility.js";
|
|
3
|
+
import { type DiagnosticLogger } from "./shared/diagnostics.js";
|
|
4
|
+
export type BindingSourceName = `${string}/${string}`;
|
|
5
|
+
export type BindingSourceArgs = Readonly<Record<string, unknown>>;
|
|
6
|
+
export type BindingFieldType = "array" | "boolean" | "integer" | "number" | "object" | "string";
|
|
7
|
+
export interface BindingSourceField<TArgs extends BindingSourceArgs = BindingSourceArgs> {
|
|
8
|
+
readonly args?: TArgs;
|
|
9
|
+
readonly label: string;
|
|
10
|
+
readonly name: string;
|
|
11
|
+
readonly type?: BindingFieldType;
|
|
12
|
+
}
|
|
13
|
+
export type BlockBindingAttributeName<TAttributes extends BlockAttributes = BlockAttributes> = Extract<Exclude<keyof TAttributes, "metadata">, string>;
|
|
14
|
+
export interface BindingSourceBindableAttributes<TAttributes extends BlockAttributes = BlockAttributes, TBlockName extends string = string, TAttributesList extends readonly BlockBindingAttributeName<TAttributes>[] = readonly BlockBindingAttributeName<TAttributes>[]> {
|
|
15
|
+
readonly attributes: TAttributesList;
|
|
16
|
+
readonly blockName: TBlockName;
|
|
17
|
+
}
|
|
18
|
+
export interface BindingSourceDefinition<TName extends string = string, TArgs extends BindingSourceArgs = BindingSourceArgs, TFields extends readonly BindingSourceField[] = readonly BindingSourceField[]> {
|
|
19
|
+
readonly args?: TArgs;
|
|
20
|
+
readonly bindableAttributes?: readonly BindingSourceBindableAttributes[];
|
|
21
|
+
readonly fields?: TFields;
|
|
22
|
+
readonly getValueCallback?: string;
|
|
23
|
+
readonly label?: string;
|
|
24
|
+
readonly name: TName;
|
|
25
|
+
readonly usesContext?: readonly string[];
|
|
26
|
+
}
|
|
27
|
+
export interface BindingSourceVersionGates {
|
|
28
|
+
readonly editor?: WordPressVersion;
|
|
29
|
+
readonly fieldsList?: WordPressVersion;
|
|
30
|
+
readonly server?: WordPressVersion;
|
|
31
|
+
readonly supportedAttributesFilter?: WordPressVersion;
|
|
32
|
+
}
|
|
33
|
+
export interface DefineBindingSourceInlineOptions {
|
|
34
|
+
readonly allowUnknownFutureKeys?: boolean;
|
|
35
|
+
readonly editor?: boolean;
|
|
36
|
+
readonly fieldsList?: boolean;
|
|
37
|
+
readonly logger?: DiagnosticLogger<BindingSourceDiagnostic>;
|
|
38
|
+
readonly minVersion?: WordPressVersion;
|
|
39
|
+
readonly minWordPress?: WordPressVersion | BindingSourceVersionGates;
|
|
40
|
+
readonly minWordPressEditor?: WordPressVersion;
|
|
41
|
+
readonly minWordPressFieldsList?: WordPressVersion;
|
|
42
|
+
readonly minWordPressServer?: WordPressVersion;
|
|
43
|
+
readonly minWordPressSupportedAttributesFilter?: WordPressVersion;
|
|
44
|
+
readonly onDiagnostic?: (diagnostic: BindingSourceDiagnostic) => void;
|
|
45
|
+
readonly server?: boolean;
|
|
46
|
+
readonly strict?: boolean;
|
|
47
|
+
readonly supportedAttributesFilter?: boolean;
|
|
48
|
+
}
|
|
49
|
+
export interface DefineBindingSourceOptions extends WordPressCompatibilitySettings {
|
|
50
|
+
readonly editor?: boolean;
|
|
51
|
+
readonly fieldsList?: boolean;
|
|
52
|
+
readonly logger?: DiagnosticLogger<BindingSourceDiagnostic>;
|
|
53
|
+
readonly minWordPress?: WordPressVersion | BindingSourceVersionGates;
|
|
54
|
+
readonly minWordPressEditor?: WordPressVersion;
|
|
55
|
+
readonly minWordPressFieldsList?: WordPressVersion;
|
|
56
|
+
readonly minWordPressServer?: WordPressVersion;
|
|
57
|
+
readonly minWordPressSupportedAttributesFilter?: WordPressVersion;
|
|
58
|
+
readonly onDiagnostic?: (diagnostic: BindingSourceDiagnostic) => void;
|
|
59
|
+
readonly server?: boolean;
|
|
60
|
+
readonly supportedAttributesFilter?: boolean;
|
|
61
|
+
}
|
|
62
|
+
export type StripDefineBindingSourceOptions<TSource> = Omit<TSource, keyof DefineBindingSourceInlineOptions>;
|
|
63
|
+
export declare const DEFINED_BLOCK_BINDING_SOURCE_METADATA: unique symbol;
|
|
64
|
+
export type DefinedBlockBindingSourceMetadataKey = typeof DEFINED_BLOCK_BINDING_SOURCE_METADATA;
|
|
65
|
+
export interface DefinedBlockBindingSourceMetadata {
|
|
66
|
+
readonly diagnostics: readonly BindingSourceDiagnostic[];
|
|
67
|
+
readonly features: readonly WordPressBlockApiCompatibilityFeature[];
|
|
68
|
+
readonly manifest: WordPressBlockApiCompatibilityManifest;
|
|
69
|
+
}
|
|
70
|
+
export type DefinedBindingSource<TName extends string = string, TArgs extends BindingSourceArgs = BindingSourceArgs, TFields extends readonly BindingSourceField[] = readonly BindingSourceField[], TSource extends BindingSourceDefinition = BindingSourceDefinition> = Readonly<StripDefineBindingSourceOptions<TSource>> & {
|
|
71
|
+
readonly [DEFINED_BLOCK_BINDING_SOURCE_METADATA]?: DefinedBlockBindingSourceMetadata | undefined;
|
|
72
|
+
readonly __wpTypiaBindingSourceArgs?: TArgs;
|
|
73
|
+
readonly __wpTypiaBindingSourceFields?: TFields;
|
|
74
|
+
readonly name: TName;
|
|
75
|
+
};
|
|
76
|
+
export interface BlockBinding<TSourceName extends string = string, TArgs extends BindingSourceArgs = BindingSourceArgs> {
|
|
77
|
+
readonly args?: TArgs;
|
|
78
|
+
readonly source: TSourceName;
|
|
79
|
+
}
|
|
80
|
+
type BindingSourceInferredArgs<TSource> = TSource extends {
|
|
81
|
+
readonly __wpTypiaBindingSourceArgs?: infer TArgs extends BindingSourceArgs;
|
|
82
|
+
} ? TArgs : BindingSourceArgs;
|
|
83
|
+
export type Binding<TSource extends DefinedBindingSource | string, TArgs extends BindingSourceArgs = BindingSourceInferredArgs<TSource>> = TSource extends DefinedBindingSource<infer TName, infer TSourceArgs> ? TArgs extends TSourceArgs ? BlockBinding<TName, TArgs> : never : TSource extends string ? BlockBinding<TSource, TArgs> : never;
|
|
84
|
+
export type BlockBindingMap<TAttributes extends BlockAttributes = BlockAttributes> = Readonly<Partial<Record<BlockBindingAttributeName<TAttributes>, BlockBinding>>>;
|
|
85
|
+
export interface BlockMetadataBindings<TBindings extends Readonly<Record<string, BlockBinding | undefined>> = Readonly<Record<string, BlockBinding>>> {
|
|
86
|
+
readonly bindings?: TBindings;
|
|
87
|
+
}
|
|
88
|
+
export type TypedBlockMetadataBindings<TAttributes extends BlockAttributes, TBindings extends BlockBindingMap<TAttributes> = BlockBindingMap<TAttributes>> = BlockMetadataBindings<TBindings>;
|
|
89
|
+
export type BindingSourceDiagnosticCode = "duplicate-bindable-attribute" | "duplicate-field-name" | "fields-list-requires-editor" | "invalid-bindable-attribute" | "invalid-block-name" | "invalid-field-name" | "invalid-source-name" | "missing-php-callback";
|
|
90
|
+
export interface BindingSourceAuthoringDiagnostic {
|
|
91
|
+
readonly attribute?: string | undefined;
|
|
92
|
+
readonly blockName?: string | undefined;
|
|
93
|
+
readonly code: BindingSourceDiagnosticCode;
|
|
94
|
+
readonly fieldName?: string | undefined;
|
|
95
|
+
readonly message: string;
|
|
96
|
+
readonly severity: "error" | "warning";
|
|
97
|
+
readonly sourceName: string;
|
|
98
|
+
}
|
|
99
|
+
export type BindingSourceDiagnostic = BindingSourceAuthoringDiagnostic | WordPressBlockApiCompatibilityDiagnostic;
|
|
100
|
+
export interface BindingSourceRegistrationEntry {
|
|
101
|
+
readonly metadata: DefinedBlockBindingSourceMetadata;
|
|
102
|
+
readonly source: DefinedBindingSource;
|
|
103
|
+
}
|
|
104
|
+
export declare function collectBindingSourceCompatibilityFeatures(settings?: {
|
|
105
|
+
readonly editor?: boolean;
|
|
106
|
+
readonly fieldsList?: boolean;
|
|
107
|
+
readonly metadata?: boolean;
|
|
108
|
+
readonly server?: boolean;
|
|
109
|
+
readonly supportedAttributesFilter?: boolean;
|
|
110
|
+
}): readonly WordPressBlockApiCompatibilityFeature[];
|
|
111
|
+
export declare function createBindingSourceCompatibilityManifest(settings?: DefineBindingSourceOptions): WordPressBlockApiCompatibilityManifest;
|
|
112
|
+
export declare function getDefinedBindingSourceMetadata(source: unknown): DefinedBlockBindingSourceMetadata | undefined;
|
|
113
|
+
export declare function getDefinedBindingSourceCompatibilityManifest(source: unknown): WordPressBlockApiCompatibilityManifest | undefined;
|
|
114
|
+
export declare function defineBindingSource<const TSource extends BindingSourceDefinition & DefineBindingSourceInlineOptions>(source: TSource, options?: DefineBindingSourceOptions): DefinedBindingSource<Extract<TSource["name"], string>, TSource extends {
|
|
115
|
+
readonly args: infer TArgs extends BindingSourceArgs;
|
|
116
|
+
} ? TArgs : BindingSourceArgs, TSource extends {
|
|
117
|
+
readonly fields: infer TFields extends readonly BindingSourceField[];
|
|
118
|
+
} ? TFields : readonly BindingSourceField[], TSource>;
|
|
119
|
+
export declare function defineBindableAttributes<TAttributes extends BlockAttributes = BlockAttributes, const TBlockName extends string = string, const TAttributesList extends readonly BlockBindingAttributeName<TAttributes>[] = readonly BlockBindingAttributeName<TAttributes>[]>(blockName: TBlockName, attributes: TAttributesList): BindingSourceBindableAttributes<TAttributes, TBlockName, TAttributesList>;
|
|
120
|
+
export declare function defineBlockMetadataBindings<const TBindings extends Readonly<Record<string, BlockBinding | undefined>>>(bindings: TBindings): BlockMetadataBindings<TBindings>;
|
|
121
|
+
export declare function defineTypedBlockMetadataBindings<TAttributes extends BlockAttributes, const TBindings extends BlockBindingMap<TAttributes> = BlockBindingMap<TAttributes>>(bindings: TBindings): TypedBlockMetadataBindings<TAttributes, TBindings>;
|
|
122
|
+
export declare function createBindingSourceRegistrationPlan(sources: readonly DefinedBindingSource[]): readonly BindingSourceRegistrationEntry[];
|
|
123
|
+
export {};
|
|
@@ -0,0 +1,351 @@
|
|
|
1
|
+
import { DEFAULT_WORDPRESS_COMPATIBILITY_MIN_VERSION, evaluateWordPressBlockApiCompatibility, } from "./compatibility.js";
|
|
2
|
+
import { getDiagnosticSeverity, handleDiagnostics, } from "./shared/diagnostics.js";
|
|
3
|
+
import { isObjectRecord } from "./shared/object-utils.js";
|
|
4
|
+
export const DEFINED_BLOCK_BINDING_SOURCE_METADATA = Symbol.for("@wp-typia/block-types/defined-binding-source");
|
|
5
|
+
const DEFINE_BINDING_SOURCE_INLINE_OPTION_KEYS = new Set([
|
|
6
|
+
"allowUnknownFutureKeys",
|
|
7
|
+
"editor",
|
|
8
|
+
"fieldsList",
|
|
9
|
+
"logger",
|
|
10
|
+
"minVersion",
|
|
11
|
+
"minWordPress",
|
|
12
|
+
"minWordPressEditor",
|
|
13
|
+
"minWordPressFieldsList",
|
|
14
|
+
"minWordPressServer",
|
|
15
|
+
"minWordPressSupportedAttributesFilter",
|
|
16
|
+
"onDiagnostic",
|
|
17
|
+
"server",
|
|
18
|
+
"strict",
|
|
19
|
+
"supportedAttributesFilter",
|
|
20
|
+
]);
|
|
21
|
+
const SOURCE_NAME_PATTERN = /^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\/[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/u;
|
|
22
|
+
const FIELD_NAME_PATTERN = /^[A-Za-z_][A-Za-z0-9_-]*$/u;
|
|
23
|
+
function isBindingSourceVersionGates(value) {
|
|
24
|
+
return isObjectRecord(value);
|
|
25
|
+
}
|
|
26
|
+
function splitDefineBindingSourceInput(source) {
|
|
27
|
+
const inlineOptions = {};
|
|
28
|
+
const normalizedSource = {};
|
|
29
|
+
for (const [key, value] of Object.entries(source)) {
|
|
30
|
+
if (DEFINE_BINDING_SOURCE_INLINE_OPTION_KEYS.has(key)) {
|
|
31
|
+
Object.assign(inlineOptions, { [key]: value });
|
|
32
|
+
continue;
|
|
33
|
+
}
|
|
34
|
+
normalizedSource[key] = value;
|
|
35
|
+
}
|
|
36
|
+
return {
|
|
37
|
+
inlineOptions,
|
|
38
|
+
source: normalizedSource,
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
function resolveMinWordPress(inlineOptions, options) {
|
|
42
|
+
const optionMinWordPress = options.minWordPress;
|
|
43
|
+
const inlineMinWordPress = inlineOptions.minWordPress;
|
|
44
|
+
const optionGates = isBindingSourceVersionGates(optionMinWordPress)
|
|
45
|
+
? optionMinWordPress
|
|
46
|
+
: {};
|
|
47
|
+
const inlineGates = isBindingSourceVersionGates(inlineMinWordPress)
|
|
48
|
+
? inlineMinWordPress
|
|
49
|
+
: {};
|
|
50
|
+
const minVersion = options.minVersion ??
|
|
51
|
+
(typeof optionMinWordPress === "string" ? optionMinWordPress : undefined) ??
|
|
52
|
+
inlineOptions.minVersion ??
|
|
53
|
+
(typeof inlineMinWordPress === "string" ? inlineMinWordPress : undefined);
|
|
54
|
+
const compatibility = {
|
|
55
|
+
strict: options.strict ?? inlineOptions.strict ?? true,
|
|
56
|
+
};
|
|
57
|
+
if (options.allowUnknownFutureKeys ?? inlineOptions.allowUnknownFutureKeys) {
|
|
58
|
+
Object.assign(compatibility, {
|
|
59
|
+
allowUnknownFutureKeys: options.allowUnknownFutureKeys ?? inlineOptions.allowUnknownFutureKeys,
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
if (minVersion !== undefined) {
|
|
63
|
+
Object.assign(compatibility, { minVersion });
|
|
64
|
+
}
|
|
65
|
+
const gates = {};
|
|
66
|
+
const editor = options.minWordPressEditor ??
|
|
67
|
+
optionGates.editor ??
|
|
68
|
+
inlineOptions.minWordPressEditor ??
|
|
69
|
+
inlineGates.editor;
|
|
70
|
+
const fieldsList = options.minWordPressFieldsList ??
|
|
71
|
+
optionGates.fieldsList ??
|
|
72
|
+
inlineOptions.minWordPressFieldsList ??
|
|
73
|
+
inlineGates.fieldsList;
|
|
74
|
+
const server = options.minWordPressServer ??
|
|
75
|
+
optionGates.server ??
|
|
76
|
+
inlineOptions.minWordPressServer ??
|
|
77
|
+
inlineGates.server;
|
|
78
|
+
const supportedAttributesFilter = options.minWordPressSupportedAttributesFilter ??
|
|
79
|
+
optionGates.supportedAttributesFilter ??
|
|
80
|
+
inlineOptions.minWordPressSupportedAttributesFilter ??
|
|
81
|
+
inlineGates.supportedAttributesFilter;
|
|
82
|
+
if (editor !== undefined) {
|
|
83
|
+
Object.assign(gates, { editor });
|
|
84
|
+
}
|
|
85
|
+
if (fieldsList !== undefined) {
|
|
86
|
+
Object.assign(gates, { fieldsList });
|
|
87
|
+
}
|
|
88
|
+
if (server !== undefined) {
|
|
89
|
+
Object.assign(gates, { server });
|
|
90
|
+
}
|
|
91
|
+
if (supportedAttributesFilter !== undefined) {
|
|
92
|
+
Object.assign(gates, { supportedAttributesFilter });
|
|
93
|
+
}
|
|
94
|
+
return {
|
|
95
|
+
compatibility,
|
|
96
|
+
gates,
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
function resolveDefineBindingSourceSettings(inlineOptions, options, source) {
|
|
100
|
+
const { compatibility, gates } = resolveMinWordPress(inlineOptions, options);
|
|
101
|
+
const strict = compatibility.strict ?? true;
|
|
102
|
+
const hasFields = (source.fields?.length ?? 0) > 0;
|
|
103
|
+
const hasBindableAttributes = (source.bindableAttributes?.length ?? 0) > 0;
|
|
104
|
+
return {
|
|
105
|
+
compatibility,
|
|
106
|
+
features: {
|
|
107
|
+
editor: options.editor ?? inlineOptions.editor ?? true,
|
|
108
|
+
fieldsList: options.fieldsList ?? inlineOptions.fieldsList ?? hasFields,
|
|
109
|
+
metadata: true,
|
|
110
|
+
server: options.server ?? inlineOptions.server ?? true,
|
|
111
|
+
supportedAttributesFilter: options.supportedAttributesFilter ??
|
|
112
|
+
inlineOptions.supportedAttributesFilter ??
|
|
113
|
+
hasBindableAttributes,
|
|
114
|
+
},
|
|
115
|
+
gates,
|
|
116
|
+
logger: options.logger ?? inlineOptions.logger,
|
|
117
|
+
onDiagnostic: options.onDiagnostic ?? inlineOptions.onDiagnostic,
|
|
118
|
+
strict,
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
function getFeatureMinVersion(feature, fallback, gates) {
|
|
122
|
+
if (feature.area !== "blockBindings") {
|
|
123
|
+
return fallback;
|
|
124
|
+
}
|
|
125
|
+
switch (feature.feature) {
|
|
126
|
+
case "metadata.bindings":
|
|
127
|
+
case "serverRegistration":
|
|
128
|
+
return gates.server ?? fallback;
|
|
129
|
+
case "editorFieldsList":
|
|
130
|
+
return gates.fieldsList ?? fallback;
|
|
131
|
+
case "editorRegistration":
|
|
132
|
+
case "editorSourceLookup":
|
|
133
|
+
return gates.editor ?? fallback;
|
|
134
|
+
case "supportedAttributesFilter":
|
|
135
|
+
return gates.supportedAttributesFilter ?? gates.fieldsList ?? fallback;
|
|
136
|
+
default:
|
|
137
|
+
return fallback;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
function createBindingCompatibilityManifest(features, settings, gates) {
|
|
141
|
+
const fallback = settings.minVersion ?? DEFAULT_WORDPRESS_COMPATIBILITY_MIN_VERSION;
|
|
142
|
+
const strict = settings.strict ?? true;
|
|
143
|
+
const allowUnknownFutureKeys = settings.allowUnknownFutureKeys ?? false;
|
|
144
|
+
const evaluations = features.map((feature) => evaluateWordPressBlockApiCompatibility(feature, {
|
|
145
|
+
allowUnknownFutureKeys,
|
|
146
|
+
minVersion: getFeatureMinVersion(feature, fallback, gates),
|
|
147
|
+
strict,
|
|
148
|
+
}));
|
|
149
|
+
const diagnostics = evaluations.flatMap((evaluation) => evaluation.diagnostic ? [evaluation.diagnostic] : []);
|
|
150
|
+
return {
|
|
151
|
+
allowUnknownFutureKeys,
|
|
152
|
+
diagnostics,
|
|
153
|
+
evaluations,
|
|
154
|
+
minVersion: fallback,
|
|
155
|
+
strict,
|
|
156
|
+
supported: evaluations.filter((evaluation) => evaluation.status === "supported"),
|
|
157
|
+
unknown: evaluations.filter((evaluation) => evaluation.status === "unknown"),
|
|
158
|
+
unsupported: evaluations.filter((evaluation) => evaluation.status === "unsupported"),
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
export function collectBindingSourceCompatibilityFeatures(settings = {}) {
|
|
162
|
+
const features = [];
|
|
163
|
+
if (settings.metadata ?? true) {
|
|
164
|
+
features.push({
|
|
165
|
+
area: "blockBindings",
|
|
166
|
+
feature: "metadata.bindings",
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
if (settings.server ?? true) {
|
|
170
|
+
features.push({
|
|
171
|
+
area: "blockBindings",
|
|
172
|
+
feature: "serverRegistration",
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
if (settings.editor ?? true) {
|
|
176
|
+
features.push({
|
|
177
|
+
area: "blockBindings",
|
|
178
|
+
feature: "editorRegistration",
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
if (settings.fieldsList ?? false) {
|
|
182
|
+
features.push({
|
|
183
|
+
area: "blockBindings",
|
|
184
|
+
feature: "editorFieldsList",
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
if (settings.supportedAttributesFilter ?? false) {
|
|
188
|
+
features.push({
|
|
189
|
+
area: "blockBindings",
|
|
190
|
+
feature: "supportedAttributesFilter",
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
return features;
|
|
194
|
+
}
|
|
195
|
+
export function createBindingSourceCompatibilityManifest(settings = {}) {
|
|
196
|
+
const resolved = resolveDefineBindingSourceSettings({}, settings, {
|
|
197
|
+
name: "wp-typia/binding-source",
|
|
198
|
+
});
|
|
199
|
+
return createBindingCompatibilityManifest(collectBindingSourceCompatibilityFeatures(resolved.features), resolved.compatibility, resolved.gates);
|
|
200
|
+
}
|
|
201
|
+
function createBindingSourceDiagnostics(source, options) {
|
|
202
|
+
const diagnostics = [];
|
|
203
|
+
const severity = getDiagnosticSeverity(options.strict);
|
|
204
|
+
if (!SOURCE_NAME_PATTERN.test(source.name)) {
|
|
205
|
+
diagnostics.push({
|
|
206
|
+
code: "invalid-source-name",
|
|
207
|
+
message: `Block binding source "${source.name}" must be lowercase and namespaced, such as "acme/profile-data".`,
|
|
208
|
+
severity,
|
|
209
|
+
sourceName: source.name,
|
|
210
|
+
});
|
|
211
|
+
}
|
|
212
|
+
if (options.server && !source.getValueCallback) {
|
|
213
|
+
diagnostics.push({
|
|
214
|
+
code: "missing-php-callback",
|
|
215
|
+
message: `Block binding source "${source.name}" needs getValueCallback when server registration is enabled.`,
|
|
216
|
+
severity,
|
|
217
|
+
sourceName: source.name,
|
|
218
|
+
});
|
|
219
|
+
}
|
|
220
|
+
if (options.fieldsList && !options.editor) {
|
|
221
|
+
diagnostics.push({
|
|
222
|
+
code: "fields-list-requires-editor",
|
|
223
|
+
message: `Block binding source "${source.name}" enables getFieldsList() without editor registration.`,
|
|
224
|
+
severity,
|
|
225
|
+
sourceName: source.name,
|
|
226
|
+
});
|
|
227
|
+
}
|
|
228
|
+
const seenFields = new Set();
|
|
229
|
+
for (const field of source.fields ?? []) {
|
|
230
|
+
if (!FIELD_NAME_PATTERN.test(field.name)) {
|
|
231
|
+
diagnostics.push({
|
|
232
|
+
code: "invalid-field-name",
|
|
233
|
+
fieldName: field.name,
|
|
234
|
+
message: `Block binding source "${source.name}" field "${field.name}" must be a stable identifier.`,
|
|
235
|
+
severity,
|
|
236
|
+
sourceName: source.name,
|
|
237
|
+
});
|
|
238
|
+
}
|
|
239
|
+
if (seenFields.has(field.name)) {
|
|
240
|
+
diagnostics.push({
|
|
241
|
+
code: "duplicate-field-name",
|
|
242
|
+
fieldName: field.name,
|
|
243
|
+
message: `Block binding source "${source.name}" declares duplicate field "${field.name}".`,
|
|
244
|
+
severity,
|
|
245
|
+
sourceName: source.name,
|
|
246
|
+
});
|
|
247
|
+
}
|
|
248
|
+
seenFields.add(field.name);
|
|
249
|
+
}
|
|
250
|
+
for (const target of source.bindableAttributes ?? []) {
|
|
251
|
+
if (!SOURCE_NAME_PATTERN.test(target.blockName)) {
|
|
252
|
+
diagnostics.push({
|
|
253
|
+
blockName: target.blockName,
|
|
254
|
+
code: "invalid-block-name",
|
|
255
|
+
message: `Bindable attributes target "${target.blockName}" must be a lowercase namespaced block name.`,
|
|
256
|
+
severity,
|
|
257
|
+
sourceName: source.name,
|
|
258
|
+
});
|
|
259
|
+
}
|
|
260
|
+
const seenAttributes = new Set();
|
|
261
|
+
for (const attribute of target.attributes) {
|
|
262
|
+
if (!FIELD_NAME_PATTERN.test(attribute)) {
|
|
263
|
+
diagnostics.push({
|
|
264
|
+
attribute,
|
|
265
|
+
blockName: target.blockName,
|
|
266
|
+
code: "invalid-bindable-attribute",
|
|
267
|
+
message: `Bindable attribute "${attribute}" for "${target.blockName}" must be a stable identifier.`,
|
|
268
|
+
severity,
|
|
269
|
+
sourceName: source.name,
|
|
270
|
+
});
|
|
271
|
+
}
|
|
272
|
+
if (seenAttributes.has(attribute)) {
|
|
273
|
+
diagnostics.push({
|
|
274
|
+
attribute,
|
|
275
|
+
blockName: target.blockName,
|
|
276
|
+
code: "duplicate-bindable-attribute",
|
|
277
|
+
message: `Bindable attribute "${attribute}" for "${target.blockName}" is declared more than once.`,
|
|
278
|
+
severity,
|
|
279
|
+
sourceName: source.name,
|
|
280
|
+
});
|
|
281
|
+
}
|
|
282
|
+
seenAttributes.add(attribute);
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
return diagnostics;
|
|
286
|
+
}
|
|
287
|
+
function handleBindingSourceDiagnostics(diagnostics, onDiagnostic, logger) {
|
|
288
|
+
handleDiagnostics(diagnostics, onDiagnostic, {
|
|
289
|
+
failureHeading: "WordPress block binding source check failed:",
|
|
290
|
+
logger,
|
|
291
|
+
});
|
|
292
|
+
}
|
|
293
|
+
export function getDefinedBindingSourceMetadata(source) {
|
|
294
|
+
return isObjectRecord(source)
|
|
295
|
+
? source[DEFINED_BLOCK_BINDING_SOURCE_METADATA]
|
|
296
|
+
: undefined;
|
|
297
|
+
}
|
|
298
|
+
export function getDefinedBindingSourceCompatibilityManifest(source) {
|
|
299
|
+
return getDefinedBindingSourceMetadata(source)?.manifest;
|
|
300
|
+
}
|
|
301
|
+
export function defineBindingSource(source, options = {}) {
|
|
302
|
+
const { inlineOptions, source: normalizedSource } = splitDefineBindingSourceInput(source);
|
|
303
|
+
const resolved = resolveDefineBindingSourceSettings(inlineOptions, options, normalizedSource);
|
|
304
|
+
const features = collectBindingSourceCompatibilityFeatures(resolved.features);
|
|
305
|
+
const manifest = createBindingCompatibilityManifest(features, resolved.compatibility, resolved.gates);
|
|
306
|
+
const diagnostics = [
|
|
307
|
+
...manifest.diagnostics,
|
|
308
|
+
...createBindingSourceDiagnostics(normalizedSource, {
|
|
309
|
+
editor: resolved.features.editor,
|
|
310
|
+
fieldsList: resolved.features.fieldsList,
|
|
311
|
+
server: resolved.features.server,
|
|
312
|
+
strict: resolved.strict,
|
|
313
|
+
}),
|
|
314
|
+
];
|
|
315
|
+
handleBindingSourceDiagnostics(diagnostics, resolved.onDiagnostic, resolved.logger);
|
|
316
|
+
Object.defineProperty(normalizedSource, DEFINED_BLOCK_BINDING_SOURCE_METADATA, {
|
|
317
|
+
configurable: false,
|
|
318
|
+
enumerable: false,
|
|
319
|
+
value: {
|
|
320
|
+
diagnostics,
|
|
321
|
+
features,
|
|
322
|
+
manifest,
|
|
323
|
+
},
|
|
324
|
+
writable: false,
|
|
325
|
+
});
|
|
326
|
+
return normalizedSource;
|
|
327
|
+
}
|
|
328
|
+
export function defineBindableAttributes(blockName, attributes) {
|
|
329
|
+
return {
|
|
330
|
+
attributes,
|
|
331
|
+
blockName,
|
|
332
|
+
};
|
|
333
|
+
}
|
|
334
|
+
export function defineBlockMetadataBindings(bindings) {
|
|
335
|
+
return { bindings };
|
|
336
|
+
}
|
|
337
|
+
export function defineTypedBlockMetadataBindings(bindings) {
|
|
338
|
+
return { bindings };
|
|
339
|
+
}
|
|
340
|
+
export function createBindingSourceRegistrationPlan(sources) {
|
|
341
|
+
return sources.map((source) => {
|
|
342
|
+
const metadata = getDefinedBindingSourceMetadata(source);
|
|
343
|
+
if (!metadata) {
|
|
344
|
+
throw new Error(`Block binding source "${source.name}" was not created by defineBindingSource().`);
|
|
345
|
+
}
|
|
346
|
+
return {
|
|
347
|
+
metadata,
|
|
348
|
+
source,
|
|
349
|
+
};
|
|
350
|
+
});
|
|
351
|
+
}
|