@wp-typia/block-types 0.3.1 → 0.3.2

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.
@@ -0,0 +1,7 @@
1
+ import { handleDiagnostics } from "./shared/diagnostics.js";
2
+ export function handleDefineSupportsDiagnostics(diagnostics, onDiagnostic, logger) {
3
+ handleDiagnostics(diagnostics, onDiagnostic, {
4
+ failureHeading: "WordPress block supports compatibility check failed:",
5
+ logger,
6
+ });
7
+ }
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Derived from Gutenberg block support keys and commonly used block.json
3
+ * support sections.
4
+ */
5
+ export type BlockSupportFeature = "align" | "alignWide" | "allowedBlocks" | "anchor" | "ariaLabel" | "autoRegister" | "background" | "border" | "className" | "color" | "contentRole" | "customClassName" | "dimensions" | "filter" | "html" | "inserter" | "interactivity" | "js" | "layout" | "lightbox" | "listView" | "lock" | "locking" | "multiple" | "position" | "renaming" | "reusable" | "shadow" | "spacing" | "splitting" | "visibility" | "typography";
6
+ export declare const BLOCK_SUPPORT_FEATURES: readonly ["align", "alignWide", "allowedBlocks", "anchor", "ariaLabel", "autoRegister", "background", "border", "className", "color", "contentRole", "customClassName", "dimensions", "filter", "html", "inserter", "interactivity", "js", "layout", "lightbox", "listView", "lock", "locking", "multiple", "position", "renaming", "reusable", "shadow", "spacing", "splitting", "typography", "visibility"];
7
+ export type TypographySupportKey = "fontFamily" | "fontSize" | "fontStyle" | "fontWeight" | "letterSpacing" | "lineHeight" | "dropCap" | "textAlign" | "textColumns" | "textDecoration" | "textTransform" | "writingMode";
8
+ export declare const TYPOGRAPHY_SUPPORT_KEYS: readonly ["fontFamily", "fontSize", "fontStyle", "fontWeight", "letterSpacing", "lineHeight", "dropCap", "textAlign", "textColumns", "textDecoration", "textTransform", "writingMode"];
9
+ export type SpacingSupportKey = "blockGap" | "margin" | "padding";
10
+ export declare const SPACING_SUPPORT_KEYS: readonly ["blockGap", "margin", "padding"];
@@ -0,0 +1,53 @@
1
+ export const BLOCK_SUPPORT_FEATURES = [
2
+ "align",
3
+ "alignWide",
4
+ "allowedBlocks",
5
+ "anchor",
6
+ "ariaLabel",
7
+ "autoRegister",
8
+ "background",
9
+ "border",
10
+ "className",
11
+ "color",
12
+ "contentRole",
13
+ "customClassName",
14
+ "dimensions",
15
+ "filter",
16
+ "html",
17
+ "inserter",
18
+ "interactivity",
19
+ "js",
20
+ "layout",
21
+ "lightbox",
22
+ "listView",
23
+ "lock",
24
+ "locking",
25
+ "multiple",
26
+ "position",
27
+ "renaming",
28
+ "reusable",
29
+ "shadow",
30
+ "spacing",
31
+ "splitting",
32
+ "typography",
33
+ "visibility",
34
+ ];
35
+ export const TYPOGRAPHY_SUPPORT_KEYS = [
36
+ "fontFamily",
37
+ "fontSize",
38
+ "fontStyle",
39
+ "fontWeight",
40
+ "letterSpacing",
41
+ "lineHeight",
42
+ "dropCap",
43
+ "textAlign",
44
+ "textColumns",
45
+ "textDecoration",
46
+ "textTransform",
47
+ "writingMode",
48
+ ];
49
+ export const SPACING_SUPPORT_KEYS = [
50
+ "blockGap",
51
+ "margin",
52
+ "padding",
53
+ ];
@@ -0,0 +1,4 @@
1
+ import { type WordPressBlockApiCompatibilityFeature, type WordPressBlockApiCompatibilityManifest } from "./compatibility.js";
2
+ import type { BlockSupportsInput, DefineSupportsOptions } from "./supports.js";
3
+ export declare function collectBlockSupportsCompatibilityFeatures(supports: BlockSupportsInput): readonly WordPressBlockApiCompatibilityFeature[];
4
+ export declare function createBlockSupportsCompatibilityManifest(supports: BlockSupportsInput, settings?: DefineSupportsOptions): WordPressBlockApiCompatibilityManifest;
@@ -0,0 +1,97 @@
1
+ import { createWordPressBlockApiCompatibilityManifest, } from "./compatibility.js";
2
+ import { BLOCK_SUPPORT_FEATURES, SPACING_SUPPORT_KEYS, } from "./supports-features.js";
3
+ import { DEFINE_SUPPORTS_INLINE_OPTION_KEYS, resolveDefineSupportsSettings, } from "./supports-settings.js";
4
+ import { isNonArrayObject, isObjectRecord, } from "./shared/object-utils.js";
5
+ const KNOWN_BLOCK_SUPPORT_FEATURES = new Set(BLOCK_SUPPORT_FEATURES);
6
+ const COLOR_COMPATIBILITY_SUPPORT_KEYS = [
7
+ "button",
8
+ "enableContrastChecker",
9
+ "heading",
10
+ ];
11
+ const TYPOGRAPHY_COMPATIBILITY_SUPPORT_KEYS = [
12
+ "fontSize",
13
+ "letterSpacing",
14
+ "lineHeight",
15
+ "textAlign",
16
+ "textDecoration",
17
+ "textTransform",
18
+ ];
19
+ const TOP_LEVEL_COMPATIBILITY_SUPPORT_KEYS = [
20
+ "allowedBlocks",
21
+ "background",
22
+ "contentRole",
23
+ "dimensions",
24
+ "listView",
25
+ "position",
26
+ "renaming",
27
+ "shadow",
28
+ "visibility",
29
+ ];
30
+ function isEnabledSupportValue(value) {
31
+ return value !== false && value !== null && value !== undefined;
32
+ }
33
+ function isEnabledTopLevelSupportValue(value) {
34
+ if (!isObjectRecord(value)) {
35
+ return isNonArrayObject(value) ? false : isEnabledSupportValue(value);
36
+ }
37
+ return Object.entries(value).some(([key, nestedValue]) => !key.startsWith("__experimental") &&
38
+ isEnabledSupportValue(nestedValue));
39
+ }
40
+ function hasEnabledNestedSupport(section, key) {
41
+ return isObjectRecord(section) && isEnabledSupportValue(section[key]);
42
+ }
43
+ function addCompatibilityFeature(features, seen, feature) {
44
+ const id = `blockSupports.${feature}`;
45
+ if (seen.has(id)) {
46
+ return;
47
+ }
48
+ seen.add(id);
49
+ features.push({
50
+ area: "blockSupports",
51
+ feature,
52
+ });
53
+ }
54
+ export function collectBlockSupportsCompatibilityFeatures(supports) {
55
+ const features = [];
56
+ const seen = new Set();
57
+ for (const key of TOP_LEVEL_COMPATIBILITY_SUPPORT_KEYS) {
58
+ if (isEnabledTopLevelSupportValue(supports[key])) {
59
+ addCompatibilityFeature(features, seen, key);
60
+ }
61
+ }
62
+ const spacing = supports.spacing;
63
+ for (const key of SPACING_SUPPORT_KEYS) {
64
+ if (hasEnabledNestedSupport(spacing, key)) {
65
+ addCompatibilityFeature(features, seen, `spacing.${key}`);
66
+ }
67
+ }
68
+ const typography = supports.typography;
69
+ for (const key of TYPOGRAPHY_COMPATIBILITY_SUPPORT_KEYS) {
70
+ if (hasEnabledNestedSupport(typography, key)) {
71
+ addCompatibilityFeature(features, seen, `typography.${key}`);
72
+ }
73
+ }
74
+ const color = supports.color;
75
+ if (isObjectRecord(color)) {
76
+ for (const key of COLOR_COMPATIBILITY_SUPPORT_KEYS) {
77
+ if (isEnabledSupportValue(color[key])) {
78
+ addCompatibilityFeature(features, seen, `color.${key}`);
79
+ }
80
+ }
81
+ }
82
+ if (hasEnabledNestedSupport(supports.filter, "duotone")) {
83
+ addCompatibilityFeature(features, seen, "filter.duotone");
84
+ }
85
+ for (const key of Object.keys(supports)) {
86
+ if (!KNOWN_BLOCK_SUPPORT_FEATURES.has(key) &&
87
+ !DEFINE_SUPPORTS_INLINE_OPTION_KEYS.has(key) &&
88
+ isEnabledTopLevelSupportValue(supports[key])) {
89
+ addCompatibilityFeature(features, seen, key);
90
+ }
91
+ }
92
+ return features;
93
+ }
94
+ export function createBlockSupportsCompatibilityManifest(supports, settings = {}) {
95
+ const compatibilitySettings = resolveDefineSupportsSettings({}, settings);
96
+ return createWordPressBlockApiCompatibilityManifest(collectBlockSupportsCompatibilityFeatures(supports), compatibilitySettings);
97
+ }
@@ -0,0 +1,8 @@
1
+ import type { WordPressCompatibilitySettings } from "./compatibility.js";
2
+ import type { BlockSupportsInput, DefineSupportsInlineOptions, DefineSupportsOptions, StripDefineSupportsOptions } from "./supports.js";
3
+ export declare const DEFINE_SUPPORTS_INLINE_OPTION_KEYS: Set<string>;
4
+ export declare function splitDefineSupportsInput<TSupports extends BlockSupportsInput>(supports: TSupports & DefineSupportsInlineOptions): {
5
+ inlineOptions: DefineSupportsInlineOptions;
6
+ supports: StripDefineSupportsOptions<TSupports> & BlockSupportsInput;
7
+ };
8
+ export declare function resolveDefineSupportsSettings(inlineOptions: DefineSupportsInlineOptions, options: DefineSupportsOptions): WordPressCompatibilitySettings;
@@ -0,0 +1,42 @@
1
+ export const DEFINE_SUPPORTS_INLINE_OPTION_KEYS = new Set([
2
+ "allowUnknownFutureKeys",
3
+ "logger",
4
+ "minVersion",
5
+ "minWordPress",
6
+ "onDiagnostic",
7
+ "strict",
8
+ ]);
9
+ export function splitDefineSupportsInput(supports) {
10
+ const normalizedSupports = {};
11
+ const inlineOptions = {};
12
+ for (const [key, value] of Object.entries(supports)) {
13
+ if (DEFINE_SUPPORTS_INLINE_OPTION_KEYS.has(key)) {
14
+ Object.assign(inlineOptions, { [key]: value });
15
+ continue;
16
+ }
17
+ normalizedSupports[key] = value;
18
+ }
19
+ return {
20
+ inlineOptions,
21
+ supports: normalizedSupports,
22
+ };
23
+ }
24
+ export function resolveDefineSupportsSettings(inlineOptions, options) {
25
+ const settings = {};
26
+ const allowUnknownFutureKeys = options.allowUnknownFutureKeys ?? inlineOptions.allowUnknownFutureKeys;
27
+ const minVersion = options.minVersion ??
28
+ options.minWordPress ??
29
+ inlineOptions.minVersion ??
30
+ inlineOptions.minWordPress;
31
+ const strict = options.strict ?? inlineOptions.strict;
32
+ if (allowUnknownFutureKeys !== undefined) {
33
+ Object.assign(settings, { allowUnknownFutureKeys });
34
+ }
35
+ if (minVersion !== undefined) {
36
+ Object.assign(settings, { minVersion });
37
+ }
38
+ if (strict !== undefined) {
39
+ Object.assign(settings, { strict });
40
+ }
41
+ return settings;
42
+ }
@@ -2,18 +2,12 @@ import type { BlockAlignment, BlockVerticalAlignment, JustifyContent, TextAlignm
2
2
  import type { BlockBorderSupportAttributes, BlockColorSupportAttributes, BlockDimensionsSupportAttributes, BlockSpacingSupportAttributes, BlockStyleAttributes, BlockTypographySupportAttributes } from "../block-editor/style-attributes.js";
3
3
  import type { FlexWrap, LayoutType, Orientation } from "../block-editor/layout.js";
4
4
  import type { SpacingAxis, SpacingDimension } from "../block-editor/spacing.js";
5
- import { type WordPressBlockApiCompatibilityDiagnostic, type WordPressBlockApiCompatibilityFeature, type WordPressBlockApiCompatibilityManifest, type WordPressCompatibilitySettings, type WordPressVersion } from "./compatibility.js";
5
+ import { type WordPressBlockApiCompatibilityDiagnostic, type WordPressBlockApiCompatibilityManifest, type WordPressCompatibilitySettings, type WordPressVersion } from "./compatibility.js";
6
+ import { BLOCK_SUPPORT_FEATURES, SPACING_SUPPORT_KEYS, TYPOGRAPHY_SUPPORT_KEYS, type BlockSupportFeature, type SpacingSupportKey, type TypographySupportKey } from "./supports-features.js";
7
+ import { collectBlockSupportsCompatibilityFeatures, createBlockSupportsCompatibilityManifest } from "./supports-manifest.js";
8
+ export { BLOCK_SUPPORT_FEATURES, SPACING_SUPPORT_KEYS, TYPOGRAPHY_SUPPORT_KEYS, collectBlockSupportsCompatibilityFeatures, createBlockSupportsCompatibilityManifest, };
9
+ export type { BlockSupportFeature, SpacingSupportKey, TypographySupportKey, };
6
10
  import { type DiagnosticLogger } from "./shared/diagnostics.js";
7
- /**
8
- * Derived from Gutenberg block support keys and commonly used block.json
9
- * support sections.
10
- */
11
- export type BlockSupportFeature = 'align' | 'alignWide' | 'allowedBlocks' | 'anchor' | 'ariaLabel' | 'autoRegister' | 'background' | 'border' | 'className' | 'color' | 'contentRole' | 'customClassName' | 'dimensions' | 'filter' | 'html' | 'inserter' | 'interactivity' | 'js' | 'layout' | 'lightbox' | 'listView' | 'lock' | 'locking' | 'multiple' | 'position' | 'renaming' | 'reusable' | 'shadow' | 'spacing' | 'splitting' | 'visibility' | 'typography';
12
- export declare const BLOCK_SUPPORT_FEATURES: readonly ["align", "alignWide", "allowedBlocks", "anchor", "ariaLabel", "autoRegister", "background", "border", "className", "color", "contentRole", "customClassName", "dimensions", "filter", "html", "inserter", "interactivity", "js", "layout", "lightbox", "listView", "lock", "locking", "multiple", "position", "renaming", "reusable", "shadow", "spacing", "splitting", "typography", "visibility"];
13
- export type TypographySupportKey = 'fontFamily' | 'fontSize' | 'fontStyle' | 'fontWeight' | 'letterSpacing' | 'lineHeight' | 'dropCap' | 'textAlign' | 'textColumns' | 'textDecoration' | 'textTransform' | 'writingMode';
14
- export declare const TYPOGRAPHY_SUPPORT_KEYS: readonly ["fontFamily", "fontSize", "fontStyle", "fontWeight", "letterSpacing", "lineHeight", "dropCap", "textAlign", "textColumns", "textDecoration", "textTransform", "writingMode"];
15
- export type SpacingSupportKey = 'blockGap' | 'margin' | 'padding';
16
- export declare const SPACING_SUPPORT_KEYS: readonly ["blockGap", "margin", "padding"];
17
11
  type BlockSupportDefaultControls<TFeature extends string> = Readonly<Partial<Record<TFeature, boolean>> & Record<string, boolean | undefined>>;
18
12
  export type SkipSerialization<TFeature extends string> = boolean | readonly TFeature[];
19
13
  export interface BlockBorderSupport {
@@ -215,8 +209,5 @@ export type DefinedBlockSupports<TSupports extends BlockSupportsInput = BlockSup
215
209
  };
216
210
  export type SupportAttributes<TSupports> = TSupports extends DefinedBlockSupports<infer TDefinedSupports> ? SupportAttributesFromBlockSupports<StripDefineSupportsOptions<TDefinedSupports>> : TSupports extends BlockSupportsInput ? SupportAttributesFromBlockSupports<StripDefineSupportsOptions<TSupports>> : {};
217
211
  export type SupportAttributesFromBlockSupports<TSupports> = IfSupport<HasSupport<TSupports, "align">, BlockAlignSupportAttributes> & IfSupport<HasSupport<TSupports, "allowedBlocks">, BlockAllowedBlocksSupportAttributes> & IfSupport<HasSupport<TSupports, "layout">, BlockLayoutSupportAttributes> & IfSupport<HasSupport<TSupports, "color">, BlockColorSupportAttributes> & IfSupport<HasSupport<TSupports, "typography">, BlockTypographySupportAttributes> & IfSupport<HasSupport<TSupports, "spacing">, BlockSpacingSupportAttributes> & IfSupport<HasSupport<TSupports, "dimensions">, BlockDimensionsSupportAttributes> & IfSupport<HasSupport<TSupports, "border">, BlockBorderSupportAttributes> & IfSupport<HasSupport<TSupports, "background">, BlockStyleAttributeSupportAttributes> & IfSupport<HasNestedSupport<TSupports, "filter", "duotone">, BlockStyleAttributeSupportAttributes> & IfSupport<HasSupport<TSupports, "position">, BlockStyleAttributeSupportAttributes> & IfSupport<HasSupport<TSupports, "shadow">, BlockStyleAttributeSupportAttributes>;
218
- export declare function collectBlockSupportsCompatibilityFeatures(supports: BlockSupportsInput): readonly WordPressBlockApiCompatibilityFeature[];
219
- export declare function createBlockSupportsCompatibilityManifest(supports: BlockSupportsInput, settings?: DefineSupportsOptions): WordPressBlockApiCompatibilityManifest;
220
212
  export declare function getDefinedSupportsCompatibilityManifest(supports: unknown): WordPressBlockApiCompatibilityManifest | undefined;
221
213
  export declare function defineSupports<const TSupports extends BlockSupportsInput & DefineSupportsInlineOptions>(supports: TSupports, options?: DefineSupportsOptions): DefinedBlockSupports<TSupports>;
222
- export {};
@@ -1,201 +1,10 @@
1
- import { createWordPressBlockApiCompatibilityManifest, } from "./compatibility.js";
2
- import { handleDiagnostics, } from "./shared/diagnostics.js";
3
- import { isNonArrayObject, isObjectRecord, } from "./shared/object-utils.js";
4
- export const BLOCK_SUPPORT_FEATURES = [
5
- 'align',
6
- 'alignWide',
7
- 'allowedBlocks',
8
- 'anchor',
9
- 'ariaLabel',
10
- 'autoRegister',
11
- 'background',
12
- 'border',
13
- 'className',
14
- 'color',
15
- 'contentRole',
16
- 'customClassName',
17
- 'dimensions',
18
- 'filter',
19
- 'html',
20
- 'inserter',
21
- 'interactivity',
22
- 'js',
23
- 'layout',
24
- 'lightbox',
25
- 'listView',
26
- 'lock',
27
- 'locking',
28
- 'multiple',
29
- 'position',
30
- 'renaming',
31
- 'reusable',
32
- 'shadow',
33
- 'spacing',
34
- 'splitting',
35
- 'typography',
36
- 'visibility',
37
- ];
38
- export const TYPOGRAPHY_SUPPORT_KEYS = [
39
- 'fontFamily',
40
- 'fontSize',
41
- 'fontStyle',
42
- 'fontWeight',
43
- 'letterSpacing',
44
- 'lineHeight',
45
- 'dropCap',
46
- 'textAlign',
47
- 'textColumns',
48
- 'textDecoration',
49
- 'textTransform',
50
- 'writingMode',
51
- ];
52
- export const SPACING_SUPPORT_KEYS = [
53
- 'blockGap',
54
- 'margin',
55
- 'padding',
56
- ];
1
+ import { handleDefineSupportsDiagnostics } from "./supports-diagnostics.js";
2
+ import { BLOCK_SUPPORT_FEATURES, SPACING_SUPPORT_KEYS, TYPOGRAPHY_SUPPORT_KEYS, } from "./supports-features.js";
3
+ import { collectBlockSupportsCompatibilityFeatures, createBlockSupportsCompatibilityManifest, } from "./supports-manifest.js";
4
+ import { resolveDefineSupportsSettings, splitDefineSupportsInput, } from "./supports-settings.js";
5
+ export { BLOCK_SUPPORT_FEATURES, SPACING_SUPPORT_KEYS, TYPOGRAPHY_SUPPORT_KEYS, collectBlockSupportsCompatibilityFeatures, createBlockSupportsCompatibilityManifest, };
6
+ import { isObjectRecord } from "./shared/object-utils.js";
57
7
  export const DEFINED_BLOCK_SUPPORTS_METADATA = Symbol.for("@wp-typia/block-types/defined-supports");
58
- const KNOWN_BLOCK_SUPPORT_FEATURES = new Set(BLOCK_SUPPORT_FEATURES);
59
- const DEFINE_SUPPORTS_INLINE_OPTION_KEYS = new Set([
60
- "allowUnknownFutureKeys",
61
- "logger",
62
- "minVersion",
63
- "minWordPress",
64
- "onDiagnostic",
65
- "strict",
66
- ]);
67
- const COLOR_COMPATIBILITY_SUPPORT_KEYS = [
68
- "button",
69
- "enableContrastChecker",
70
- "heading",
71
- ];
72
- const TYPOGRAPHY_COMPATIBILITY_SUPPORT_KEYS = [
73
- "fontSize",
74
- "letterSpacing",
75
- "lineHeight",
76
- "textAlign",
77
- "textDecoration",
78
- "textTransform",
79
- ];
80
- const TOP_LEVEL_COMPATIBILITY_SUPPORT_KEYS = [
81
- "allowedBlocks",
82
- "background",
83
- "contentRole",
84
- "dimensions",
85
- "listView",
86
- "position",
87
- "renaming",
88
- "shadow",
89
- "visibility",
90
- ];
91
- function isEnabledSupportValue(value) {
92
- return value !== false && value !== null && value !== undefined;
93
- }
94
- function isEnabledTopLevelSupportValue(value) {
95
- if (!isObjectRecord(value)) {
96
- return isNonArrayObject(value) ? false : isEnabledSupportValue(value);
97
- }
98
- return Object.entries(value).some(([key, nestedValue]) => !key.startsWith("__experimental") &&
99
- isEnabledSupportValue(nestedValue));
100
- }
101
- function hasEnabledNestedSupport(section, key) {
102
- return isObjectRecord(section) && isEnabledSupportValue(section[key]);
103
- }
104
- function addCompatibilityFeature(features, seen, feature) {
105
- const id = `blockSupports.${feature}`;
106
- if (seen.has(id)) {
107
- return;
108
- }
109
- seen.add(id);
110
- features.push({
111
- area: "blockSupports",
112
- feature,
113
- });
114
- }
115
- export function collectBlockSupportsCompatibilityFeatures(supports) {
116
- const features = [];
117
- const seen = new Set();
118
- for (const key of TOP_LEVEL_COMPATIBILITY_SUPPORT_KEYS) {
119
- if (isEnabledTopLevelSupportValue(supports[key])) {
120
- addCompatibilityFeature(features, seen, key);
121
- }
122
- }
123
- const spacing = supports.spacing;
124
- for (const key of SPACING_SUPPORT_KEYS) {
125
- if (hasEnabledNestedSupport(spacing, key)) {
126
- addCompatibilityFeature(features, seen, `spacing.${key}`);
127
- }
128
- }
129
- const typography = supports.typography;
130
- for (const key of TYPOGRAPHY_COMPATIBILITY_SUPPORT_KEYS) {
131
- if (hasEnabledNestedSupport(typography, key)) {
132
- addCompatibilityFeature(features, seen, `typography.${key}`);
133
- }
134
- }
135
- const color = supports.color;
136
- if (isObjectRecord(color)) {
137
- for (const key of COLOR_COMPATIBILITY_SUPPORT_KEYS) {
138
- if (isEnabledSupportValue(color[key])) {
139
- addCompatibilityFeature(features, seen, `color.${key}`);
140
- }
141
- }
142
- }
143
- if (hasEnabledNestedSupport(supports.filter, "duotone")) {
144
- addCompatibilityFeature(features, seen, "filter.duotone");
145
- }
146
- for (const key of Object.keys(supports)) {
147
- if (!KNOWN_BLOCK_SUPPORT_FEATURES.has(key) &&
148
- !DEFINE_SUPPORTS_INLINE_OPTION_KEYS.has(key) &&
149
- isEnabledTopLevelSupportValue(supports[key])) {
150
- addCompatibilityFeature(features, seen, key);
151
- }
152
- }
153
- return features;
154
- }
155
- function splitDefineSupportsInput(supports) {
156
- const normalizedSupports = {};
157
- const inlineOptions = {};
158
- for (const [key, value] of Object.entries(supports)) {
159
- if (DEFINE_SUPPORTS_INLINE_OPTION_KEYS.has(key)) {
160
- Object.assign(inlineOptions, { [key]: value });
161
- continue;
162
- }
163
- normalizedSupports[key] = value;
164
- }
165
- return {
166
- inlineOptions,
167
- supports: normalizedSupports,
168
- };
169
- }
170
- function resolveDefineSupportsSettings(inlineOptions, options) {
171
- const settings = {};
172
- const allowUnknownFutureKeys = options.allowUnknownFutureKeys ?? inlineOptions.allowUnknownFutureKeys;
173
- const minVersion = options.minVersion ??
174
- options.minWordPress ??
175
- inlineOptions.minVersion ??
176
- inlineOptions.minWordPress;
177
- const strict = options.strict ?? inlineOptions.strict;
178
- if (allowUnknownFutureKeys !== undefined) {
179
- Object.assign(settings, { allowUnknownFutureKeys });
180
- }
181
- if (minVersion !== undefined) {
182
- Object.assign(settings, { minVersion });
183
- }
184
- if (strict !== undefined) {
185
- Object.assign(settings, { strict });
186
- }
187
- return settings;
188
- }
189
- export function createBlockSupportsCompatibilityManifest(supports, settings = {}) {
190
- const compatibilitySettings = resolveDefineSupportsSettings({}, settings);
191
- return createWordPressBlockApiCompatibilityManifest(collectBlockSupportsCompatibilityFeatures(supports), compatibilitySettings);
192
- }
193
- function handleDefineSupportsDiagnostics(diagnostics, onDiagnostic, logger) {
194
- handleDiagnostics(diagnostics, onDiagnostic, {
195
- failureHeading: "WordPress block supports compatibility check failed:",
196
- logger,
197
- });
198
- }
199
8
  export function getDefinedSupportsCompatibilityManifest(supports) {
200
9
  return isObjectRecord(supports)
201
10
  ? supports[DEFINED_BLOCK_SUPPORTS_METADATA]?.manifest
@@ -0,0 +1,6 @@
1
+ import type { BlockAttributes } from "./registration.js";
2
+ import type { BlockVariationAuthoringDiagnostic, BlockVariationDefinition, BlockVariationDiagnostic, BlockVariationRegistrationEntry, DefineVariationOptions } from "./variations.js";
3
+ import type { ResolvedDefineVariationSettings } from "./variations-settings.js";
4
+ export declare function createVariationDiagnostics<TAttributes extends BlockAttributes>(blockName: string, variation: BlockVariationDefinition<TAttributes>, options: ResolvedDefineVariationSettings["diagnostics"]): readonly BlockVariationAuthoringDiagnostic[];
5
+ export declare function createCollectionDiagnostics(entries: readonly BlockVariationRegistrationEntry[], strict: boolean): readonly BlockVariationAuthoringDiagnostic[];
6
+ export declare function handleVariationDiagnostics(diagnostics: readonly BlockVariationDiagnostic[], onDiagnostic: DefineVariationOptions["onDiagnostic"], logger: DefineVariationOptions["logger"]): void;
@@ -0,0 +1,123 @@
1
+ import { getDiagnosticSeverity, handleDiagnostics } from "./shared/diagnostics.js";
2
+ import { isObjectRecord } from "./shared/object-utils.js";
3
+ const STABLE_VARIATION_MARKER_ATTRIBUTES = [
4
+ "className",
5
+ "namespace",
6
+ "wpTypiaVariation",
7
+ ];
8
+ function hasStableMarkerAttribute(attributes) {
9
+ if (!isObjectRecord(attributes)) {
10
+ return false;
11
+ }
12
+ return STABLE_VARIATION_MARKER_ATTRIBUTES.some((key) => key in attributes);
13
+ }
14
+ function stringifyActiveMarkerValue(value) {
15
+ try {
16
+ return JSON.stringify(value) ?? String(value);
17
+ }
18
+ catch {
19
+ return String(value);
20
+ }
21
+ }
22
+ function createActiveMarker(entry) {
23
+ const isActive = entry.variation.isActive;
24
+ if (!Array.isArray(isActive) || isActive.length === 0) {
25
+ return undefined;
26
+ }
27
+ const attributes = isObjectRecord(entry.variation.attributes)
28
+ ? entry.variation.attributes
29
+ : {};
30
+ return [...isActive]
31
+ .sort()
32
+ .map((attribute) => {
33
+ const value = attribute in attributes ? attributes[attribute] : "";
34
+ return `${attribute}=${stringifyActiveMarkerValue(value)}`;
35
+ })
36
+ .join("|");
37
+ }
38
+ export function createVariationDiagnostics(blockName, variation, options) {
39
+ const diagnostics = [];
40
+ const variationName = variation.name;
41
+ const attributes = variation.attributes;
42
+ const isActive = variation.isActive;
43
+ if (options.requireIsActive &&
44
+ !options.allowMissingIsActive &&
45
+ !variation.isDefault &&
46
+ isActive === undefined) {
47
+ diagnostics.push({
48
+ blockName,
49
+ code: "missing-is-active",
50
+ message: `Block variation "${variationName}" for "${blockName}" does not declare isActive; add an active discriminator or set allowMissingIsActive.`,
51
+ severity: "warning",
52
+ variationName,
53
+ });
54
+ }
55
+ if (options.requireIsActive &&
56
+ !options.allowMissingIsActive &&
57
+ !variation.isDefault &&
58
+ isActive === undefined &&
59
+ !hasStableMarkerAttribute(attributes)) {
60
+ diagnostics.push({
61
+ blockName,
62
+ code: "missing-stable-marker",
63
+ message: `Block variation "${variationName}" for "${blockName}" has no stable marker attribute such as className, namespace, or wpTypiaVariation.`,
64
+ severity: "warning",
65
+ variationName,
66
+ });
67
+ }
68
+ if (Array.isArray(isActive)) {
69
+ for (const attribute of isActive) {
70
+ if (!isObjectRecord(attributes) || !(attribute in attributes)) {
71
+ diagnostics.push({
72
+ attribute,
73
+ blockName,
74
+ code: "unknown-is-active-attribute",
75
+ message: `Block variation "${variationName}" for "${blockName}" uses isActive attribute "${attribute}" that is not present in its attributes.`,
76
+ severity: "warning",
77
+ variationName,
78
+ });
79
+ }
80
+ }
81
+ }
82
+ return diagnostics;
83
+ }
84
+ export function createCollectionDiagnostics(entries, strict) {
85
+ const diagnostics = [];
86
+ const seenNames = new Map();
87
+ const seenActiveMarkers = new Map();
88
+ for (const entry of entries) {
89
+ const nameKey = `${entry.blockName}:${entry.variation.name}`;
90
+ const activeMarker = createActiveMarker(entry);
91
+ if (seenNames.has(nameKey)) {
92
+ diagnostics.push({
93
+ blockName: entry.blockName,
94
+ code: "duplicate-variation-name",
95
+ message: `Duplicate block variation name "${entry.variation.name}" for "${entry.blockName}".`,
96
+ severity: getDiagnosticSeverity(strict),
97
+ variationName: entry.variation.name,
98
+ });
99
+ }
100
+ seenNames.set(nameKey, entry);
101
+ if (activeMarker && activeMarker.length > 0) {
102
+ const markerKey = `${entry.blockName}:${activeMarker}`;
103
+ const existing = seenActiveMarkers.get(markerKey);
104
+ if (existing) {
105
+ diagnostics.push({
106
+ blockName: entry.blockName,
107
+ code: "duplicate-active-marker",
108
+ message: `Block variations "${existing.variation.name}" and "${entry.variation.name}" for "${entry.blockName}" share the same isActive discriminator "${activeMarker}".`,
109
+ severity: "warning",
110
+ variationName: entry.variation.name,
111
+ });
112
+ }
113
+ seenActiveMarkers.set(markerKey, entry);
114
+ }
115
+ }
116
+ return diagnostics;
117
+ }
118
+ export function handleVariationDiagnostics(diagnostics, onDiagnostic, logger) {
119
+ handleDiagnostics(diagnostics, onDiagnostic, {
120
+ failureHeading: "WordPress block variation check failed:",
121
+ logger,
122
+ });
123
+ }
@@ -0,0 +1,5 @@
1
+ import { type WordPressBlockApiCompatibilityFeature, type WordPressBlockApiCompatibilityManifest, type WordPressCompatibilitySettings } from "./compatibility.js";
2
+ import type { DefineVariationOptions } from "./variations.js";
3
+ export declare function collectBlockVariationCompatibilityFeatures(): readonly WordPressBlockApiCompatibilityFeature[];
4
+ export declare function createBlockVariationCompatibilityManifest(settings?: DefineVariationOptions): WordPressBlockApiCompatibilityManifest;
5
+ export declare function createBlockVariationCompatibilityManifestFromSettings(settings: WordPressCompatibilitySettings): WordPressBlockApiCompatibilityManifest;
@@ -0,0 +1,17 @@
1
+ import { createWordPressBlockApiCompatibilityManifest, } from "./compatibility.js";
2
+ import { resolveDefineVariationSettings } from "./variations-settings.js";
3
+ export function collectBlockVariationCompatibilityFeatures() {
4
+ return [
5
+ {
6
+ area: "blockVariations",
7
+ feature: "editorRegistration",
8
+ },
9
+ ];
10
+ }
11
+ export function createBlockVariationCompatibilityManifest(settings = {}) {
12
+ const resolved = resolveDefineVariationSettings({}, settings);
13
+ return createBlockVariationCompatibilityManifestFromSettings(resolved.compatibility);
14
+ }
15
+ export function createBlockVariationCompatibilityManifestFromSettings(settings) {
16
+ return createWordPressBlockApiCompatibilityManifest(collectBlockVariationCompatibilityFeatures(), settings);
17
+ }
@@ -0,0 +1,18 @@
1
+ import type { WordPressCompatibilitySettings } from "./compatibility.js";
2
+ import type { BlockAttributes } from "./registration.js";
3
+ import type { BlockVariationDefinition, DefineVariationInlineOptions, DefineVariationOptions, StripDefineVariationOptions } from "./variations.js";
4
+ export interface ResolvedDefineVariationSettings {
5
+ readonly compatibility: WordPressCompatibilitySettings;
6
+ readonly diagnostics: {
7
+ readonly allowMissingIsActive: boolean;
8
+ readonly requireIsActive: boolean;
9
+ readonly strict: boolean;
10
+ };
11
+ readonly logger: DefineVariationOptions["logger"];
12
+ readonly onDiagnostic: DefineVariationOptions["onDiagnostic"];
13
+ }
14
+ export declare function splitDefineVariationInput<TAttributes extends BlockAttributes, TVariation extends BlockVariationDefinition<TAttributes> & DefineVariationInlineOptions>(variation: TVariation): {
15
+ inlineOptions: DefineVariationInlineOptions;
16
+ variation: StripDefineVariationOptions<TVariation> & BlockVariationDefinition<TAttributes>;
17
+ };
18
+ export declare function resolveDefineVariationSettings(inlineOptions: DefineVariationInlineOptions, options: DefineVariationOptions): ResolvedDefineVariationSettings;