@compact-design/core 0.2.0 → 0.3.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/dist/generated-schema.d.ts +598 -2
- package/dist/index.cjs +2266 -400
- package/dist/index.d.ts +32 -2
- package/dist/index.js +2234 -399
- package/dist/normalize.d.ts +7 -1
- package/dist/patch-definitions.d.ts +41 -0
- package/dist/patch-duplicate.d.ts +34 -0
- package/dist/patch-keys.d.ts +61 -0
- package/dist/patch-prototype.d.ts +39 -0
- package/dist/patch.d.ts +25 -1
- package/dist/types.d.ts +69 -3
- package/dist/validate.d.ts +15 -1
- package/package.json +1 -1
package/dist/normalize.d.ts
CHANGED
|
@@ -1,4 +1,10 @@
|
|
|
1
|
-
import type { InternalDocument, InternalPatchDocument } from "./types";
|
|
1
|
+
import type { InternalDocument, InternalPatchDocument, JsonObject, PatchSetValues } from "./types";
|
|
2
2
|
export declare function normalizeDocument(value: unknown): InternalDocument;
|
|
3
|
+
/**
|
|
4
|
+
* Normalize a patch `set` without knowing the target. Only authored keys are
|
|
5
|
+
* produced; nothing is defaulted (no Arial, no TEXT fill). Unknown, deferred
|
|
6
|
+
* and immutable keys throw. Coordinates stay parent-relative.
|
|
7
|
+
*/
|
|
8
|
+
export declare function normalizePatchSet(set: JsonObject, path?: string): PatchSetValues;
|
|
3
9
|
export declare function isPatchDocument(value: unknown): boolean;
|
|
4
10
|
export declare function normalizePatchDocument(value: unknown): InternalPatchDocument;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { ComponentPropertyPatchEntry, DesignProperties, InternalNode } from "./types";
|
|
2
|
+
export type AxisRename = {
|
|
3
|
+
from: string;
|
|
4
|
+
to: string;
|
|
5
|
+
};
|
|
6
|
+
export type OptionRename = {
|
|
7
|
+
axis: string;
|
|
8
|
+
from: string;
|
|
9
|
+
to: string;
|
|
10
|
+
};
|
|
11
|
+
/** Explicit variantAxes patch entry: array sets options (never renames); object renames explicitly. */
|
|
12
|
+
export type VariantAxisPatchEntry = null | string[] | {
|
|
13
|
+
rename?: string;
|
|
14
|
+
options?: string[];
|
|
15
|
+
renameOptions?: Record<string, string>;
|
|
16
|
+
};
|
|
17
|
+
export type VariantAxesPatch = Record<string, VariantAxisPatchEntry>;
|
|
18
|
+
/**
|
|
19
|
+
* Apply a variantAxes shallow-merge with **explicit** renames only.
|
|
20
|
+
* - `axis: string[]` — replace that axis's options. Never inferred as a rename.
|
|
21
|
+
* - `axis: { rename?, options?, renameOptions? }` — explicit axis/option renames.
|
|
22
|
+
* - `axis: null` — error (Figma cannot delete VARIANT properties).
|
|
23
|
+
* Unmentioned axes are kept.
|
|
24
|
+
*/
|
|
25
|
+
export declare function detectVariantRenames(current: Record<string, string[]>, patch: VariantAxesPatch): {
|
|
26
|
+
axes: Record<string, string[]>;
|
|
27
|
+
axisRenames: AxisRename[];
|
|
28
|
+
optionRenames: OptionRename[];
|
|
29
|
+
errors: string[];
|
|
30
|
+
};
|
|
31
|
+
/** After renames, ensure removed options are not still sitting on children without renameOptions. */
|
|
32
|
+
export declare function variantAxesChildConflicts(set: InternalNode, previousAxes: Record<string, string[]>, nextAxes: Record<string, string[]>, optionRenames: OptionRename[], axisRenames: AxisRename[]): string[];
|
|
33
|
+
/** Every declared option must appear on at least one COMPONENT child (Figma derives options from names). */
|
|
34
|
+
export declare function variantAxesUncarriedOptions(set: InternalNode, axes: Record<string, string[]>): string[];
|
|
35
|
+
export declare function applyVariantRenamesInForest(roots: InternalNode[], setId: string, axisRenames: AxisRename[], optionRenames: OptionRename[], axes: Record<string, string[]>, index?: Map<string, {
|
|
36
|
+
node: InternalNode;
|
|
37
|
+
parent: InternalNode | null;
|
|
38
|
+
}>): void;
|
|
39
|
+
export declare function applyComponentPropertiesPatch(props: DesignProperties, patch: Record<string, ComponentPropertyPatchEntry | null> | null, path: string): string[];
|
|
40
|
+
export declare function applyVariantPatchOnComponent(node: InternalNode, parent: InternalNode | null, patch: Record<string, string | null> | null, path: string): string[];
|
|
41
|
+
export declare function rewriteVariantChildNames(set: InternalNode): void;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { InternalNode, JsonObject } from "./types";
|
|
2
|
+
/** Collect every id in a subtree (root first, depth-first). */
|
|
3
|
+
export declare function collectSubtreeIds(node: InternalNode): string[];
|
|
4
|
+
export declare function subtreeContainsType(node: InternalNode, types: Set<string>): boolean;
|
|
5
|
+
/**
|
|
6
|
+
* Build the deterministic id map for a duplicate.
|
|
7
|
+
* Default: `<sourceId><idSuffix>` for every id in the subtree.
|
|
8
|
+
* `ids` overrides specific source→new mappings; every key must be in the subtree.
|
|
9
|
+
*/
|
|
10
|
+
export declare function buildDuplicateIdMap(source: InternalNode, idSuffix: string, ids: Record<string, string> | undefined, path: string): {
|
|
11
|
+
map: Map<string, string>;
|
|
12
|
+
errors: string[];
|
|
13
|
+
};
|
|
14
|
+
/** Same as buildDuplicateIdMap but when only the id set is known (e.g. live Figma walk). */
|
|
15
|
+
export declare function buildDuplicateIdMapFromIds(subtreeIds: Iterable<string>, idSuffix: string, ids: Record<string, string> | undefined, path: string): {
|
|
16
|
+
map: Map<string, string>;
|
|
17
|
+
errors: string[];
|
|
18
|
+
};
|
|
19
|
+
/** Deep-clone a node tree applying an id map (and re-pointing internal prototype destinations). */
|
|
20
|
+
export declare function cloneSubtreeWithIds(node: InternalNode, idMap: Map<string, string>): InternalNode;
|
|
21
|
+
/** Re-point prototype destinations that land inside the duplicated subtree. */
|
|
22
|
+
export declare function rewritePrototypeDestinations(properties: JsonObject, idMap: Map<string, string>): void;
|
|
23
|
+
/**
|
|
24
|
+
* Replace only delimited whole ids in text (quoted `'id'` / `"id"`, or path
|
|
25
|
+
* segments bounded by non-id characters). Longest source ids first so
|
|
26
|
+
* `card-title` is not corrupted by a shorter `card` mapping.
|
|
27
|
+
*/
|
|
28
|
+
export declare function remapDelimitedIds(text: string, idMap: Map<string, string>): string;
|
|
29
|
+
/**
|
|
30
|
+
* Remap issue identity keys through a source→copy id map so duplicated
|
|
31
|
+
* pre-existing issues on the copy are exempt (with multiplicity).
|
|
32
|
+
* Owner is remapped exactly (`node:${id}`); path/message only via delimited ids.
|
|
33
|
+
*/
|
|
34
|
+
export declare function remapIssueKeyThroughDuplicate(key: string, idMap: Map<string, string>): string | null;
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import type { JsonObject } from "./types";
|
|
2
|
+
/**
|
|
3
|
+
* Single source of truth for `set` in patch operations. Every key a node may
|
|
4
|
+
* carry in the schema is either settable here or explicitly excluded. Core,
|
|
5
|
+
* the JSON schema test-suite, and the Figma adapter all read this list.
|
|
6
|
+
*/
|
|
7
|
+
export declare const PATCH_SET_EXCLUDED_NODE_KEYS: readonly ["id", "type", "children", "coordinateMode"];
|
|
8
|
+
export declare const PATCH_SET_KEYS: readonly ["name", "x", "y", "w", "h", "rotation", "fill", "fills", "stroke", "strokes", "strokeWeight", "strokeTopWeight", "strokeRightWeight", "strokeBottomWeight", "strokeLeftWeight", "strokeAlign", "strokeCap", "strokeJoin", "dashPattern", "cornerRadius", "cornerRadii", "opacity", "blendMode", "visible", "locked", "isMask", "clipsContent", "effects", "elevation", "shadow", "layout", "constraints", "layoutSizingHorizontal", "layoutSizingVertical", "layoutAlign", "layoutGrow", "layoutPositioning", "minWidth", "maxWidth", "minHeight", "maxHeight", "layoutGrids", "text", "font", "lineHeight", "letterSpacing", "align", "verticalAlignment", "textDecoration", "textCase", "paragraphSpacing", "paragraphIndent", "listSpacing", "hangingPunctuation", "hangingList", "textAutoResize", "textTruncation", "maxLines", "runs", "pointCount", "innerRadius", "startingAngle", "endingAngle", "innerRadiusRatio", "svg", "vectorPaths", "componentId", "componentProperties", "instanceProperties", "componentPropertyReferences", "variantAxes", "variant", "operation", "prototype", "overflowDirection", "numberOfFixedChildren", "styleRefs", "bindings", "variableModes"];
|
|
9
|
+
export type PatchSetKey = typeof PATCH_SET_KEYS[number];
|
|
10
|
+
/**
|
|
11
|
+
* - `scalar`: the value replaces the previous value.
|
|
12
|
+
* - `merge`: objects deep-merge into the current value (unmentioned fields are kept).
|
|
13
|
+
* - `replace`: arrays (paint, effect, run, grid, path lists) replace the whole list.
|
|
14
|
+
* - `deferred`: recognised but not patchable yet; both engines reject it with PATCH_SET_UNSUPPORTED.
|
|
15
|
+
* - object merge keys (`bindings`, `styleRefs`, `variableModes`, `instanceProperties`, `componentPropertyReferences`, `componentProperties`, `variantAxes`, `variant`): shallow-merge entries; a field set to `null` clears that entry (except variantAxes: deleting an axis is an error).
|
|
16
|
+
* - `immutable`: can never be patched in place; remove + insert instead.
|
|
17
|
+
*/
|
|
18
|
+
export type PatchSetSemantics = "scalar" | "merge" | "replace" | "deferred" | "immutable";
|
|
19
|
+
export declare const PATCH_SET_SEMANTICS: Readonly<Record<PatchSetKey, PatchSetSemantics>>;
|
|
20
|
+
export declare const PATCH_SET_DEFERRED_KEYS: readonly PatchSetKey[];
|
|
21
|
+
/** Compact node types each key applies to. `null` means every type. */
|
|
22
|
+
export declare const PATCH_SET_APPLIES_TO: Readonly<Record<PatchSetKey, readonly string[] | null>>;
|
|
23
|
+
/** Keys that style a TEXT node and are owned by a linked text style. */
|
|
24
|
+
export declare const PATCH_TEXT_STYLE_KEYS: readonly PatchSetKey[];
|
|
25
|
+
export declare function isPatchSetKey(key: string): key is PatchSetKey;
|
|
26
|
+
/**
|
|
27
|
+
* The state of a patch target as seen by an engine (core document tree or the
|
|
28
|
+
* Figma scene). Both engines build this and run the same rules, so a set that
|
|
29
|
+
* is rejected in one is rejected in the other.
|
|
30
|
+
*/
|
|
31
|
+
export interface PatchTargetContext {
|
|
32
|
+
/** Compact node type of the target (Figma maps its native type to the compact one). */
|
|
33
|
+
type: string;
|
|
34
|
+
/** Compact type of the parent, or null for a root canvas. */
|
|
35
|
+
parentType: string | null;
|
|
36
|
+
/** Parent currently has Auto Layout. */
|
|
37
|
+
parentAutoLayout: boolean;
|
|
38
|
+
/** Target currently has Auto Layout (before this set). */
|
|
39
|
+
autoLayout: boolean;
|
|
40
|
+
/** Current layoutPositioning of the target. */
|
|
41
|
+
layoutPositioning?: string;
|
|
42
|
+
/** TEXT with per-range styling (core: a run carrying font/fill/letterSpacing/textDecoration/link; Figma: some text property is "mixed" in Figma). */
|
|
43
|
+
mixedText: boolean;
|
|
44
|
+
/** TEXT whose fonts differ per range (core: a run with font.family/style; Figma: fontName is "mixed" in Figma). */
|
|
45
|
+
mixedFontName: boolean;
|
|
46
|
+
/** TEXT linked to a text style (core: styleRefs.text; Figma: textStyleId). */
|
|
47
|
+
textStyle: boolean;
|
|
48
|
+
/** Variable-bound fields on the target (compact binding field names). */
|
|
49
|
+
boundFields: readonly string[];
|
|
50
|
+
/** Number of direct children. */
|
|
51
|
+
childCount: number;
|
|
52
|
+
}
|
|
53
|
+
/** Variable-binding field names a set would overwrite (fill/stroke excluded: those detach — see docs). */
|
|
54
|
+
export declare function patchSetBindingFields(set: JsonObject): string[];
|
|
55
|
+
/** Shape checks that need no target. Returns `key: message` strings. */
|
|
56
|
+
export declare function patchSetShapeIssues(set: JsonObject): string[];
|
|
57
|
+
/**
|
|
58
|
+
* Target-dependent rules. Both engines call this with their own view of the
|
|
59
|
+
* target before applying a set. Returns `key: message` strings.
|
|
60
|
+
*/
|
|
61
|
+
export declare function patchSetTargetIssues(set: JsonObject, context: PatchTargetContext): string[];
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { InternalDocument, InternalNode, JsonObject } from "./types";
|
|
2
|
+
/** Walk every destination-bearing action in a prototype array. */
|
|
3
|
+
export declare function forEachPrototypeDestination(prototype: unknown, visit: (action: JsonObject, type: string, destination: string, actionPath: string) => void, basePath?: string): void;
|
|
4
|
+
export declare function isAfterTimeoutReaction(reaction: JsonObject): boolean;
|
|
5
|
+
/** True when `nodeId` is a document.nodes root (top-level canvas frame). */
|
|
6
|
+
export declare function isTopLevelNodeId(roots: InternalNode[], nodeId: string): boolean;
|
|
7
|
+
export type PrototypeLookup = {
|
|
8
|
+
has: (id: string) => boolean;
|
|
9
|
+
typeOf?: (id: string) => string | undefined;
|
|
10
|
+
/** Canvas root id for a node id (document.nodes root). */
|
|
11
|
+
canvasOf?: (id: string) => string | undefined;
|
|
12
|
+
/** Whether an id is a top-level canvas frame. */
|
|
13
|
+
isTopLevel?: (id: string) => boolean;
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* Shared destination checks (missing / CHANGE_TO / SCROLL_TO).
|
|
17
|
+
* Used by validateDocument. Does not require NAVIGATE destinations to be top-level
|
|
18
|
+
* (import stays lenient).
|
|
19
|
+
*/
|
|
20
|
+
export declare function assertPrototypeSetDestinations(prototype: unknown, lookup: PrototypeLookup, path: string, sourceId?: string): string[];
|
|
21
|
+
/**
|
|
22
|
+
* Strict rules for patch `set.prototype` only: NAVIGATE/SWAP/OVERLAY destinations
|
|
23
|
+
* must be top-level frames; AFTER_TIMEOUT only on a top-level target.
|
|
24
|
+
*/
|
|
25
|
+
export declare function assertPrototypePatchRules(prototype: unknown, lookup: PrototypeLookup, path: string, sourceId: string | undefined, sourceIsTopLevel: boolean): string[];
|
|
26
|
+
/** Top-level canvas id for a node (the document.nodes root containing it). */
|
|
27
|
+
export declare function canvasRootId(roots: InternalNode[], nodeId: string): string | undefined;
|
|
28
|
+
/**
|
|
29
|
+
* Document-wide prototype destination errors (missing / CHANGE_TO / SCROLL_TO).
|
|
30
|
+
* Used by validateDocument so end-of-patch remove of a destination fails.
|
|
31
|
+
* Import-lenient: nested NAVIGATE destinations are allowed here.
|
|
32
|
+
*/
|
|
33
|
+
export declare function prototypeDestinationErrors(document: InternalDocument): string[];
|
|
34
|
+
/**
|
|
35
|
+
* Strict patch rules across the whole document (top-level NAVIGATE dest +
|
|
36
|
+
* AFTER_TIMEOUT only on top-level hosts). Used at end of patch with multiset
|
|
37
|
+
* exemption against the pre-patch document.
|
|
38
|
+
*/
|
|
39
|
+
export declare function prototypePatchStrictErrors(document: InternalDocument): string[];
|
package/dist/patch.d.ts
CHANGED
|
@@ -1,6 +1,30 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { type RepairIssue } from "./lint";
|
|
2
|
+
import { type PatchTargetContext } from "./patch-keys";
|
|
3
|
+
import type { InternalDocument, InternalNode, InternalPatchDocument } from "./types";
|
|
2
4
|
export interface PatchResult {
|
|
3
5
|
document: InternalDocument;
|
|
4
6
|
affectedIds: string[];
|
|
7
|
+
warnings: string[];
|
|
5
8
|
}
|
|
9
|
+
/** Thrown by applyPatch. `issues` carries every problem as structured repair output. */
|
|
10
|
+
export declare class PatchError extends Error {
|
|
11
|
+
readonly issues: RepairIssue[];
|
|
12
|
+
constructor(issues: RepairIssue[]);
|
|
13
|
+
}
|
|
14
|
+
/** Core's view of a target, mirrored by the Figma adapter's figmaPatchContext. */
|
|
15
|
+
export declare function corePatchContext(node: InternalNode, parent: InternalNode | null): PatchTargetContext;
|
|
16
|
+
/**
|
|
17
|
+
* Apply a normalized patch to a canonical document. The input is never
|
|
18
|
+
* mutated. Throws PatchError (with structured issues) when an operation is
|
|
19
|
+
* rejected or when the patched document fails validateDocument.
|
|
20
|
+
*/
|
|
6
21
|
export declare function applyDocumentPatch(document: InternalDocument, patch: InternalPatchDocument): PatchResult;
|
|
22
|
+
/**
|
|
23
|
+
* Issues present in `after` but not in `before`. Issues already in the input
|
|
24
|
+
* document never block a patch, even on nodes the patch touches; only issues
|
|
25
|
+
* the patch introduces (directly or through a move/insert/remove) are
|
|
26
|
+
* reported. Identity is code + owner (node id / variable / document) + the
|
|
27
|
+
* property path inside the owner + message, never an array index, and the
|
|
28
|
+
* comparison is a multiset so a second copy of an existing issue counts as new.
|
|
29
|
+
*/
|
|
30
|
+
export declare function newDocumentIssues(before: InternalDocument, after: InternalDocument, duplicateMaps?: Array<Map<string, string>>): RepairIssue[];
|
package/dist/types.d.ts
CHANGED
|
@@ -22,13 +22,20 @@ export interface Constraints {
|
|
|
22
22
|
horizontal: "MIN" | "CENTER" | "MAX" | "STRETCH" | "SCALE";
|
|
23
23
|
vertical: "MIN" | "CENTER" | "MAX" | "STRETCH" | "SCALE";
|
|
24
24
|
}
|
|
25
|
-
|
|
25
|
+
/** Authorable component property types. VARIANT axes use variantAxes/variant on COMPONENT_SET instead; Figma SLOT is out of scope. */
|
|
26
|
+
export type ComponentPropertyType = "BOOLEAN" | "TEXT" | "INSTANCE_SWAP";
|
|
26
27
|
export interface ComponentPropertyOptions {
|
|
27
28
|
preferredValues?: Array<{
|
|
28
29
|
type: "COMPONENT" | "COMPONENT_SET";
|
|
29
30
|
key: string;
|
|
30
31
|
}>;
|
|
31
32
|
}
|
|
33
|
+
/** Child-layer links to the nearest ancestor COMPONENT's componentProperties (Figma componentPropertyReferences). Values are authored property names. */
|
|
34
|
+
export interface ComponentPropertyReferences {
|
|
35
|
+
characters?: string;
|
|
36
|
+
visible?: string;
|
|
37
|
+
mainComponent?: string;
|
|
38
|
+
}
|
|
32
39
|
export type OverflowDirection = "NONE" | "HORIZONTAL" | "VERTICAL" | "BOTH";
|
|
33
40
|
export type BlendMode = "PASS_THROUGH" | "NORMAL" | "DARKEN" | "MULTIPLY" | "LINEAR_BURN" | "COLOR_BURN" | "LIGHTEN" | "SCREEN" | "LINEAR_DODGE" | "COLOR_DODGE" | "OVERLAY" | "SOFT_LIGHT" | "HARD_LIGHT" | "DIFFERENCE" | "EXCLUSION" | "HUE" | "SATURATION" | "COLOR" | "LUMINOSITY";
|
|
34
41
|
export type StrokeCap = "NONE" | "ROUND" | "SQUARE" | "LINE_ARROW" | "TRIANGLE_ARROW" | "DIAMOND_FILLED" | "CIRCLE_FILLED" | "TRIANGLE_FILLED" | "WASHI_TAPE_1" | "WASHI_TAPE_2" | "WASHI_TAPE_3" | "WASHI_TAPE_4" | "WASHI_TAPE_5" | "WASHI_TAPE_6";
|
|
@@ -156,6 +163,7 @@ export interface DesignProperties {
|
|
|
156
163
|
options?: ComponentPropertyOptions;
|
|
157
164
|
}>;
|
|
158
165
|
instanceProperties?: Record<string, string | boolean | VariableAlias>;
|
|
166
|
+
componentPropertyReferences?: ComponentPropertyReferences;
|
|
159
167
|
operation?: "UNION" | "SUBTRACT" | "INTERSECT" | "EXCLUDE";
|
|
160
168
|
overflowDirection?: OverflowDirection;
|
|
161
169
|
numberOfFixedChildren?: number;
|
|
@@ -262,13 +270,71 @@ export interface InternalDocument {
|
|
|
262
270
|
variables: VariableCollectionDefinition[];
|
|
263
271
|
}
|
|
264
272
|
export type ImportMode = "CREATE" | "REPLACE" | "UPDATE";
|
|
273
|
+
/**
|
|
274
|
+
* Normalized values of a patch `set`, independent of the target type. Only
|
|
275
|
+
* keys present in the authored set appear here: no defaults are added.
|
|
276
|
+
* Coordinates are parent-relative (the authoring convention).
|
|
277
|
+
*/
|
|
278
|
+
export interface ComponentPropertyPatchEntry {
|
|
279
|
+
type?: ComponentPropertyType;
|
|
280
|
+
defaultValue?: string | boolean;
|
|
281
|
+
options?: ComponentPropertyOptions;
|
|
282
|
+
}
|
|
283
|
+
/** variantAxes patch value: string[] replaces options (never renames); object form renames explicitly. */
|
|
284
|
+
export type VariantAxisPatchEntry = null | string[] | {
|
|
285
|
+
rename?: string;
|
|
286
|
+
options?: string[];
|
|
287
|
+
renameOptions?: Record<string, string>;
|
|
288
|
+
};
|
|
289
|
+
export interface PatchSetValues extends Omit<Partial<DesignProperties>, "position" | "size" | "styles" | "font" | "constraints" | "layout" | "bindings" | "styleRefs" | "variableModes" | "instanceProperties" | "componentPropertyReferences" | "componentProperties" | "variantAxes" | "variant"> {
|
|
290
|
+
name?: string;
|
|
291
|
+
position?: {
|
|
292
|
+
x?: number;
|
|
293
|
+
y?: number;
|
|
294
|
+
};
|
|
295
|
+
size?: {
|
|
296
|
+
width?: number;
|
|
297
|
+
height?: number;
|
|
298
|
+
};
|
|
299
|
+
styles?: {
|
|
300
|
+
fills?: DesignPaint[];
|
|
301
|
+
strokes?: DesignPaint[];
|
|
302
|
+
effects?: DesignEffect[];
|
|
303
|
+
};
|
|
304
|
+
font?: Partial<DesignFont>;
|
|
305
|
+
constraints?: Partial<Constraints>;
|
|
306
|
+
layout?: DesignLayout;
|
|
307
|
+
/** Shallow-merge; field `null` clears that entry; whole-key `null` clears the map. */
|
|
308
|
+
bindings?: Record<string, string | null> | null;
|
|
309
|
+
styleRefs?: Record<string, string | null> | null;
|
|
310
|
+
variableModes?: Record<string, string | null> | null;
|
|
311
|
+
instanceProperties?: Record<string, string | boolean | VariableAlias | null> | null;
|
|
312
|
+
componentPropertyReferences?: {
|
|
313
|
+
characters?: string | null;
|
|
314
|
+
visible?: string | null;
|
|
315
|
+
mainComponent?: string | null;
|
|
316
|
+
} | null;
|
|
317
|
+
/** Name-keyed upsert of COMPONENT property definitions; `null` deletes a TEXT/BOOLEAN/INSTANCE_SWAP def. */
|
|
318
|
+
componentProperties?: Record<string, ComponentPropertyPatchEntry | null> | null;
|
|
319
|
+
/** Shallow-merge axes; array replaces options (never renames); object form `{ rename, options, renameOptions }` is explicit. Null axis deletes are rejected. */
|
|
320
|
+
variantAxes?: Record<string, VariantAxisPatchEntry> | null;
|
|
321
|
+
/** Merge variant selection on a COMPONENT inside a set. Whole-key or per-axis null is rejected. */
|
|
322
|
+
variant?: Record<string, string | null> | null;
|
|
323
|
+
}
|
|
265
324
|
export interface PatchOperation {
|
|
266
|
-
op: "SET" | "REMOVE" | "APPEND";
|
|
325
|
+
op: "SET" | "REMOVE" | "APPEND" | "INSERT" | "MOVE" | "DUPLICATE";
|
|
267
326
|
id?: string;
|
|
268
327
|
parent?: string;
|
|
328
|
+
index?: number;
|
|
329
|
+
/** Authored set object (keys from PATCH_SET_KEYS). */
|
|
269
330
|
set?: JsonObject;
|
|
270
|
-
normalized
|
|
331
|
+
/** Type-agnostic normalized set values; target-type rules run at apply time. */
|
|
332
|
+
normalized?: PatchSetValues;
|
|
271
333
|
node?: InternalNode;
|
|
334
|
+
/** Required for DUPLICATE: non-empty suffix appended to every subtree id (unless overridden). */
|
|
335
|
+
idSuffix?: string;
|
|
336
|
+
/** Optional DUPLICATE overrides: sourceId → newId (keys must be in the source subtree). */
|
|
337
|
+
ids?: Record<string, string>;
|
|
272
338
|
}
|
|
273
339
|
export interface InternalPatchDocument {
|
|
274
340
|
patch: {
|
package/dist/validate.d.ts
CHANGED
|
@@ -1,2 +1,16 @@
|
|
|
1
1
|
import type { InternalDocument } from "./types";
|
|
2
|
-
|
|
2
|
+
/** Validate a canonical document. Reports at most `limit` errors (default 30; pass Infinity for all). */
|
|
3
|
+
export declare function validateDocument(document: InternalDocument, limit?: number): string[];
|
|
4
|
+
/**
|
|
5
|
+
* A stable identity for a validateDocument issue that survives index shifts.
|
|
6
|
+
* Node issues are keyed on the owning node's id plus the property path inside
|
|
7
|
+
* that node (e.g. `node:card .bindings.fill`); variable issues on collection
|
|
8
|
+
* and variable names; anything else on its path. Array indexes in node paths
|
|
9
|
+
* (nodes[i].children[j]) never appear in the key, so an insert, move or remove
|
|
10
|
+
* elsewhere does not make an old issue look new.
|
|
11
|
+
*/
|
|
12
|
+
export declare function documentIssueOwners(document: InternalDocument): (path: string) => {
|
|
13
|
+
owner: string;
|
|
14
|
+
nodeId?: string;
|
|
15
|
+
rest: string;
|
|
16
|
+
};
|