@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.
@@ -0,0 +1,258 @@
1
+ import { createWordPressBlockApiCompatibilityManifest, } from "./compatibility.js";
2
+ import { getDiagnosticSeverity, handleDiagnostics, } from "./shared/diagnostics.js";
3
+ import { isObjectRecord } from "./shared/object-utils.js";
4
+ import { normalizeStaticRegistrationValue } from "./shared/static-registration.js";
5
+ export const DEFINED_BLOCK_VARIATION_METADATA = Symbol.for("@wp-typia/block-types/defined-variation");
6
+ export const DEFINED_BLOCK_VARIATIONS_METADATA = Symbol.for("@wp-typia/block-types/defined-variations");
7
+ const DEFINE_VARIATION_INLINE_OPTION_KEYS = new Set([
8
+ "allowMissingIsActive",
9
+ "logger",
10
+ "minVersion",
11
+ "minWordPress",
12
+ "onDiagnostic",
13
+ "requireIsActive",
14
+ "strict",
15
+ ]);
16
+ const STABLE_VARIATION_MARKER_ATTRIBUTES = [
17
+ "className",
18
+ "namespace",
19
+ "wpTypiaVariation",
20
+ ];
21
+ function splitDefineVariationInput(variation) {
22
+ const inlineOptions = {};
23
+ const normalizedVariation = {};
24
+ for (const [key, value] of Object.entries(variation)) {
25
+ if (DEFINE_VARIATION_INLINE_OPTION_KEYS.has(key)) {
26
+ Object.assign(inlineOptions, { [key]: value });
27
+ continue;
28
+ }
29
+ normalizedVariation[key] = value;
30
+ }
31
+ return {
32
+ inlineOptions,
33
+ variation: normalizedVariation,
34
+ };
35
+ }
36
+ function resolveDefineVariationSettings(inlineOptions, options) {
37
+ const compatibility = {};
38
+ const allowUnknownFutureKeys = options.allowUnknownFutureKeys;
39
+ const minVersion = options.minVersion ??
40
+ options.minWordPress ??
41
+ inlineOptions.minVersion ??
42
+ inlineOptions.minWordPress;
43
+ const strict = options.strict ?? inlineOptions.strict ?? true;
44
+ if (allowUnknownFutureKeys !== undefined) {
45
+ Object.assign(compatibility, { allowUnknownFutureKeys });
46
+ }
47
+ if (minVersion !== undefined) {
48
+ Object.assign(compatibility, { minVersion });
49
+ }
50
+ Object.assign(compatibility, { strict });
51
+ return {
52
+ compatibility,
53
+ diagnostics: {
54
+ allowMissingIsActive: options.allowMissingIsActive ?? inlineOptions.allowMissingIsActive ?? false,
55
+ requireIsActive: options.requireIsActive ?? inlineOptions.requireIsActive ?? true,
56
+ strict,
57
+ },
58
+ logger: options.logger ?? inlineOptions.logger,
59
+ onDiagnostic: options.onDiagnostic ?? inlineOptions.onDiagnostic,
60
+ };
61
+ }
62
+ export function collectBlockVariationCompatibilityFeatures() {
63
+ return [
64
+ {
65
+ area: "blockVariations",
66
+ feature: "editorRegistration",
67
+ },
68
+ ];
69
+ }
70
+ export function createBlockVariationCompatibilityManifest(settings = {}) {
71
+ const resolved = resolveDefineVariationSettings({}, settings);
72
+ return createWordPressBlockApiCompatibilityManifest(collectBlockVariationCompatibilityFeatures(), resolved.compatibility);
73
+ }
74
+ function hasStableMarkerAttribute(attributes) {
75
+ if (!isObjectRecord(attributes)) {
76
+ return false;
77
+ }
78
+ return STABLE_VARIATION_MARKER_ATTRIBUTES.some((key) => key in attributes);
79
+ }
80
+ function createVariationDiagnostics(blockName, variation, options) {
81
+ const diagnostics = [];
82
+ const variationName = variation.name;
83
+ const attributes = variation.attributes;
84
+ const isActive = variation.isActive;
85
+ if (options.requireIsActive &&
86
+ !options.allowMissingIsActive &&
87
+ !variation.isDefault &&
88
+ isActive === undefined) {
89
+ diagnostics.push({
90
+ blockName,
91
+ code: "missing-is-active",
92
+ message: `Block variation "${variationName}" for "${blockName}" does not declare isActive; add an active discriminator or set allowMissingIsActive.`,
93
+ severity: "warning",
94
+ variationName,
95
+ });
96
+ }
97
+ if (options.requireIsActive &&
98
+ !options.allowMissingIsActive &&
99
+ !variation.isDefault &&
100
+ isActive === undefined &&
101
+ !hasStableMarkerAttribute(attributes)) {
102
+ diagnostics.push({
103
+ blockName,
104
+ code: "missing-stable-marker",
105
+ message: `Block variation "${variationName}" for "${blockName}" has no stable marker attribute such as className, namespace, or wpTypiaVariation.`,
106
+ severity: "warning",
107
+ variationName,
108
+ });
109
+ }
110
+ if (Array.isArray(isActive)) {
111
+ for (const attribute of isActive) {
112
+ if (!isObjectRecord(attributes) || !(attribute in attributes)) {
113
+ diagnostics.push({
114
+ attribute,
115
+ blockName,
116
+ code: "unknown-is-active-attribute",
117
+ message: `Block variation "${variationName}" for "${blockName}" uses isActive attribute "${attribute}" that is not present in its attributes.`,
118
+ severity: "warning",
119
+ variationName,
120
+ });
121
+ }
122
+ }
123
+ }
124
+ return diagnostics;
125
+ }
126
+ function handleVariationDiagnostics(diagnostics, onDiagnostic, logger) {
127
+ handleDiagnostics(diagnostics, onDiagnostic, {
128
+ failureHeading: "WordPress block variation check failed:",
129
+ logger,
130
+ });
131
+ }
132
+ export function getDefinedVariationMetadata(variation) {
133
+ return isObjectRecord(variation)
134
+ ? variation[DEFINED_BLOCK_VARIATION_METADATA]
135
+ : undefined;
136
+ }
137
+ export function getDefinedVariationBlockName(variation) {
138
+ return getDefinedVariationMetadata(variation)?.blockName;
139
+ }
140
+ export function getDefinedVariationCompatibilityManifest(variation) {
141
+ return getDefinedVariationMetadata(variation)?.manifest;
142
+ }
143
+ export function getDefinedVariationsMetadata(variations) {
144
+ return Array.isArray(variations)
145
+ ? variations[DEFINED_BLOCK_VARIATIONS_METADATA]
146
+ : undefined;
147
+ }
148
+ export function defineVariation(blockName, variation, options = {}) {
149
+ const { inlineOptions, variation: normalizedVariation } = splitDefineVariationInput(variation);
150
+ const resolved = resolveDefineVariationSettings(inlineOptions, options);
151
+ const manifest = createWordPressBlockApiCompatibilityManifest(collectBlockVariationCompatibilityFeatures(), resolved.compatibility);
152
+ const diagnostics = [
153
+ ...manifest.diagnostics,
154
+ ...createVariationDiagnostics(blockName, normalizedVariation, resolved.diagnostics),
155
+ ];
156
+ handleVariationDiagnostics(diagnostics, resolved.onDiagnostic, resolved.logger);
157
+ Object.defineProperty(normalizedVariation, DEFINED_BLOCK_VARIATION_METADATA, {
158
+ configurable: false,
159
+ enumerable: false,
160
+ value: {
161
+ blockName,
162
+ diagnostics,
163
+ manifest,
164
+ },
165
+ writable: false,
166
+ });
167
+ return normalizedVariation;
168
+ }
169
+ function createCollectionDiagnostics(entries, strict) {
170
+ const diagnostics = [];
171
+ const seenNames = new Map();
172
+ const seenActiveMarkers = new Map();
173
+ for (const entry of entries) {
174
+ const nameKey = `${entry.blockName}:${entry.variation.name}`;
175
+ const activeMarker = Array.isArray(entry.variation.isActive)
176
+ ? entry.variation.isActive.join("|")
177
+ : undefined;
178
+ if (seenNames.has(nameKey)) {
179
+ diagnostics.push({
180
+ blockName: entry.blockName,
181
+ code: "duplicate-variation-name",
182
+ message: `Duplicate block variation name "${entry.variation.name}" for "${entry.blockName}".`,
183
+ severity: getDiagnosticSeverity(strict),
184
+ variationName: entry.variation.name,
185
+ });
186
+ }
187
+ seenNames.set(nameKey, entry);
188
+ if (activeMarker && activeMarker.length > 0) {
189
+ const markerKey = `${entry.blockName}:${activeMarker}`;
190
+ const existing = seenActiveMarkers.get(markerKey);
191
+ if (existing) {
192
+ diagnostics.push({
193
+ blockName: entry.blockName,
194
+ code: "duplicate-active-marker",
195
+ message: `Block variations "${existing.variation.name}" and "${entry.variation.name}" for "${entry.blockName}" share the same isActive discriminator "${activeMarker}".`,
196
+ severity: "warning",
197
+ variationName: entry.variation.name,
198
+ });
199
+ }
200
+ seenActiveMarkers.set(markerKey, entry);
201
+ }
202
+ }
203
+ return diagnostics;
204
+ }
205
+ export function createBlockVariationRegistrationPlan(variations) {
206
+ return variations.map((variation) => {
207
+ const metadata = getDefinedVariationMetadata(variation);
208
+ if (!metadata) {
209
+ throw new Error(`Block variation "${variation.name}" was not created by defineVariation().`);
210
+ }
211
+ return {
212
+ blockName: metadata.blockName,
213
+ variation,
214
+ };
215
+ });
216
+ }
217
+ export function defineVariations(variations, options = {}) {
218
+ const entries = createBlockVariationRegistrationPlan(variations);
219
+ const strict = options.strict ?? true;
220
+ const variationDiagnostics = entries.flatMap((entry) => getDefinedVariationMetadata(entry.variation)?.diagnostics ?? []);
221
+ const collectionDiagnostics = createCollectionDiagnostics(entries, strict);
222
+ const diagnostics = [
223
+ ...variationDiagnostics,
224
+ ...collectionDiagnostics,
225
+ ];
226
+ handleVariationDiagnostics(collectionDiagnostics, options.onDiagnostic, options.logger);
227
+ const normalizedVariations = [...variations];
228
+ Object.defineProperty(normalizedVariations, DEFINED_BLOCK_VARIATIONS_METADATA, {
229
+ configurable: false,
230
+ enumerable: false,
231
+ value: {
232
+ diagnostics,
233
+ entries,
234
+ },
235
+ writable: false,
236
+ });
237
+ return normalizedVariations;
238
+ }
239
+ export function createStaticBlockVariationRegistrationSource(variations, options = {}) {
240
+ const importSource = options.importSource ?? "@wordpress/blocks";
241
+ const functionName = options.functionName ?? "registerWpTypiaBlockVariations";
242
+ const entries = createBlockVariationRegistrationPlan(variations).map((entry, index) => normalizeStaticRegistrationValue(entry, `variations[${index}]`, {
243
+ description: "variation",
244
+ }));
245
+ const serializedEntries = JSON.stringify(entries, null, 2);
246
+ return [
247
+ `import { registerBlockVariation } from ${JSON.stringify(importSource)};`,
248
+ "",
249
+ `const variations = ${serializedEntries};`,
250
+ "",
251
+ `export function ${functionName}() {`,
252
+ " for (const { blockName, variation } of variations) {",
253
+ " registerBlockVariation(blockName, variation);",
254
+ " }",
255
+ "}",
256
+ "",
257
+ ].join("\n");
258
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wp-typia/block-types",
3
- "version": "0.2.4",
3
+ "version": "0.3.1",
4
4
  "description": "Shared WordPress block semantic types derived from Gutenberg and unofficial declarations",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -56,6 +56,16 @@
56
56
  "import": "./dist/blocks/index.js",
57
57
  "default": "./dist/blocks/index.js"
58
58
  },
59
+ "./blocks/bindings": {
60
+ "types": "./dist/blocks/bindings.d.ts",
61
+ "import": "./dist/blocks/bindings.js",
62
+ "default": "./dist/blocks/bindings.js"
63
+ },
64
+ "./blocks/compatibility": {
65
+ "types": "./dist/blocks/compatibility.d.ts",
66
+ "import": "./dist/blocks/compatibility.js",
67
+ "default": "./dist/blocks/compatibility.js"
68
+ },
59
69
  "./blocks/registration": {
60
70
  "types": "./dist/blocks/registration.d.ts",
61
71
  "import": "./dist/blocks/registration.js",
@@ -66,6 +76,11 @@
66
76
  "import": "./dist/blocks/supports.js",
67
77
  "default": "./dist/blocks/supports.js"
68
78
  },
79
+ "./blocks/variations": {
80
+ "types": "./dist/blocks/variations.d.ts",
81
+ "import": "./dist/blocks/variations.js",
82
+ "default": "./dist/blocks/variations.js"
83
+ },
69
84
  "./package.json": "./package.json"
70
85
  },
71
86
  "files": [