From e8b19744382e8254e9362f8dc93cecb3d296b38a Mon Sep 17 00:00:00 2001 From: Caio Pizzol Date: Mon, 9 Mar 2026 10:04:34 -0300 Subject: [PATCH 1/5] fix(document-api): return NodeAddress from find and getNode instead of SDAddress MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit SD-2168: find and getNode now return NodeAddress directly, making their results compatible with mutation targets like create.paragraph. Removes the toSDAddress conversion layer that stripped nodeType and changed kind from 'block' to 'content', which made find results unusable for positional inserts. Also adds docs for the query.match → create.paragraph workflow. --- apps/docs/document-api/common-workflows.mdx | 36 ++++++++++++ .../src/overview-examples.test.ts | 47 +++++++++++++++ .../document-api/src/types/sd-envelope.ts | 12 +++- .../src/document-api-adapters/find-adapter.ts | 58 +++++++------------ .../get-node-adapter.test.ts | 2 +- .../document-api-adapters/get-node-adapter.ts | 35 +++++------ 6 files changed, 132 insertions(+), 58 deletions(-) diff --git a/apps/docs/document-api/common-workflows.mdx b/apps/docs/document-api/common-workflows.mdx index b18ca85078..4282cd10fe 100644 --- a/apps/docs/document-api/common-workflows.mdx +++ b/apps/docs/document-api/common-workflows.mdx @@ -105,6 +105,42 @@ if (firstBlock) { } ``` +## Find text and insert at position + +Search for a heading (or any text) and insert a new paragraph relative to it: + +```ts +// 1. Find the heading by text content +const match = editor.doc.query.match({ + select: { type: 'text', pattern: 'Materials and methods' }, + require: 'first', +}); + +const address = match.items?.[0]?.address; +if (!address) return; + +// 2. Insert a paragraph after the heading +editor.doc.create.paragraph({ + at: { kind: 'after', target: address }, + text: 'New section content goes here.', +}); +``` + +The `address` from `query.match` is a `BlockNodeAddress` that works directly with `create.paragraph`, `create.heading`, and `create.table`. Use `kind: 'before'` to insert before the matched node instead. + +To insert as a tracked change, pass `changeMode: 'tracked'`: + +```ts +editor.doc.create.paragraph( + { at: { kind: 'after', target: address }, text: 'Suggested addition.' }, + { changeMode: 'tracked' }, +); +``` + + +Use `query.match` (not `find`) for this workflow. `query.match` returns `BlockNodeAddress` objects that are directly compatible with mutation targets. + + ## Tracked-mode insert Insert text as a tracked change so reviewers can accept or reject it: diff --git a/packages/document-api/src/overview-examples.test.ts b/packages/document-api/src/overview-examples.test.ts index da90dd6f09..515fd91c02 100644 --- a/packages/document-api/src/overview-examples.test.ts +++ b/packages/document-api/src/overview-examples.test.ts @@ -552,6 +552,53 @@ describe('overview.mdx examples', () => { }); }); +// --------------------------------------------------------------------------- +// common-workflows.mdx — "Find text and insert at position" +// --------------------------------------------------------------------------- + +describe('common-workflows.mdx: Find text and insert at position', () => { + it('query.match → create.paragraph with at: after', () => { + const doc = makeApi(); + + // Step 1: Find the heading by text content + const match = doc.query.match({ + select: { type: 'text', pattern: 'Materials and methods' }, + require: 'first', + }); + + const address = match.items?.[0]?.address; + if (!address) return; + + // Step 2: Insert a paragraph after the heading + const result = doc.create.paragraph({ + at: { kind: 'after', target: address }, + text: 'New section content goes here.', + }); + + expect(address.kind).toBe('block'); + expect(result.success).toBe(true); + }); + + it('query.match → create.paragraph with tracked changes', () => { + const doc = makeApi(); + + const match = doc.query.match({ + select: { type: 'text', pattern: 'Materials and methods' }, + require: 'first', + }); + + const address = match.items?.[0]?.address; + if (!address) return; + + const result = doc.create.paragraph( + { at: { kind: 'after', target: address }, text: 'Suggested addition.' }, + { changeMode: 'tracked' }, + ); + + expect(result.success).toBe(true); + }); +}); + // --------------------------------------------------------------------------- // src/README.md — "Workflow:" examples // --------------------------------------------------------------------------- diff --git a/packages/document-api/src/types/sd-envelope.ts b/packages/document-api/src/types/sd-envelope.ts index 5148b897ec..6632673d65 100644 --- a/packages/document-api/src/types/sd-envelope.ts +++ b/packages/document-api/src/types/sd-envelope.ts @@ -8,6 +8,7 @@ * SDReadOptions — projection options for reads */ +import type { NodeAddress } from './base.js'; import type { SDContentNode, SDInlineNode } from './sd-nodes.js'; // --------------------------------------------------------------------------- @@ -20,6 +21,13 @@ export interface SDPoint { offset: number; } +/** + * Legacy SDM/1 address type. + * + * @deprecated Prefer `NodeAddress` from `./base.js`. `find` results now return + * `NodeAddress` directly. This type is retained for backward-compatible inputs + * (`within`, `getNode`). + */ export interface SDAddress { kind: 'content' | 'inline' | 'annotation' | 'section'; stability: 'stable' | 'ephemeral'; @@ -83,7 +91,7 @@ export type SDSelector = SDTextSelector | SDNodeSelector; export interface SDFindInput { select: SDSelector; - within?: SDAddress; + within?: SDAddress | NodeAddress; limit?: number; offset?: number; options?: SDReadOptions; @@ -95,7 +103,7 @@ export interface SDFindInput { export interface SDNodeResult { node: SDContentNode | SDInlineNode; - address: SDAddress; + address: NodeAddress; context?: SDNodeContext; } diff --git a/packages/super-editor/src/document-api-adapters/find-adapter.ts b/packages/super-editor/src/document-api-adapters/find-adapter.ts index 30e4bf6887..28b601b193 100644 --- a/packages/super-editor/src/document-api-adapters/find-adapter.ts +++ b/packages/super-editor/src/document-api-adapters/find-adapter.ts @@ -5,7 +5,6 @@ import type { SDFindInput, SDFindResult, SDNodeResult, - SDAddress, NodeAddress, NodeType, UnknownNodeDiagnostic, @@ -153,21 +152,27 @@ function translateToInternalQuery(input: SDFindInput): Query { } /** - * Validates an SDAddress for use as a within scope. + * Validates an address for use as a within scope. * - * Only content-kind addresses with a `nodeId` are supported for scoping. + * Accepts both NodeAddress (`kind: 'block'`) and legacy SDAddress (`kind: 'content'`). + * Only block/content-kind addresses with a `nodeId` are supported for scoping. * The actual nodeType resolution is deferred to {@link resolveWithinNodeType} * which requires the block index. */ -function validateWithinAddress(sdAddress: SDFindInput['within'] & object): { nodeId: string } { - if (sdAddress.kind === 'content' && sdAddress.nodeId) { - return { nodeId: sdAddress.nodeId }; +function validateWithinAddress(address: SDFindInput['within'] & object): { nodeId: string } { + // Accept NodeAddress (kind: 'block') and legacy SDAddress (kind: 'content') + if ( + (address.kind === 'block' || address.kind === 'content') && + 'nodeId' in address && + typeof address.nodeId === 'string' + ) { + return { nodeId: address.nodeId }; } throw new DocumentApiAdapterError( 'INVALID_TARGET', - `"within" scope requires a content-kind SDAddress with a nodeId. Got kind="${sdAddress.kind}".`, - { field: 'within', value: sdAddress }, + `"within" scope requires a block address with a nodeId. Got kind="${address.kind}".`, + { field: 'within', value: address }, ); } @@ -187,31 +192,12 @@ function resolveWithinNodeType(index: ReturnType, nodeId: } as NodeAddress; } -/** - * Builds an SDAddress from an internal NodeAddress match result. - */ -function toSDAddress(address: NodeAddress): SDAddress { - if (address.kind === 'block') { - return { - kind: 'content', - stability: 'stable', - nodeId: address.nodeId, - }; - } - return { - kind: 'inline', - stability: 'ephemeral', - anchor: { - start: { blockId: address.anchor.start.blockId, offset: address.anchor.start.offset }, - end: { blockId: address.anchor.end.blockId, offset: address.anchor.end.offset }, - }, - }; -} - /** * Projects a matched address into an SDNodeResult by looking up the PM node * in the block index (for blocks) or inline index (for inlines) and projecting * it to an SDM/1 node. + * + * Returns NodeAddress directly — no SDAddress conversion. */ function projectMatchToSDNodeResult( editor: Editor, @@ -227,12 +213,12 @@ function projectMatchToSDNodeResult( if (!found) return null; return { node: projectContentNode(found.node), - address: toSDAddress(address), + address, }; } return { node: projectContentNode(candidate.node), - address: toSDAddress(address), + address, }; } @@ -246,13 +232,13 @@ function projectMatchToSDNodeResult( if (inlineCandidate.node) { return { node: projectInlineNode(inlineCandidate.node), - address: toSDAddress(address), + address, }; } // Mark-based inlines (hyperlink, comment) have mark/attrs but no node. const markProjected = projectMarkBasedInline(editor, inlineCandidate); if (markProjected) { - return { node: markProjected, address: toSDAddress(address) }; + return { node: markProjected, address }; } } @@ -260,7 +246,7 @@ function projectMatchToSDNodeResult( const resolvedText = resolveTextByBlockId(editor, address.anchor); return { node: { kind: 'run', run: { text: resolvedText } }, - address: toSDAddress(address), + address, }; } @@ -282,8 +268,8 @@ export function sdFindAdapter(editor: Editor, input: SDFindInput): SDFindResult const query = translateToInternalQuery(input); const index = getBlockIndex(editor); - // Resolve within scope after index is built (SDAddress doesn't carry nodeType, - // so we need the index to look up the actual PM node type for the nodeId). + // Resolve within scope after index is built (legacy SDAddress doesn't carry + // nodeType, so we need the index to look up the actual PM node type). if (input.within) { const { nodeId } = validateWithinAddress(input.within); query.within = resolveWithinNodeType(index, nodeId); diff --git a/packages/super-editor/src/document-api-adapters/get-node-adapter.test.ts b/packages/super-editor/src/document-api-adapters/get-node-adapter.test.ts index 27c6b9be80..f5ff1e16b2 100644 --- a/packages/super-editor/src/document-api-adapters/get-node-adapter.test.ts +++ b/packages/super-editor/src/document-api-adapters/get-node-adapter.test.ts @@ -204,7 +204,7 @@ describe('getNodeByIdAdapter', () => { const result = getNodeByIdAdapter(editor, { nodeId: 'p1' }); expect(result.node.kind).toBe('paragraph'); - expect(result.address.kind).toBe('content'); + expect(result.address.kind).toBe('block'); }); it('resolves a block node by id with nodeType', () => { diff --git a/packages/super-editor/src/document-api-adapters/get-node-adapter.ts b/packages/super-editor/src/document-api-adapters/get-node-adapter.ts index ecf6f457cc..9be6d56045 100644 --- a/packages/super-editor/src/document-api-adapters/get-node-adapter.ts +++ b/packages/super-editor/src/document-api-adapters/get-node-adapter.ts @@ -1,5 +1,5 @@ import type { Editor } from '../core/Editor.js'; -import type { BlockNodeType, GetNodeByIdInput, NodeAddress, SDNodeResult, SDAddress } from '@superdoc/document-api'; +import type { BlockNodeType, GetNodeByIdInput, NodeAddress, SDNodeResult } from '@superdoc/document-api'; import type { BlockCandidate, BlockIndex } from './helpers/node-address-resolver.js'; import { getBlockIndex, getInlineIndex } from './helpers/index-cache.js'; import { findInlineByAnchor } from './helpers/inline-address-resolver.js'; @@ -16,23 +16,20 @@ function findBlocksByTypeAndId(blockIndex: BlockIndex, nodeType: BlockNodeType, return blockIndex.candidates.filter((candidate) => candidate.nodeType === nodeType && candidate.nodeId === nodeId); } -function buildBlockAddress(nodeId: string): SDAddress { - return { - kind: 'content', - stability: 'stable', - nodeId, - }; +/** + * Returns the input block address as-is (it's already a NodeAddress). + * Previously converted to SDAddress; now passes through directly. + */ +function buildBlockAddress(address: NodeAddress & { kind: 'block' }): NodeAddress { + return address; } -function buildInlineAddress(address: NodeAddress & { kind: 'inline' }): SDAddress { - return { - kind: 'inline', - stability: 'ephemeral', - anchor: { - start: { blockId: address.anchor.start.blockId, offset: address.anchor.start.offset }, - end: { blockId: address.anchor.end.blockId, offset: address.anchor.end.offset }, - }, - }; +/** + * Returns the input inline address as-is (it's already a NodeAddress). + * Previously converted to SDAddress; now passes through directly. + */ +function buildInlineAddress(address: NodeAddress & { kind: 'inline' }): NodeAddress { + return address; } /** @@ -60,7 +57,7 @@ export function getNodeAdapter(editor: Editor, address: NodeAddress): SDNodeResu const candidate = matches[0]!; return { node: projectContentNode(candidate.node), - address: buildBlockAddress(address.nodeId), + address: buildBlockAddress(address), }; } @@ -137,9 +134,9 @@ function resolveBlockById( */ export function getNodeByIdAdapter(editor: Editor, input: GetNodeByIdInput): SDNodeResult { const { nodeId, nodeType } = input; - const { candidate } = resolveBlockById(editor, nodeId, nodeType); + const { candidate, resolvedType } = resolveBlockById(editor, nodeId, nodeType); return { node: projectContentNode(candidate.node), - address: buildBlockAddress(nodeId), + address: { kind: 'block', nodeType: resolvedType, nodeId } as NodeAddress, }; } From 2a39db2c2b1fb6a6628e070c2cbc2ac3770c13a1 Mon Sep 17 00:00:00 2001 From: Nick Bernal Date: Mon, 16 Mar 2026 14:01:14 -0700 Subject: [PATCH 2/5] feat(document-api): adopt SDM/1 addressing model for find, insert, and replace --- apps/cli/src/__tests__/cli.test.ts | 103 +- apps/cli/src/__tests__/host.test.ts | 14 +- apps/cli/src/__tests__/lib/validate.test.ts | 6 +- apps/cli/src/lib/find-query.ts | 4 +- apps/cli/src/lib/validate.ts | 26 +- .../document-api/available-operations.mdx | 4 +- apps/docs/document-api/overview.mdx | 2 +- .../reference/_generated-manifest.json | 6 +- .../reference/blocks/delete-range.mdx | 290 +++++ .../document-api/reference/blocks/delete.mdx | 65 +- .../document-api/reference/blocks/index.mdx | 2 + .../document-api/reference/blocks/list.mdx | 183 +++ .../reference/capabilities/get.mdx | 98 ++ .../reference/create/paragraph.mdx | 4 +- apps/docs/document-api/reference/delete.mdx | 40 +- apps/docs/document-api/reference/find.mdx | 211 +--- .../document-api/reference/format/apply.mdx | 892 +++++++++++++- .../document-api/reference/format/b-cs.mdx | 47 +- .../document-api/reference/format/bold.mdx | 47 +- .../document-api/reference/format/border.mdx | 92 +- .../document-api/reference/format/caps.mdx | 47 +- .../reference/format/char-scale.mdx | 46 +- .../document-api/reference/format/color.mdx | 47 +- .../format/contextual-alternates.mdx | 47 +- .../docs/document-api/reference/format/cs.mdx | 47 +- .../document-api/reference/format/dstrike.mdx | 47 +- .../reference/format/east-asian-layout.mdx | 102 +- .../docs/document-api/reference/format/em.mdx | 47 +- .../document-api/reference/format/emboss.mdx | 47 +- .../reference/format/fit-text.mdx | 71 +- .../reference/format/font-family.mdx | 47 +- .../reference/format/font-size-cs.mdx | 46 +- .../reference/format/font-size.mdx | 46 +- .../reference/format/highlight.mdx | 47 +- .../document-api/reference/format/i-cs.mdx | 47 +- .../document-api/reference/format/imprint.mdx | 47 +- .../document-api/reference/format/italic.mdx | 47 +- .../document-api/reference/format/kerning.mdx | 46 +- .../document-api/reference/format/lang.mdx | 83 +- .../reference/format/letter-spacing.mdx | 46 +- .../reference/format/ligatures.mdx | 47 +- .../reference/format/num-form.mdx | 47 +- .../reference/format/num-spacing.mdx | 47 +- .../document-api/reference/format/o-math.mdx | 47 +- .../document-api/reference/format/outline.mdx | 47 +- .../reference/format/position.mdx | 46 +- .../document-api/reference/format/r-fonts.mdx | 149 ++- .../document-api/reference/format/r-style.mdx | 47 +- .../document-api/reference/format/rtl.mdx | 47 +- .../document-api/reference/format/shading.mdx | 83 +- .../document-api/reference/format/shadow.mdx | 47 +- .../reference/format/small-caps.mdx | 47 +- .../reference/format/snap-to-grid.mdx | 47 +- .../reference/format/spec-vanish.mdx | 47 +- .../document-api/reference/format/strike.mdx | 47 +- .../reference/format/stylistic-sets.mdx | 62 +- .../reference/format/underline.mdx | 87 +- .../document-api/reference/format/vanish.mdx | 47 +- .../reference/format/vert-align.mdx | 50 +- .../reference/format/web-hidden.mdx | 47 +- .../document-api/reference/get-node-by-id.mdx | 108 +- apps/docs/document-api/reference/get-node.mdx | 108 +- .../document-api/reference/history/redo.mdx | 2 +- .../document-api/reference/history/undo.mdx | 2 +- .../reference/hyperlinks/list.mdx | 7 +- apps/docs/document-api/reference/index.mdx | 18 +- apps/docs/document-api/reference/insert.mdx | 772 +----------- .../document-api/reference/lists/insert.mdx | 4 +- .../reference/mutations/apply.mdx | 16 +- .../reference/mutations/preview.mdx | 16 +- .../document-api/reference/query/match.mdx | 13 +- apps/docs/document-api/reference/replace.mdx | 1033 ++--------------- apps/docs/document-engine/sdks.mdx | 34 +- .../scripts/lib/contract-output-artifacts.ts | 2 +- packages/document-api/src/README.md | 4 +- .../src/contract/operation-definitions.ts | 13 +- packages/document-api/src/contract/schemas.ts | 45 +- packages/document-api/src/find/find.test.ts | 2 +- packages/document-api/src/find/find.ts | 26 +- .../src/hyperlinks/hyperlinks.types.ts | 4 +- packages/document-api/src/index.test.ts | 17 +- packages/document-api/src/index.ts | 23 +- packages/document-api/src/insert/insert.ts | 7 +- .../src/overview-examples.test.ts | 29 +- packages/document-api/src/receipt-bridge.ts | 104 +- packages/document-api/src/replace/replace.ts | 16 +- packages/document-api/src/types/discovery.ts | 4 +- packages/document-api/src/types/fragment.ts | 2 +- .../src/types/mutation-plan.types.ts | 10 +- .../src/types/query-match.types.ts | 8 +- packages/document-api/src/types/query.ts | 4 +- .../document-api/src/types/sd-contract.ts | 21 +- .../document-api/src/types/sd-envelope.ts | 48 +- .../src/types/structural-input.ts | 24 +- .../document-api/src/validation-primitives.ts | 21 +- .../src/core/Editor.lifecycle.test.ts | 2 +- .../citations-export.integration.test.ts | 18 +- .../find-adapter.test.ts | 10 +- .../src/document-api-adapters/find-adapter.ts | 115 +- .../document-api-adapters/get-node-adapter.ts | 10 +- .../helpers/adapter-utils.ts | 41 +- .../helpers/sd-projection.test.ts | 2 +- .../plan-engine/compiler.ts | 6 +- .../plan-engine/plan-wrappers.ts | 161 ++- .../plan-engine/query-match-adapter.ts | 3 +- .../structural-write-engine/index.ts | 8 +- .../structural-write-engine.test.ts | 44 +- .../target-resolver.ts | 65 +- tests/behavior/fixtures/superdoc.ts | 15 +- tests/behavior/helpers/table.ts | 8 +- 110 files changed, 4454 insertions(+), 2942 deletions(-) create mode 100644 apps/docs/document-api/reference/blocks/delete-range.mdx create mode 100644 apps/docs/document-api/reference/blocks/list.mdx diff --git a/apps/cli/src/__tests__/cli.test.ts b/apps/cli/src/__tests__/cli.test.ts index 1910baa92c..82632ac5f2 100644 --- a/apps/cli/src/__tests__/cli.test.ts +++ b/apps/cli/src/__tests__/cli.test.ts @@ -42,6 +42,15 @@ type ErrorEnvelope = { }; }; +type MutationReceiptEnvelope = SuccessEnvelope<{ + receipt: { + success: boolean; + resolution?: { + target: TextRange; + }; + }; +}>; + const TEST_DIR = join(import.meta.dir, 'fixtures-cli'); const STATE_DIR = join(TEST_DIR, 'state'); const SAMPLE_DOC = join(TEST_DIR, 'sample.docx'); @@ -103,8 +112,8 @@ function hasPrettyProperties(node: unknown): boolean { } async function firstTextRange(args: string[]): Promise { - // SDM/1: find returns SDNodeResult with SDAddress. For text searches, - // the address is content-level (the containing block). We extract the + // SDM/1: find returns SDNodeResult with NodeAddress. For text searches, + // the address is block-level (the containing block). We extract the // blockId and find the pattern position within the node's text content. const result = await runCli(args); expect(result.code).toBe(0); @@ -665,7 +674,7 @@ describe('superdoc CLI', () => { expect(envelope.error.message).toContain('query.include'); }); - test('find text queries return content addresses with node projections', async () => { + test('find text queries return block addresses with node projections', async () => { const result = await runCli([ 'find', SAMPLE_DOC, @@ -682,7 +691,7 @@ describe('superdoc CLI', () => { result: { items?: Array<{ node?: { kind?: string }; - address?: { kind?: string; nodeId?: string }; + address?: { kind?: string; nodeType?: string; nodeId?: string }; }>; }; }> @@ -690,7 +699,8 @@ describe('superdoc CLI', () => { const firstItem = envelope.data.result.items?.[0]; expect(firstItem).toBeDefined(); - expect(firstItem?.address?.kind).toBe('content'); + expect(firstItem?.address?.kind).toBe('block'); + expect(firstItem?.address?.nodeType).toBeDefined(); expect(firstItem?.address?.nodeId).toBeDefined(); expect(firstItem?.node?.kind).toBeDefined(); }); @@ -710,8 +720,7 @@ describe('superdoc CLI', () => { const address = findEnvelope.data.result.items[0]?.address; expect(address).toBeDefined(); - // SDM/1 addresses use kind: 'content' for block-level nodes - // getNode still accepts the old NodeAddress format, so we construct one + // find returns NodeAddress with kind: 'block' for block-level nodes const nodeId = address?.nodeId as string; expect(nodeId).toBeDefined(); @@ -776,13 +785,13 @@ describe('superdoc CLI', () => { const findEnvelope = parseJsonOutput< SuccessEnvelope<{ result: { - items: Array<{ node: { kind: string }; address: { kind: string; nodeId: string } }>; + items: Array<{ node: { kind: string }; address: { kind: string; nodeType: string; nodeId: string } }>; }; }> >(findResult); const firstItem = findEnvelope.data.result.items[0]; - expect(firstItem.address.kind).toBe('content'); + expect(firstItem.address.kind).toBe('block'); const getByIdResult = await runCli([ 'get-node-by-id', @@ -806,13 +815,13 @@ describe('superdoc CLI', () => { const findEnvelope = parseJsonOutput< SuccessEnvelope<{ result: { - items: Array<{ node: { kind: string }; address: { kind: string; nodeId: string } }>; + items: Array<{ node: { kind: string }; address: { kind: string; nodeType: string; nodeId: string } }>; }; }> >(findResult); const firstItem = findEnvelope.data.result.items[0]; - expect(firstItem.address.kind).toBe('content'); + expect(firstItem.address.kind).toBe('block'); const prettyResult = await runCli([ 'get-node-by-id', @@ -947,19 +956,13 @@ describe('superdoc CLI', () => { expect(insertResult.code).toBe(0); - const insertEnvelope = parseJsonOutput< - SuccessEnvelope<{ - receipt: { - success: boolean; - resolution?: { - target: { anchor?: { start: { offset: number }; end: { offset: number } } }; - }; - }; - }> - >(insertResult); + const insertEnvelope = parseJsonOutput(insertResult); expect(insertEnvelope.data.receipt.success).toBe(true); - expect(insertEnvelope.data.receipt.resolution?.target.anchor?.start.offset).toBe(0); - expect(insertEnvelope.data.receipt.resolution?.target.anchor?.end.offset).toBe(0); + const target = insertEnvelope.data.receipt.resolution?.target; + expect(target?.kind).toBe('text'); + expect(target?.blockId).toBeDefined(); + expect(target?.range.start).toBe(0); + expect(target?.range.end).toBe(0); const verifyResult = await runCli([ 'find', @@ -1002,21 +1005,14 @@ describe('superdoc CLI', () => { ]); expect(insertResult.code).toBe(0); - const insertEnvelope = parseJsonOutput< - SuccessEnvelope<{ - receipt: { - success: boolean; - resolution?: { - target: { anchor?: { start: { offset: number }; end: { offset: number } } }; - }; - }; - }> - >(insertResult); + const insertEnvelope = parseJsonOutput(insertResult); expect(insertEnvelope.data.receipt.success).toBe(true); - const anchor = insertEnvelope.data.receipt.resolution?.target.anchor; - expect(anchor?.start.offset).toBe(0); - expect(anchor?.end.offset).toBe(0); + const target = insertEnvelope.data.receipt.resolution?.target; + expect(target?.kind).toBe('text'); + expect(target?.blockId).toBeDefined(); + expect(target?.range.start).toBe(0); + expect(target?.range.end).toBe(0); const verifyResult = await runCli([ 'find', @@ -1087,20 +1083,13 @@ describe('superdoc CLI', () => { expect(insertResult.code).toBe(0); - const insertEnvelope = parseJsonOutput< - SuccessEnvelope<{ - receipt: { - success: boolean; - resolution?: { - target: { anchor?: { start: { offset: number }; end: { offset: number } } }; - }; - }; - }> - >(insertResult); + const insertEnvelope = parseJsonOutput(insertResult); // blockId alone → offset defaults to 0 → collapsed range at start expect(insertEnvelope.data.receipt.success).toBe(true); - expect(insertEnvelope.data.receipt.resolution?.target.anchor?.start.offset).toBe(0); - expect(insertEnvelope.data.receipt.resolution?.target.anchor?.end.offset).toBe(0); + const resolvedTarget = insertEnvelope.data.receipt.resolution?.target; + expect(resolvedTarget?.kind).toBe('text'); + expect(resolvedTarget?.range.start).toBe(0); + expect(resolvedTarget?.range.end).toBe(0); }); test('insert with --offset but no --block-id returns INVALID_ARGUMENT', async () => { @@ -1793,19 +1782,13 @@ describe('superdoc CLI', () => { const insertResult = await runCli(['insert', '--value', 'STATEFUL_DEFAULT_INSERT_1597']); expect(insertResult.code).toBe(0); - const insertEnvelope = parseJsonOutput< - SuccessEnvelope<{ - receipt: { - success: boolean; - resolution?: { - target: { anchor?: { start: { offset: number }; end: { offset: number } } }; - }; - }; - }> - >(insertResult); + const insertEnvelope = parseJsonOutput(insertResult); expect(insertEnvelope.data.receipt.success).toBe(true); - expect(insertEnvelope.data.receipt.resolution?.target.anchor?.start.offset).toBe(0); - expect(insertEnvelope.data.receipt.resolution?.target.anchor?.end.offset).toBe(0); + const target = insertEnvelope.data.receipt.resolution?.target; + expect(target?.kind).toBe('text'); + expect(target?.blockId).toBeDefined(); + expect(target?.range.start).toBe(0); + expect(target?.range.end).toBe(0); const verifyResult = await runCli(['find', '--type', 'text', '--pattern', 'STATEFUL_DEFAULT_INSERT_1597']); expect(verifyResult.code).toBe(0); diff --git a/apps/cli/src/__tests__/host.test.ts b/apps/cli/src/__tests__/host.test.ts index 69783ef8b3..0cdc58f9dd 100644 --- a/apps/cli/src/__tests__/host.test.ts +++ b/apps/cli/src/__tests__/host.test.ts @@ -294,18 +294,18 @@ describe('CLI host mode', () => { }>; }; const firstItem = findResult.items?.[0]; - const sdAddress = firstItem?.address; + const address = firstItem?.address; const nodeKind = firstItem?.node?.kind ?? 'paragraph'; - expect(sdAddress?.nodeId).toBeDefined(); + expect(address?.nodeId).toBeDefined(); - // Build a legacy NodeAddress for getNode which expects { kind: 'block', nodeType, nodeId } - const legacyAddress = { kind: 'block', nodeType: nodeKind, nodeId: sdAddress!.nodeId }; - await invokeAndValidate('doc.getNode', ['get-node', docPath, '--address-json', JSON.stringify(legacyAddress)]); + // Build a NodeAddress for getNode which expects { kind: 'block', nodeType, nodeId } + const blockAddress = { kind: 'block', nodeType: nodeKind, nodeId: address!.nodeId }; + await invokeAndValidate('doc.getNode', ['get-node', docPath, '--address-json', JSON.stringify(blockAddress)]); - // Build a collapsed text target from the SDM/1 address + // Build a collapsed text target from the block address const collapsedTarget = { kind: 'text', - blockId: sdAddress!.nodeId, + blockId: address!.nodeId, range: { start: 0, end: 0 }, }; await invokeAndValidate('doc.insert', [ diff --git a/apps/cli/src/__tests__/lib/validate.test.ts b/apps/cli/src/__tests__/lib/validate.test.ts index 9410687968..9aa7144651 100644 --- a/apps/cli/src/__tests__/lib/validate.test.ts +++ b/apps/cli/src/__tests__/lib/validate.test.ts @@ -193,7 +193,7 @@ describe('validateQuery', () => { select: { type: 'paragraph' }, }); expect(result.select.type).toBe('node'); - expect((result.select as { nodeKind?: string }).nodeKind).toBe('paragraph'); + expect((result.select as { nodeType?: string }).nodeType).toBe('paragraph'); }); test('validates with limit and offset', () => { @@ -206,11 +206,11 @@ describe('validateQuery', () => { expect(result.offset).toBe(5); }); - test('validates nodeKind via legacy nodeType key', () => { + test('validates nodeType on node selector', () => { const result = validateQuery({ select: { type: 'node', nodeType: 'paragraph' }, }); - expect((result.select as { nodeKind?: string }).nodeKind).toBe('paragraph'); + expect((result.select as { nodeType?: string }).nodeType).toBe('paragraph'); }); test('rejects non-object input', () => { diff --git a/apps/cli/src/lib/find-query.ts b/apps/cli/src/lib/find-query.ts index 3a8e3725d0..80a9d570b6 100644 --- a/apps/cli/src/lib/find-query.ts +++ b/apps/cli/src/lib/find-query.ts @@ -35,7 +35,7 @@ function buildFlatFindQueryDraft(parsed: ParsedArgs): unknown { return { select: { type: 'node', - nodeKind: getStringOption(parsed, 'node-type'), + nodeType: getStringOption(parsed, 'node-type'), kind: getStringOption(parsed, 'kind'), }, limit: getNumberOption(parsed, 'limit'), @@ -47,7 +47,7 @@ function buildFlatFindQueryDraft(parsed: ParsedArgs): unknown { const select = kind ? { type: 'node', - nodeKind: selectorType, + nodeType: selectorType, kind, } : { diff --git a/apps/cli/src/lib/validate.ts b/apps/cli/src/lib/validate.ts index e9be728705..6388402026 100644 --- a/apps/cli/src/lib/validate.ts +++ b/apps/cli/src/lib/validate.ts @@ -321,19 +321,17 @@ function validateQuerySelect(value: unknown, path: string): Query['select'] { } if (type === 'node') { - expectOnlyKeys(obj, ['type', 'nodeKind', 'kind', 'nodeType'], path); - // Accept both SDM/1 nodeKind and legacy nodeType - const rawNodeKind = obj.nodeKind ?? obj.nodeType; - const nodeKind = rawNodeKind != null ? String(rawNodeKind) : undefined; + expectOnlyKeys(obj, ['type', 'nodeType', 'kind'], path); + const nodeType = obj.nodeType != null ? String(obj.nodeType) : undefined; - if (obj.kind != null && obj.kind !== 'content' && obj.kind !== 'inline' && !NODE_KINDS.has(obj.kind as NodeKind)) { - throw new CliError('VALIDATION_ERROR', `${path}.kind must be "content", "inline", "block", or "inline".`); + if (obj.kind != null && !NODE_KINDS.has(obj.kind as NodeKind)) { + throw new CliError('VALIDATION_ERROR', `${path}.kind must be "block" or "inline".`); } return { type: 'node', - nodeKind, - kind: obj.kind as string | undefined, + nodeType: nodeType as NodeType | undefined, + kind: obj.kind as NodeKind | undefined, }; } @@ -345,7 +343,7 @@ function validateQuerySelect(value: unknown, path: string): Query['select'] { return { type: 'node', - nodeKind: type as string, + nodeType: type as NodeType, }; } @@ -358,13 +356,11 @@ export function validateQuery(value: unknown, path = 'query'): Query { }; if (obj.within != null) { - // Accept SDAddress format for within scope - const within = expectRecord(obj.within, `${path}.within`); - if (within.kind === 'content' && typeof within.nodeId === 'string') { - query.within = within as unknown as Query['within']; - } else { - query.within = validateNodeAddress(obj.within, `${path}.within`) as unknown as Query['within']; + const within = validateNodeAddress(obj.within, `${path}.within`); + if (within.kind !== 'block') { + throw new CliError('VALIDATION_ERROR', `${path}.within must be a BlockNodeAddress (kind: "block").`); } + query.within = within; } if (obj.limit != null) { diff --git a/apps/docs/document-api/available-operations.mdx b/apps/docs/document-api/available-operations.mdx index 71dd76fbda..a4a6c7ed16 100644 --- a/apps/docs/document-api/available-operations.mdx +++ b/apps/docs/document-api/available-operations.mdx @@ -14,7 +14,7 @@ Use the tables below to see what operations are available and where each one is | Namespace | Canonical ops | Aliases | Total surface | Reference | | --- | --- | --- | --- | --- | -| Blocks | 1 | 0 | 1 | [Reference](/document-api/reference/blocks/index) | +| Blocks | 3 | 0 | 3 | [Reference](/document-api/reference/blocks/index) | | Bookmarks | 5 | 0 | 5 | [Reference](/document-api/reference/bookmarks/index) | | Capabilities | 1 | 0 | 1 | [Reference](/document-api/reference/capabilities/index) | | Captions | 6 | 0 | 6 | [Reference](/document-api/reference/captions/index) | @@ -47,7 +47,9 @@ Use the tables below to see what operations are available and where each one is | Editor method | Operation | | --- | --- | +| editor.doc.blocks.list(...) | [`blocks.list`](/document-api/reference/blocks/list) | | editor.doc.blocks.delete(...) | [`blocks.delete`](/document-api/reference/blocks/delete) | +| editor.doc.blocks.deleteRange(...) | [`blocks.deleteRange`](/document-api/reference/blocks/delete-range) | | editor.doc.bookmarks.list(...) | [`bookmarks.list`](/document-api/reference/bookmarks/list) | | editor.doc.bookmarks.get(...) | [`bookmarks.get`](/document-api/reference/bookmarks/get) | | editor.doc.bookmarks.insert(...) | [`bookmarks.insert`](/document-api/reference/bookmarks/insert) | diff --git a/apps/docs/document-api/overview.mdx b/apps/docs/document-api/overview.mdx index df9cf12481..0e8f5df834 100644 --- a/apps/docs/document-api/overview.mdx +++ b/apps/docs/document-api/overview.mdx @@ -31,7 +31,7 @@ For mutation targeting and `getNode(...)`, use `NodeAddress`: } ``` -`find(...)` returns SDM/1 `SDAddress` values (for example `kind: "content"`). For text selectors, `query.match(...)` returns deterministic mutation-ready data: `item.target` as a canonical `SelectionTarget`, `item.handle.ref` as a reusable resolved handle, and `item.address` as the matching `NodeAddress`. +`find(...)` returns `NodeAddress` values (for example `kind: "block"`). For text selectors, `query.match(...)` returns deterministic mutation-ready data: `item.target` as a canonical `SelectionTarget`, `item.handle.ref` as a reusable resolved handle, and `item.address` as the matching `NodeAddress`. ## Mutation targeting diff --git a/apps/docs/document-api/reference/_generated-manifest.json b/apps/docs/document-api/reference/_generated-manifest.json index 7588eb7b15..31200dc8d9 100644 --- a/apps/docs/document-api/reference/_generated-manifest.json +++ b/apps/docs/document-api/reference/_generated-manifest.json @@ -13,8 +13,10 @@ "apps/docs/document-api/reference/authorities/list.mdx", "apps/docs/document-api/reference/authorities/rebuild.mdx", "apps/docs/document-api/reference/authorities/remove.mdx", + "apps/docs/document-api/reference/blocks/delete-range.mdx", "apps/docs/document-api/reference/blocks/delete.mdx", "apps/docs/document-api/reference/blocks/index.mdx", + "apps/docs/document-api/reference/blocks/list.mdx", "apps/docs/document-api/reference/bookmarks/get.mdx", "apps/docs/document-api/reference/bookmarks/index.mdx", "apps/docs/document-api/reference/bookmarks/insert.mdx", @@ -419,7 +421,7 @@ { "aliasMemberPaths": [], "key": "blocks", - "operationIds": ["blocks.delete"], + "operationIds": ["blocks.list", "blocks.delete", "blocks.deleteRange"], "pagePath": "apps/docs/document-api/reference/blocks/index.mdx", "title": "Blocks" }, @@ -949,5 +951,5 @@ } ], "marker": "{/* GENERATED FILE: DO NOT EDIT. Regenerate via `pnpm run docapi:sync`. */}", - "sourceHash": "08748422ca56636a690f6224f369929364172c120c1113343f06de4f1f4e1e14" + "sourceHash": "414b3ae9575b723c5618dbcaa69abb048c3378bd00f7157d74cd780804058d43" } diff --git a/apps/docs/document-api/reference/blocks/delete-range.mdx b/apps/docs/document-api/reference/blocks/delete-range.mdx new file mode 100644 index 0000000000..4a1684b675 --- /dev/null +++ b/apps/docs/document-api/reference/blocks/delete-range.mdx @@ -0,0 +1,290 @@ +--- +title: blocks.deleteRange +sidebarTitle: blocks.deleteRange +description: Delete a contiguous range of top-level blocks between two endpoints (inclusive). Both endpoints must be direct children of the document node. Supports dry-run preview. +--- + +{/* GENERATED FILE: DO NOT EDIT. Regenerate via `pnpm run docapi:sync`. */} + +> Alpha: Document API is currently alpha and subject to breaking changes. + +## Summary + +Delete a contiguous range of top-level blocks between two endpoints (inclusive). Both endpoints must be direct children of the document node. Supports dry-run preview. + +- Operation ID: `blocks.deleteRange` +- API member path: `editor.doc.blocks.deleteRange(...)` +- Mutates document: `yes` +- Idempotency: `conditional` +- Supports tracked mode: `no` +- Supports dry run: `yes` +- Deterministic target resolution: `yes` + +## Expected result + +Returns a BlocksDeleteRangeResult with deletedCount, deletedBlocks array (each with ordinal, nodeId, nodeType, textPreview), before/after revision, and dryRun flag. + +## Input fields + +| Field | Type | Required | Description | +| --- | --- | --- | --- | +| `end` | BlockNodeAddress | yes | BlockNodeAddress | +| `end.kind` | `"block"` | yes | Constant: `"block"` | +| `end.nodeId` | string | yes | | +| `end.nodeType` | enum | yes | `"paragraph"`, `"heading"`, `"listItem"`, `"table"`, `"tableRow"`, `"tableCell"`, `"tableOfContents"`, `"image"`, `"sdt"` | +| `start` | BlockNodeAddress | yes | BlockNodeAddress | +| `start.kind` | `"block"` | yes | Constant: `"block"` | +| `start.nodeId` | string | yes | | +| `start.nodeType` | enum | yes | `"paragraph"`, `"heading"`, `"listItem"`, `"table"`, `"tableRow"`, `"tableCell"`, `"tableOfContents"`, `"image"`, `"sdt"` | + +### Example request + +```json +{ + "end": { + "kind": "block", + "nodeId": "node-def456", + "nodeType": "paragraph" + }, + "start": { + "kind": "block", + "nodeId": "node-def456", + "nodeType": "paragraph" + } +} +``` + +## Output fields + +| Field | Type | Required | Description | +| --- | --- | --- | --- | +| `deletedBlocks` | object[] | yes | | +| `deletedCount` | number | yes | | +| `dryRun` | boolean | yes | | +| `revision` | object | yes | | +| `revision.after` | string | yes | | +| `revision.before` | string | yes | | +| `success` | `true` | yes | Constant: `true` | + +### Example response + +```json +{ + "deletedBlocks": [ + { + "nodeId": "node-def456", + "nodeType": "paragraph", + "ordinal": 1, + "textPreview": "example" + } + ], + "deletedCount": 12.5, + "dryRun": true, + "revision": { + "after": "example", + "before": "example" + }, + "success": true +} +``` + +## Pre-apply throws + +- `TARGET_NOT_FOUND` +- `AMBIGUOUS_TARGET` +- `INVALID_TARGET` +- `INVALID_INPUT` +- `CAPABILITY_UNAVAILABLE` +- `INTERNAL_ERROR` + +## Non-applied failure codes + +- None + +## Raw schemas + + +```json +{ + "additionalProperties": false, + "properties": { + "end": { + "$ref": "#/$defs/BlockNodeAddress" + }, + "start": { + "$ref": "#/$defs/BlockNodeAddress" + } + }, + "required": [ + "start", + "end" + ], + "type": "object" +} +``` + + + +```json +{ + "additionalProperties": false, + "properties": { + "deletedBlocks": { + "items": { + "additionalProperties": false, + "properties": { + "nodeId": { + "type": "string" + }, + "nodeType": { + "type": "string" + }, + "ordinal": { + "type": "number" + }, + "textPreview": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ] + } + }, + "required": [ + "ordinal", + "nodeId", + "nodeType", + "textPreview" + ], + "type": "object" + }, + "type": "array" + }, + "deletedCount": { + "type": "number" + }, + "dryRun": { + "type": "boolean" + }, + "revision": { + "additionalProperties": false, + "properties": { + "after": { + "type": "string" + }, + "before": { + "type": "string" + } + }, + "required": [ + "before", + "after" + ], + "type": "object" + }, + "success": { + "const": true + } + }, + "required": [ + "success", + "deletedCount", + "deletedBlocks", + "revision", + "dryRun" + ], + "type": "object" +} +``` + + + +```json +{ + "additionalProperties": false, + "properties": { + "deletedBlocks": { + "type": "array" + }, + "deletedCount": { + "type": "number" + }, + "dryRun": { + "type": "boolean" + }, + "revision": { + "additionalProperties": false, + "properties": { + "after": { + "type": "string" + }, + "before": { + "type": "string" + } + }, + "required": [ + "before", + "after" + ], + "type": "object" + }, + "success": { + "const": true + } + }, + "required": [ + "success", + "deletedCount", + "deletedBlocks", + "revision", + "dryRun" + ], + "type": "object" +} +``` + + + +```json +{ + "additionalProperties": false, + "properties": { + "failure": { + "additionalProperties": false, + "properties": { + "code": { + "enum": [ + "TARGET_NOT_FOUND", + "AMBIGUOUS_TARGET", + "INVALID_TARGET", + "INVALID_INPUT", + "CAPABILITY_UNAVAILABLE", + "INTERNAL_ERROR" + ] + }, + "details": {}, + "message": { + "type": "string" + } + }, + "required": [ + "code", + "message" + ], + "type": "object" + }, + "success": { + "const": false + } + }, + "required": [ + "success", + "failure" + ], + "type": "object" +} +``` + diff --git a/apps/docs/document-api/reference/blocks/delete.mdx b/apps/docs/document-api/reference/blocks/delete.mdx index 5352c5bb64..182ecb836b 100644 --- a/apps/docs/document-api/reference/blocks/delete.mdx +++ b/apps/docs/document-api/reference/blocks/delete.mdx @@ -1,7 +1,7 @@ --- title: blocks.delete sidebarTitle: blocks.delete -description: Delete an entire block node (paragraph, heading, list item, table, or sdt) deterministically by block address. +description: Delete an entire block node (paragraph, heading, list item, table, image, or sdt) deterministically. --- {/* GENERATED FILE: DO NOT EDIT. Regenerate via `pnpm run docapi:sync`. */} @@ -10,7 +10,7 @@ description: Delete an entire block node (paragraph, heading, list item, table, ## Summary -Delete an entire block node (paragraph, heading, list item, table, or sdt) deterministically by block address. +Delete an entire block node (paragraph, heading, list item, table, image, or sdt) deterministically. - Operation ID: `blocks.delete` - API member path: `editor.doc.blocks.delete(...)` @@ -22,7 +22,7 @@ Delete an entire block node (paragraph, heading, list item, table, or sdt) deter ## Expected result -Returns a BlocksDeleteResult receipt confirming the block was removed from the document. +Returns a BlocksDeleteResult receipt confirming the block was removed, including a deletedBlock summary with ordinal, nodeType, and textPreview. ## Input fields @@ -53,6 +53,11 @@ Returns a BlocksDeleteResult receipt confirming the block was removed from the d | `deleted.kind` | `"block"` | yes | Constant: `"block"` | | `deleted.nodeId` | string | yes | | | `deleted.nodeType` | enum | yes | `"paragraph"`, `"heading"`, `"listItem"`, `"table"`, `"sdt"` | +| `deletedBlock` | object | no | | +| `deletedBlock.nodeId` | string | no | | +| `deletedBlock.nodeType` | string | no | | +| `deletedBlock.ordinal` | number | no | | +| `deletedBlock.textPreview` | string \\| null | no | One of: string, null | | `success` | `true` | yes | Constant: `true` | ### Example response @@ -64,6 +69,10 @@ Returns a BlocksDeleteResult receipt confirming the block was removed from the d "nodeId": "node-def456", "nodeType": "paragraph" }, + "deletedBlock": { + "nodeId": "node-def456", + "ordinal": 1 + }, "success": true } ``` @@ -108,6 +117,31 @@ Returns a BlocksDeleteResult receipt confirming the block was removed from the d "deleted": { "$ref": "#/$defs/DeletableBlockNodeAddress" }, + "deletedBlock": { + "additionalProperties": false, + "properties": { + "nodeId": { + "type": "string" + }, + "nodeType": { + "type": "string" + }, + "ordinal": { + "type": "number" + }, + "textPreview": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ] + } + }, + "type": "object" + }, "success": { "const": true } @@ -129,6 +163,31 @@ Returns a BlocksDeleteResult receipt confirming the block was removed from the d "deleted": { "$ref": "#/$defs/DeletableBlockNodeAddress" }, + "deletedBlock": { + "additionalProperties": false, + "properties": { + "nodeId": { + "type": "string" + }, + "nodeType": { + "type": "string" + }, + "ordinal": { + "type": "number" + }, + "textPreview": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ] + } + }, + "type": "object" + }, "success": { "const": true } diff --git a/apps/docs/document-api/reference/blocks/index.mdx b/apps/docs/document-api/reference/blocks/index.mdx index b1a0a46b1f..d0c212626e 100644 --- a/apps/docs/document-api/reference/blocks/index.mdx +++ b/apps/docs/document-api/reference/blocks/index.mdx @@ -14,5 +14,7 @@ Block-level structural operations. | Operation | Member path | Mutates | Idempotency | Tracked | Dry run | | --- | --- | --- | --- | --- | --- | +| blocks.list | `blocks.list` | No | `idempotent` | No | No | | blocks.delete | `blocks.delete` | Yes | `conditional` | No | Yes | +| blocks.deleteRange | `blocks.deleteRange` | Yes | `conditional` | No | Yes | diff --git a/apps/docs/document-api/reference/blocks/list.mdx b/apps/docs/document-api/reference/blocks/list.mdx new file mode 100644 index 0000000000..3768711a13 --- /dev/null +++ b/apps/docs/document-api/reference/blocks/list.mdx @@ -0,0 +1,183 @@ +--- +title: blocks.list +sidebarTitle: blocks.list +description: List top-level blocks in document order with IDs, types, and text previews. Supports pagination via offset/limit and optional nodeType filtering. +--- + +{/* GENERATED FILE: DO NOT EDIT. Regenerate via `pnpm run docapi:sync`. */} + +> Alpha: Document API is currently alpha and subject to breaking changes. + +## Summary + +List top-level blocks in document order with IDs, types, and text previews. Supports pagination via offset/limit and optional nodeType filtering. + +- Operation ID: `blocks.list` +- API member path: `editor.doc.blocks.list(...)` +- Mutates document: `no` +- Idempotency: `idempotent` +- Supports tracked mode: `no` +- Supports dry run: `no` +- Deterministic target resolution: `yes` + +## Expected result + +Returns a BlocksListResult with total block count, an ordered array of block entries (ordinal, nodeId, nodeType, textPreview, isEmpty), and the current document revision. + +## Input fields + +| Field | Type | Required | Description | +| --- | --- | --- | --- | +| `limit` | number | no | | +| `nodeTypes` | enum[] | no | | +| `offset` | number | no | | + +### Example request + +```json +{ + "limit": 50, + "offset": 0 +} +``` + +## Output fields + +| Field | Type | Required | Description | +| --- | --- | --- | --- | +| `blocks` | object[] | yes | | +| `revision` | string | yes | | +| `total` | number | yes | | + +### Example response + +```json +{ + "blocks": [ + { + "isEmpty": true, + "nodeId": "node-def456", + "nodeType": "paragraph", + "ordinal": 1, + "textPreview": "example" + } + ], + "revision": "example", + "total": 1 +} +``` + +## Pre-apply throws + +- `INVALID_INPUT` + +## Non-applied failure codes + +- None + +## Raw schemas + + +```json +{ + "additionalProperties": false, + "properties": { + "limit": { + "minimum": 1, + "type": "number" + }, + "nodeTypes": { + "items": { + "enum": [ + "paragraph", + "heading", + "listItem", + "table", + "tableRow", + "tableCell", + "tableOfContents", + "image", + "sdt" + ] + }, + "type": "array" + }, + "offset": { + "minimum": 0, + "type": "number" + } + }, + "type": "object" +} +``` + + + +```json +{ + "additionalProperties": false, + "properties": { + "blocks": { + "items": { + "additionalProperties": false, + "properties": { + "isEmpty": { + "type": "boolean" + }, + "nodeId": { + "type": "string" + }, + "nodeType": { + "enum": [ + "paragraph", + "heading", + "listItem", + "table", + "tableRow", + "tableCell", + "tableOfContents", + "image", + "sdt" + ] + }, + "ordinal": { + "type": "number" + }, + "textPreview": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ] + } + }, + "required": [ + "ordinal", + "nodeId", + "nodeType", + "textPreview", + "isEmpty" + ], + "type": "object" + }, + "type": "array" + }, + "revision": { + "type": "string" + }, + "total": { + "type": "number" + } + }, + "required": [ + "total", + "blocks", + "revision" + ], + "type": "object" +} +``` + diff --git a/apps/docs/document-api/reference/capabilities/get.mdx b/apps/docs/document-api/reference/capabilities/get.mdx index f7d0dfe459..7540879a86 100644 --- a/apps/docs/document-api/reference/capabilities/get.mdx +++ b/apps/docs/document-api/reference/capabilities/get.mdx @@ -332,6 +332,16 @@ _No fields._ | `operations.blocks.delete.dryRun` | boolean | yes | | | `operations.blocks.delete.reasons` | enum[] | no | | | `operations.blocks.delete.tracked` | boolean | yes | | +| `operations.blocks.deleteRange` | object | yes | | +| `operations.blocks.deleteRange.available` | boolean | yes | | +| `operations.blocks.deleteRange.dryRun` | boolean | yes | | +| `operations.blocks.deleteRange.reasons` | enum[] | no | | +| `operations.blocks.deleteRange.tracked` | boolean | yes | | +| `operations.blocks.list` | object | yes | | +| `operations.blocks.list.available` | boolean | yes | | +| `operations.blocks.list.dryRun` | boolean | yes | | +| `operations.blocks.list.reasons` | enum[] | no | | +| `operations.blocks.list.tracked` | boolean | yes | | | `operations.bookmarks.get` | object | yes | | | `operations.bookmarks.get.available` | boolean | yes | | | `operations.bookmarks.get.dryRun` | boolean | yes | | @@ -2474,6 +2484,22 @@ _No fields._ ], "tracked": true }, + "blocks.deleteRange": { + "available": true, + "dryRun": true, + "reasons": [ + "COMMAND_UNAVAILABLE" + ], + "tracked": true + }, + "blocks.list": { + "available": true, + "dryRun": true, + "reasons": [ + "COMMAND_UNAVAILABLE" + ], + "tracked": true + }, "bookmarks.get": { "available": true, "dryRun": true, @@ -7351,6 +7377,76 @@ _No fields._ ], "type": "object" }, + "blocks.deleteRange": { + "additionalProperties": false, + "properties": { + "available": { + "type": "boolean" + }, + "dryRun": { + "type": "boolean" + }, + "reasons": { + "items": { + "enum": [ + "COMMAND_UNAVAILABLE", + "HELPER_UNAVAILABLE", + "OPERATION_UNAVAILABLE", + "TRACKED_MODE_UNAVAILABLE", + "DRY_RUN_UNAVAILABLE", + "NAMESPACE_UNAVAILABLE", + "STYLES_PART_MISSING", + "COLLABORATION_ACTIVE" + ] + }, + "type": "array" + }, + "tracked": { + "type": "boolean" + } + }, + "required": [ + "available", + "tracked", + "dryRun" + ], + "type": "object" + }, + "blocks.list": { + "additionalProperties": false, + "properties": { + "available": { + "type": "boolean" + }, + "dryRun": { + "type": "boolean" + }, + "reasons": { + "items": { + "enum": [ + "COMMAND_UNAVAILABLE", + "HELPER_UNAVAILABLE", + "OPERATION_UNAVAILABLE", + "TRACKED_MODE_UNAVAILABLE", + "DRY_RUN_UNAVAILABLE", + "NAMESPACE_UNAVAILABLE", + "STYLES_PART_MISSING", + "COLLABORATION_ACTIVE" + ] + }, + "type": "array" + }, + "tracked": { + "type": "boolean" + } + }, + "required": [ + "available", + "tracked", + "dryRun" + ], + "type": "object" + }, "bookmarks.get": { "additionalProperties": false, "properties": { @@ -19546,7 +19642,9 @@ _No fields._ "insert", "replace", "delete", + "blocks.list", "blocks.delete", + "blocks.deleteRange", "format.apply", "format.bold", "format.italic", diff --git a/apps/docs/document-api/reference/create/paragraph.mdx b/apps/docs/document-api/reference/create/paragraph.mdx index fd432775ad..7179f49c7c 100644 --- a/apps/docs/document-api/reference/create/paragraph.mdx +++ b/apps/docs/document-api/reference/create/paragraph.mdx @@ -1,7 +1,7 @@ --- title: create.paragraph sidebarTitle: create.paragraph -description: Create a new paragraph at the target position. +description: Create a standalone paragraph at the target position. To add a list item, use lists.insert instead. --- {/* GENERATED FILE: DO NOT EDIT. Regenerate via `pnpm run docapi:sync`. */} @@ -10,7 +10,7 @@ description: Create a new paragraph at the target position. ## Summary -Create a new paragraph at the target position. +Create a standalone paragraph at the target position. To add a list item, use lists.insert instead. - Operation ID: `create.paragraph` - API member path: `editor.doc.create.paragraph(...)` diff --git a/apps/docs/document-api/reference/delete.mdx b/apps/docs/document-api/reference/delete.mdx index db16af11f2..de113bfd05 100644 --- a/apps/docs/document-api/reference/delete.mdx +++ b/apps/docs/document-api/reference/delete.mdx @@ -26,14 +26,22 @@ Returns a TextMutationReceipt with applied status; receipt reports NO_OP if the ## Input fields +### Variant 1 (target.kind="selection") + +| Field | Type | Required | Description | +| --- | --- | --- | --- | +| `behavior` | DeleteBehavior | no | DeleteBehavior | +| `target` | SelectionTarget | yes | SelectionTarget | +| `target.end` | SelectionPoint | yes | SelectionPoint | +| `target.kind` | `"selection"` | yes | Constant: `"selection"` | +| `target.start` | SelectionPoint | yes | SelectionPoint | + +### Variant 2 + | Field | Type | Required | Description | | --- | --- | --- | --- | | `behavior` | DeleteBehavior | no | DeleteBehavior | -| `ref` | string | no | | -| `target` | SelectionTarget | no | SelectionTarget | -| `target.end` | SelectionPoint | no | SelectionPoint | -| `target.kind` | `"selection"` | no | Constant: `"selection"` | -| `target.start` | SelectionPoint | no | SelectionPoint | +| `ref` | string | yes | | ### Example request @@ -193,17 +201,35 @@ Returns a TextMutationReceipt with applied status; receipt reports NO_OP if the ```json { - "allOf": [ + "oneOf": [ { - "$ref": "#/$defs/TargetLocator" + "additionalProperties": false, + "properties": { + "behavior": { + "$ref": "#/$defs/DeleteBehavior" + }, + "target": { + "$ref": "#/$defs/SelectionTarget" + } + }, + "required": [ + "target" + ], + "type": "object" }, { "additionalProperties": false, "properties": { "behavior": { "$ref": "#/$defs/DeleteBehavior" + }, + "ref": { + "type": "string" } }, + "required": [ + "ref" + ], "type": "object" } ] diff --git a/apps/docs/document-api/reference/find.mdx b/apps/docs/document-api/reference/find.mdx index 00824dcc82..73fdbd17fa 100644 --- a/apps/docs/document-api/reference/find.mdx +++ b/apps/docs/document-api/reference/find.mdx @@ -1,7 +1,7 @@ --- title: find sidebarTitle: find -description: Search the document for text or node matches using SDM/1 selectors. +description: Search the document for text or node matches using SDM/1 selectors. Returns discovery-grade results — for mutation targeting, use query.match instead. --- {/* GENERATED FILE: DO NOT EDIT. Regenerate via `pnpm run docapi:sync`. */} @@ -10,7 +10,7 @@ description: Search the document for text or node matches using SDM/1 selectors. ## Summary -Search the document for text or node matches using SDM/1 selectors. +Search the document for text or node matches using SDM/1 selectors. Returns discovery-grade results — for mutation targeting, use query.match instead. - Operation ID: `find` - API member path: `editor.doc.find(...)` @@ -35,19 +35,10 @@ Returns an SDFindResult envelope (\{ total, limit, offset, items \}). Each item | `options.includeProvenance` | boolean | no | | | `options.includeResolved` | boolean | no | | | `select` | object(type="text") \\| object(type="node") | yes | One of: object(type="text"), object(type="node") | -| `within` | object | no | | -| `within.anchor` | object | no | | -| `within.anchor.end` | object | no | | -| `within.anchor.end.blockId` | string | no | | -| `within.anchor.end.offset` | integer | no | | -| `within.anchor.start` | object | no | | -| `within.anchor.start.blockId` | string | no | | -| `within.anchor.start.offset` | integer | no | | -| `within.evaluatedRevision` | string | no | | -| `within.kind` | enum | no | `"content"`, `"inline"`, `"annotation"`, `"section"` | +| `within` | BlockNodeAddress | no | BlockNodeAddress | +| `within.kind` | `"block"` | no | Constant: `"block"` | | `within.nodeId` | string | no | | -| `within.path` | string \\| integer[] | no | | -| `within.stability` | enum | no | `"stable"`, `"ephemeral"` | +| `within.nodeType` | enum | no | `"paragraph"`, `"heading"`, `"listItem"`, `"table"`, `"tableRow"`, `"tableCell"`, `"tableOfContents"`, `"image"`, `"sdt"` | ### Example request @@ -61,19 +52,9 @@ Returns an SDFindResult envelope (\{ total, limit, offset, items \}). Each item "type": "text" }, "within": { - "anchor": { - "end": { - "blockId": "block-abc123", - "offset": 0 - }, - "start": { - "blockId": "block-abc123", - "offset": 0 - } - }, - "kind": "content", + "kind": "block", "nodeId": "node-def456", - "stability": "stable" + "nodeType": "paragraph" } } ``` @@ -94,19 +75,9 @@ Returns an SDFindResult envelope (\{ total, limit, offset, items \}). Each item "items": [ { "address": { - "anchor": { - "end": { - "blockId": "block-abc123", - "offset": 0 - }, - "start": { - "blockId": "block-abc123", - "offset": 0 - } - }, - "kind": "content", + "kind": "block", "nodeId": "node-def456", - "stability": "stable" + "nodeType": "paragraph" }, "context": {}, "node": {} @@ -188,11 +159,11 @@ Returns an SDFindResult envelope (\{ total, limit, offset, items \}). Each item "properties": { "kind": { "enum": [ - "content", + "block", "inline" ] }, - "nodeKind": { + "nodeType": { "type": "string" }, "type": { @@ -207,85 +178,7 @@ Returns an SDFindResult envelope (\{ total, limit, offset, items \}). Each item ] }, "within": { - "additionalProperties": false, - "properties": { - "anchor": { - "additionalProperties": false, - "properties": { - "end": { - "additionalProperties": false, - "properties": { - "blockId": { - "type": "string" - }, - "offset": { - "type": "integer" - } - }, - "required": [ - "blockId", - "offset" - ], - "type": "object" - }, - "start": { - "additionalProperties": false, - "properties": { - "blockId": { - "type": "string" - }, - "offset": { - "type": "integer" - } - }, - "required": [ - "blockId", - "offset" - ], - "type": "object" - } - }, - "type": "object" - }, - "evaluatedRevision": { - "type": "string" - }, - "kind": { - "enum": [ - "content", - "inline", - "annotation", - "section" - ] - }, - "nodeId": { - "type": "string" - }, - "path": { - "items": { - "oneOf": [ - { - "type": "string" - }, - { - "type": "integer" - } - ] - }, - "type": "array" - }, - "stability": { - "enum": [ - "stable", - "ephemeral" - ] - } - }, - "required": [ - "kind", - "stability" - ], - "type": "object" + "$ref": "#/$defs/BlockNodeAddress" } }, "required": [ @@ -306,85 +199,7 @@ Returns an SDFindResult envelope (\{ total, limit, offset, items \}). Each item "additionalProperties": false, "properties": { "address": { - "additionalProperties": false, - "properties": { - "anchor": { - "additionalProperties": false, - "properties": { - "end": { - "additionalProperties": false, - "properties": { - "blockId": { - "type": "string" - }, - "offset": { - "type": "integer" - } - }, - "required": [ - "blockId", - "offset" - ], - "type": "object" - }, - "start": { - "additionalProperties": false, - "properties": { - "blockId": { - "type": "string" - }, - "offset": { - "type": "integer" - } - }, - "required": [ - "blockId", - "offset" - ], - "type": "object" - } - }, - "type": "object" - }, - "evaluatedRevision": { - "type": "string" - }, - "kind": { - "enum": [ - "content", - "inline", - "annotation", - "section" - ] - }, - "nodeId": { - "type": "string" - }, - "path": { - "items": { - "oneOf": [ - { - "type": "string" - }, - { - "type": "integer" - } - ] - }, - "type": "array" - }, - "stability": { - "enum": [ - "stable", - "ephemeral" - ] - } - }, - "required": [ - "kind", - "stability" - ], - "type": "object" + "$ref": "#/$defs/NodeAddress" }, "context": { "type": "object" diff --git a/apps/docs/document-api/reference/format/apply.mdx b/apps/docs/document-api/reference/format/apply.mdx index 7fb357d8be..0194e44916 100644 --- a/apps/docs/document-api/reference/format/apply.mdx +++ b/apps/docs/document-api/reference/format/apply.mdx @@ -26,6 +26,61 @@ Returns a TextMutationReceipt confirming inline styles were applied to the targe ## Input fields +### Variant 1 (target.kind="selection") + +| Field | Type | Required | Description | +| --- | --- | --- | --- | +| `inline` | object | yes | | +| `inline.bCs` | boolean \\| null | no | One of: boolean, null | +| `inline.bold` | boolean \\| null | no | One of: boolean, null | +| `inline.border` | object \\| null | no | One of: object, null | +| `inline.caps` | boolean \\| null | no | One of: boolean, null | +| `inline.charScale` | number \\| null | no | One of: number, null | +| `inline.color` | string \\| null | no | One of: string, null | +| `inline.contextualAlternates` | boolean \\| null | no | One of: boolean, null | +| `inline.cs` | boolean \\| null | no | One of: boolean, null | +| `inline.dstrike` | boolean \\| null | no | One of: boolean, null | +| `inline.eastAsianLayout` | object \\| null | no | One of: object, null | +| `inline.em` | string \\| null | no | One of: string, null | +| `inline.emboss` | boolean \\| null | no | One of: boolean, null | +| `inline.fitText` | object \\| null | no | One of: object, null | +| `inline.fontFamily` | string \\| null | no | One of: string, null | +| `inline.fontSize` | number \\| null | no | One of: number, null | +| `inline.fontSizeCs` | number \\| null | no | One of: number, null | +| `inline.highlight` | string \\| null | no | One of: string, null | +| `inline.iCs` | boolean \\| null | no | One of: boolean, null | +| `inline.imprint` | boolean \\| null | no | One of: boolean, null | +| `inline.italic` | boolean \\| null | no | One of: boolean, null | +| `inline.kerning` | number \\| null | no | One of: number, null | +| `inline.lang` | object \\| null | no | One of: object, null | +| `inline.letterSpacing` | number \\| null | no | One of: number, null | +| `inline.ligatures` | string \\| null | no | One of: string, null | +| `inline.numForm` | string \\| null | no | One of: string, null | +| `inline.numSpacing` | string \\| null | no | One of: string, null | +| `inline.oMath` | boolean \\| null | no | One of: boolean, null | +| `inline.outline` | boolean \\| null | no | One of: boolean, null | +| `inline.position` | number \\| null | no | One of: number, null | +| `inline.rFonts` | object \\| null | no | One of: object, null | +| `inline.rStyle` | string \\| null | no | One of: string, null | +| `inline.rtl` | boolean \\| null | no | One of: boolean, null | +| `inline.shading` | object \\| null | no | One of: object, null | +| `inline.shadow` | boolean \\| null | no | One of: boolean, null | +| `inline.smallCaps` | boolean \\| null | no | One of: boolean, null | +| `inline.snapToGrid` | boolean \\| null | no | One of: boolean, null | +| `inline.specVanish` | boolean \\| null | no | One of: boolean, null | +| `inline.strike` | boolean \\| null | no | One of: boolean, null | +| `inline.stylisticSets` | object[] \\| null | no | One of: object[], null | +| `inline.underline` | boolean \\| null \\| object | no | One of: boolean, null, object | +| `inline.vanish` | boolean \\| null | no | One of: boolean, null | +| `inline.vertAlign` | enum \\| null | no | One of: enum, null | +| `inline.webHidden` | boolean \\| null | no | One of: boolean, null | +| `target` | SelectionTarget | yes | SelectionTarget | +| `target.end` | SelectionPoint | yes | SelectionPoint | +| `target.kind` | `"selection"` | yes | Constant: `"selection"` | +| `target.start` | SelectionPoint | yes | SelectionPoint | + +### Variant 2 + | Field | Type | Required | Description | | --- | --- | --- | --- | | `inline` | object | yes | | @@ -72,11 +127,7 @@ Returns a TextMutationReceipt confirming inline styles were applied to the targe | `inline.vanish` | boolean \\| null | no | One of: boolean, null | | `inline.vertAlign` | enum \\| null | no | One of: enum, null | | `inline.webHidden` | boolean \\| null | no | One of: boolean, null | -| `ref` | string | no | | -| `target` | SelectionTarget | no | SelectionTarget | -| `target.end` | SelectionPoint | no | SelectionPoint | -| `target.kind` | `"selection"` | no | Constant: `"selection"` | -| `target.start` | SelectionPoint | no | SelectionPoint | +| `ref` | string | yes | | ### Example request @@ -239,10 +290,7 @@ Returns a TextMutationReceipt confirming inline styles were applied to the targe ```json { - "allOf": [ - { - "$ref": "#/$defs/TargetLocator" - }, + "oneOf": [ { "additionalProperties": false, "properties": { @@ -1054,9 +1102,835 @@ Returns a TextMutationReceipt confirming inline styles were applied to the targe } }, "type": "object" + }, + "target": { + "$ref": "#/$defs/SelectionTarget" + } + }, + "required": [ + "target", + "inline" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "inline": { + "additionalProperties": false, + "minProperties": 1, + "properties": { + "bCs": { + "oneOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ] + }, + "bold": { + "oneOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ] + }, + "border": { + "oneOf": [ + { + "additionalProperties": false, + "minProperties": 1, + "properties": { + "color": { + "oneOf": [ + { + "minLength": 1, + "type": "string" + }, + { + "type": "null" + } + ] + }, + "space": { + "oneOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ] + }, + "sz": { + "oneOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ] + }, + "val": { + "oneOf": [ + { + "minLength": 1, + "type": "string" + }, + { + "type": "null" + } + ] + } + }, + "type": "object" + }, + { + "type": "null" + } + ] + }, + "caps": { + "oneOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ] + }, + "charScale": { + "oneOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ] + }, + "color": { + "oneOf": [ + { + "minLength": 1, + "type": "string" + }, + { + "type": "null" + } + ] + }, + "contextualAlternates": { + "oneOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ] + }, + "cs": { + "oneOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ] + }, + "dstrike": { + "oneOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ] + }, + "eastAsianLayout": { + "oneOf": [ + { + "additionalProperties": false, + "minProperties": 1, + "properties": { + "combine": { + "oneOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ] + }, + "combineBrackets": { + "oneOf": [ + { + "minLength": 1, + "type": "string" + }, + { + "type": "null" + } + ] + }, + "id": { + "oneOf": [ + { + "minLength": 1, + "type": "string" + }, + { + "type": "null" + } + ] + }, + "vert": { + "oneOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ] + }, + "vertCompress": { + "oneOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ] + } + }, + "type": "object" + }, + { + "type": "null" + } + ] + }, + "em": { + "oneOf": [ + { + "minLength": 1, + "type": "string" + }, + { + "type": "null" + } + ] + }, + "emboss": { + "oneOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ] + }, + "fitText": { + "oneOf": [ + { + "additionalProperties": false, + "minProperties": 1, + "properties": { + "id": { + "oneOf": [ + { + "minLength": 1, + "type": "string" + }, + { + "type": "null" + } + ] + }, + "val": { + "oneOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ] + } + }, + "type": "object" + }, + { + "type": "null" + } + ] + }, + "fontFamily": { + "oneOf": [ + { + "minLength": 1, + "type": "string" + }, + { + "type": "null" + } + ] + }, + "fontSize": { + "oneOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ] + }, + "fontSizeCs": { + "oneOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ] + }, + "highlight": { + "oneOf": [ + { + "minLength": 1, + "type": "string" + }, + { + "type": "null" + } + ] + }, + "iCs": { + "oneOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ] + }, + "imprint": { + "oneOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ] + }, + "italic": { + "oneOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ] + }, + "kerning": { + "oneOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ] + }, + "lang": { + "oneOf": [ + { + "additionalProperties": false, + "minProperties": 1, + "properties": { + "bidi": { + "oneOf": [ + { + "minLength": 1, + "type": "string" + }, + { + "type": "null" + } + ] + }, + "eastAsia": { + "oneOf": [ + { + "minLength": 1, + "type": "string" + }, + { + "type": "null" + } + ] + }, + "val": { + "oneOf": [ + { + "minLength": 1, + "type": "string" + }, + { + "type": "null" + } + ] + } + }, + "type": "object" + }, + { + "type": "null" + } + ] + }, + "letterSpacing": { + "oneOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ] + }, + "ligatures": { + "oneOf": [ + { + "minLength": 1, + "type": "string" + }, + { + "type": "null" + } + ] + }, + "numForm": { + "oneOf": [ + { + "minLength": 1, + "type": "string" + }, + { + "type": "null" + } + ] + }, + "numSpacing": { + "oneOf": [ + { + "minLength": 1, + "type": "string" + }, + { + "type": "null" + } + ] + }, + "oMath": { + "oneOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ] + }, + "outline": { + "oneOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ] + }, + "position": { + "oneOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ] + }, + "rFonts": { + "oneOf": [ + { + "additionalProperties": false, + "minProperties": 1, + "properties": { + "ascii": { + "oneOf": [ + { + "minLength": 1, + "type": "string" + }, + { + "type": "null" + } + ] + }, + "asciiTheme": { + "oneOf": [ + { + "minLength": 1, + "type": "string" + }, + { + "type": "null" + } + ] + }, + "cs": { + "oneOf": [ + { + "minLength": 1, + "type": "string" + }, + { + "type": "null" + } + ] + }, + "csTheme": { + "oneOf": [ + { + "minLength": 1, + "type": "string" + }, + { + "type": "null" + } + ] + }, + "eastAsia": { + "oneOf": [ + { + "minLength": 1, + "type": "string" + }, + { + "type": "null" + } + ] + }, + "eastAsiaTheme": { + "oneOf": [ + { + "minLength": 1, + "type": "string" + }, + { + "type": "null" + } + ] + }, + "hAnsi": { + "oneOf": [ + { + "minLength": 1, + "type": "string" + }, + { + "type": "null" + } + ] + }, + "hAnsiTheme": { + "oneOf": [ + { + "minLength": 1, + "type": "string" + }, + { + "type": "null" + } + ] + }, + "hint": { + "oneOf": [ + { + "minLength": 1, + "type": "string" + }, + { + "type": "null" + } + ] + } + }, + "type": "object" + }, + { + "type": "null" + } + ] + }, + "rStyle": { + "oneOf": [ + { + "minLength": 1, + "type": "string" + }, + { + "type": "null" + } + ] + }, + "rtl": { + "oneOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ] + }, + "shading": { + "oneOf": [ + { + "additionalProperties": false, + "minProperties": 1, + "properties": { + "color": { + "oneOf": [ + { + "minLength": 1, + "type": "string" + }, + { + "type": "null" + } + ] + }, + "fill": { + "oneOf": [ + { + "minLength": 1, + "type": "string" + }, + { + "type": "null" + } + ] + }, + "val": { + "oneOf": [ + { + "minLength": 1, + "type": "string" + }, + { + "type": "null" + } + ] + } + }, + "type": "object" + }, + { + "type": "null" + } + ] + }, + "shadow": { + "oneOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ] + }, + "smallCaps": { + "oneOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ] + }, + "snapToGrid": { + "oneOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ] + }, + "specVanish": { + "oneOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ] + }, + "strike": { + "oneOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ] + }, + "stylisticSets": { + "oneOf": [ + { + "items": { + "additionalProperties": false, + "properties": { + "id": { + "type": "number" + }, + "val": { + "type": "boolean" + } + }, + "required": [ + "id" + ], + "type": "object" + }, + "minItems": 1, + "type": "array" + }, + { + "type": "null" + } + ] + }, + "underline": { + "oneOf": [ + { + "type": "boolean" + }, + { + "type": "null" + }, + { + "additionalProperties": false, + "minProperties": 1, + "properties": { + "color": { + "oneOf": [ + { + "minLength": 1, + "type": "string" + }, + { + "type": "null" + } + ] + }, + "style": { + "oneOf": [ + { + "minLength": 1, + "type": "string" + }, + { + "type": "null" + } + ] + }, + "themeColor": { + "oneOf": [ + { + "minLength": 1, + "type": "string" + }, + { + "type": "null" + } + ] + } + }, + "type": "object" + } + ] + }, + "vanish": { + "oneOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ] + }, + "vertAlign": { + "oneOf": [ + { + "enum": [ + "superscript", + "subscript", + "baseline" + ] + }, + { + "type": "null" + } + ] + }, + "webHidden": { + "oneOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ] + } + }, + "type": "object" + }, + "ref": { + "type": "string" } }, "required": [ + "ref", "inline" ], "type": "object" diff --git a/apps/docs/document-api/reference/format/b-cs.mdx b/apps/docs/document-api/reference/format/b-cs.mdx index a53efa3997..15d538aeef 100644 --- a/apps/docs/document-api/reference/format/b-cs.mdx +++ b/apps/docs/document-api/reference/format/b-cs.mdx @@ -26,13 +26,21 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli ## Input fields +### Variant 1 (target.kind="selection") + | Field | Type | Required | Description | | --- | --- | --- | --- | -| `ref` | string | no | | -| `target` | SelectionTarget | no | SelectionTarget | -| `target.end` | SelectionPoint | no | SelectionPoint | -| `target.kind` | `"selection"` | no | Constant: `"selection"` | -| `target.start` | SelectionPoint | no | SelectionPoint | +| `target` | SelectionTarget | yes | SelectionTarget | +| `target.end` | SelectionPoint | yes | SelectionPoint | +| `target.kind` | `"selection"` | yes | Constant: `"selection"` | +| `target.start` | SelectionPoint | yes | SelectionPoint | +| `value` | boolean \\| null | no | One of: boolean, null | + +### Variant 2 + +| Field | Type | Required | Description | +| --- | --- | --- | --- | +| `ref` | string | yes | | | `value` | boolean \\| null | no | One of: boolean, null | ### Example request @@ -193,13 +201,35 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli ```json { - "allOf": [ + "oneOf": [ { - "$ref": "#/$defs/TargetLocator" + "additionalProperties": false, + "properties": { + "target": { + "$ref": "#/$defs/SelectionTarget" + }, + "value": { + "oneOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ] + } + }, + "required": [ + "target" + ], + "type": "object" }, { "additionalProperties": false, "properties": { + "ref": { + "type": "string" + }, "value": { "oneOf": [ { @@ -211,6 +241,9 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli ] } }, + "required": [ + "ref" + ], "type": "object" } ] diff --git a/apps/docs/document-api/reference/format/bold.mdx b/apps/docs/document-api/reference/format/bold.mdx index f34fbbc3dc..351982085e 100644 --- a/apps/docs/document-api/reference/format/bold.mdx +++ b/apps/docs/document-api/reference/format/bold.mdx @@ -26,13 +26,21 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli ## Input fields +### Variant 1 (target.kind="selection") + | Field | Type | Required | Description | | --- | --- | --- | --- | -| `ref` | string | no | | -| `target` | SelectionTarget | no | SelectionTarget | -| `target.end` | SelectionPoint | no | SelectionPoint | -| `target.kind` | `"selection"` | no | Constant: `"selection"` | -| `target.start` | SelectionPoint | no | SelectionPoint | +| `target` | SelectionTarget | yes | SelectionTarget | +| `target.end` | SelectionPoint | yes | SelectionPoint | +| `target.kind` | `"selection"` | yes | Constant: `"selection"` | +| `target.start` | SelectionPoint | yes | SelectionPoint | +| `value` | boolean \\| null | no | One of: boolean, null | + +### Variant 2 + +| Field | Type | Required | Description | +| --- | --- | --- | --- | +| `ref` | string | yes | | | `value` | boolean \\| null | no | One of: boolean, null | ### Example request @@ -193,13 +201,35 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli ```json { - "allOf": [ + "oneOf": [ { - "$ref": "#/$defs/TargetLocator" + "additionalProperties": false, + "properties": { + "target": { + "$ref": "#/$defs/SelectionTarget" + }, + "value": { + "oneOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ] + } + }, + "required": [ + "target" + ], + "type": "object" }, { "additionalProperties": false, "properties": { + "ref": { + "type": "string" + }, "value": { "oneOf": [ { @@ -211,6 +241,9 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli ] } }, + "required": [ + "ref" + ], "type": "object" } ] diff --git a/apps/docs/document-api/reference/format/border.mdx b/apps/docs/document-api/reference/format/border.mdx index 96bc55a219..64a0aa4e9b 100644 --- a/apps/docs/document-api/reference/format/border.mdx +++ b/apps/docs/document-api/reference/format/border.mdx @@ -26,13 +26,21 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli ## Input fields +### Variant 1 (target.kind="selection") + +| Field | Type | Required | Description | +| --- | --- | --- | --- | +| `target` | SelectionTarget | yes | SelectionTarget | +| `target.end` | SelectionPoint | yes | SelectionPoint | +| `target.kind` | `"selection"` | yes | Constant: `"selection"` | +| `target.start` | SelectionPoint | yes | SelectionPoint | +| `value` | object \\| null | yes | One of: object, null | + +### Variant 2 + | Field | Type | Required | Description | | --- | --- | --- | --- | -| `ref` | string | no | | -| `target` | SelectionTarget | no | SelectionTarget | -| `target.end` | SelectionPoint | no | SelectionPoint | -| `target.kind` | `"selection"` | no | Constant: `"selection"` | -| `target.start` | SelectionPoint | no | SelectionPoint | +| `ref` | string | yes | | | `value` | object \\| null | yes | One of: object, null | ### Example request @@ -196,13 +204,82 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli ```json { - "allOf": [ + "oneOf": [ { - "$ref": "#/$defs/TargetLocator" + "additionalProperties": false, + "properties": { + "target": { + "$ref": "#/$defs/SelectionTarget" + }, + "value": { + "oneOf": [ + { + "additionalProperties": false, + "minProperties": 1, + "properties": { + "color": { + "oneOf": [ + { + "minLength": 1, + "type": "string" + }, + { + "type": "null" + } + ] + }, + "space": { + "oneOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ] + }, + "sz": { + "oneOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ] + }, + "val": { + "oneOf": [ + { + "minLength": 1, + "type": "string" + }, + { + "type": "null" + } + ] + } + }, + "type": "object" + }, + { + "type": "null" + } + ] + } + }, + "required": [ + "target", + "value" + ], + "type": "object" }, { "additionalProperties": false, "properties": { + "ref": { + "type": "string" + }, "value": { "oneOf": [ { @@ -261,6 +338,7 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli } }, "required": [ + "ref", "value" ], "type": "object" diff --git a/apps/docs/document-api/reference/format/caps.mdx b/apps/docs/document-api/reference/format/caps.mdx index 9e52f9f5cf..2dd902137d 100644 --- a/apps/docs/document-api/reference/format/caps.mdx +++ b/apps/docs/document-api/reference/format/caps.mdx @@ -26,13 +26,21 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli ## Input fields +### Variant 1 (target.kind="selection") + | Field | Type | Required | Description | | --- | --- | --- | --- | -| `ref` | string | no | | -| `target` | SelectionTarget | no | SelectionTarget | -| `target.end` | SelectionPoint | no | SelectionPoint | -| `target.kind` | `"selection"` | no | Constant: `"selection"` | -| `target.start` | SelectionPoint | no | SelectionPoint | +| `target` | SelectionTarget | yes | SelectionTarget | +| `target.end` | SelectionPoint | yes | SelectionPoint | +| `target.kind` | `"selection"` | yes | Constant: `"selection"` | +| `target.start` | SelectionPoint | yes | SelectionPoint | +| `value` | boolean \\| null | no | One of: boolean, null | + +### Variant 2 + +| Field | Type | Required | Description | +| --- | --- | --- | --- | +| `ref` | string | yes | | | `value` | boolean \\| null | no | One of: boolean, null | ### Example request @@ -193,13 +201,35 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli ```json { - "allOf": [ + "oneOf": [ { - "$ref": "#/$defs/TargetLocator" + "additionalProperties": false, + "properties": { + "target": { + "$ref": "#/$defs/SelectionTarget" + }, + "value": { + "oneOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ] + } + }, + "required": [ + "target" + ], + "type": "object" }, { "additionalProperties": false, "properties": { + "ref": { + "type": "string" + }, "value": { "oneOf": [ { @@ -211,6 +241,9 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli ] } }, + "required": [ + "ref" + ], "type": "object" } ] diff --git a/apps/docs/document-api/reference/format/char-scale.mdx b/apps/docs/document-api/reference/format/char-scale.mdx index c929ddc99d..257b48446c 100644 --- a/apps/docs/document-api/reference/format/char-scale.mdx +++ b/apps/docs/document-api/reference/format/char-scale.mdx @@ -26,13 +26,21 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli ## Input fields +### Variant 1 (target.kind="selection") + | Field | Type | Required | Description | | --- | --- | --- | --- | -| `ref` | string | no | | -| `target` | SelectionTarget | no | SelectionTarget | -| `target.end` | SelectionPoint | no | SelectionPoint | -| `target.kind` | `"selection"` | no | Constant: `"selection"` | -| `target.start` | SelectionPoint | no | SelectionPoint | +| `target` | SelectionTarget | yes | SelectionTarget | +| `target.end` | SelectionPoint | yes | SelectionPoint | +| `target.kind` | `"selection"` | yes | Constant: `"selection"` | +| `target.start` | SelectionPoint | yes | SelectionPoint | +| `value` | number \\| null | yes | One of: number, null | + +### Variant 2 + +| Field | Type | Required | Description | +| --- | --- | --- | --- | +| `ref` | string | yes | | | `value` | number \\| null | yes | One of: number, null | ### Example request @@ -193,13 +201,36 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli ```json { - "allOf": [ + "oneOf": [ { - "$ref": "#/$defs/TargetLocator" + "additionalProperties": false, + "properties": { + "target": { + "$ref": "#/$defs/SelectionTarget" + }, + "value": { + "oneOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ] + } + }, + "required": [ + "target", + "value" + ], + "type": "object" }, { "additionalProperties": false, "properties": { + "ref": { + "type": "string" + }, "value": { "oneOf": [ { @@ -212,6 +243,7 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli } }, "required": [ + "ref", "value" ], "type": "object" diff --git a/apps/docs/document-api/reference/format/color.mdx b/apps/docs/document-api/reference/format/color.mdx index 7e5ce227d8..bbe4ab703e 100644 --- a/apps/docs/document-api/reference/format/color.mdx +++ b/apps/docs/document-api/reference/format/color.mdx @@ -26,13 +26,21 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli ## Input fields +### Variant 1 (target.kind="selection") + | Field | Type | Required | Description | | --- | --- | --- | --- | -| `ref` | string | no | | -| `target` | SelectionTarget | no | SelectionTarget | -| `target.end` | SelectionPoint | no | SelectionPoint | -| `target.kind` | `"selection"` | no | Constant: `"selection"` | -| `target.start` | SelectionPoint | no | SelectionPoint | +| `target` | SelectionTarget | yes | SelectionTarget | +| `target.end` | SelectionPoint | yes | SelectionPoint | +| `target.kind` | `"selection"` | yes | Constant: `"selection"` | +| `target.start` | SelectionPoint | yes | SelectionPoint | +| `value` | string \\| null | yes | One of: string, null | + +### Variant 2 + +| Field | Type | Required | Description | +| --- | --- | --- | --- | +| `ref` | string | yes | | | `value` | string \\| null | yes | One of: string, null | ### Example request @@ -193,13 +201,37 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli ```json { - "allOf": [ + "oneOf": [ { - "$ref": "#/$defs/TargetLocator" + "additionalProperties": false, + "properties": { + "target": { + "$ref": "#/$defs/SelectionTarget" + }, + "value": { + "oneOf": [ + { + "minLength": 1, + "type": "string" + }, + { + "type": "null" + } + ] + } + }, + "required": [ + "target", + "value" + ], + "type": "object" }, { "additionalProperties": false, "properties": { + "ref": { + "type": "string" + }, "value": { "oneOf": [ { @@ -213,6 +245,7 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli } }, "required": [ + "ref", "value" ], "type": "object" diff --git a/apps/docs/document-api/reference/format/contextual-alternates.mdx b/apps/docs/document-api/reference/format/contextual-alternates.mdx index 6601943155..5858ea01ad 100644 --- a/apps/docs/document-api/reference/format/contextual-alternates.mdx +++ b/apps/docs/document-api/reference/format/contextual-alternates.mdx @@ -26,13 +26,21 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli ## Input fields +### Variant 1 (target.kind="selection") + | Field | Type | Required | Description | | --- | --- | --- | --- | -| `ref` | string | no | | -| `target` | SelectionTarget | no | SelectionTarget | -| `target.end` | SelectionPoint | no | SelectionPoint | -| `target.kind` | `"selection"` | no | Constant: `"selection"` | -| `target.start` | SelectionPoint | no | SelectionPoint | +| `target` | SelectionTarget | yes | SelectionTarget | +| `target.end` | SelectionPoint | yes | SelectionPoint | +| `target.kind` | `"selection"` | yes | Constant: `"selection"` | +| `target.start` | SelectionPoint | yes | SelectionPoint | +| `value` | boolean \\| null | no | One of: boolean, null | + +### Variant 2 + +| Field | Type | Required | Description | +| --- | --- | --- | --- | +| `ref` | string | yes | | | `value` | boolean \\| null | no | One of: boolean, null | ### Example request @@ -193,13 +201,35 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli ```json { - "allOf": [ + "oneOf": [ { - "$ref": "#/$defs/TargetLocator" + "additionalProperties": false, + "properties": { + "target": { + "$ref": "#/$defs/SelectionTarget" + }, + "value": { + "oneOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ] + } + }, + "required": [ + "target" + ], + "type": "object" }, { "additionalProperties": false, "properties": { + "ref": { + "type": "string" + }, "value": { "oneOf": [ { @@ -211,6 +241,9 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli ] } }, + "required": [ + "ref" + ], "type": "object" } ] diff --git a/apps/docs/document-api/reference/format/cs.mdx b/apps/docs/document-api/reference/format/cs.mdx index 9d2a74465a..5fb6e48b60 100644 --- a/apps/docs/document-api/reference/format/cs.mdx +++ b/apps/docs/document-api/reference/format/cs.mdx @@ -26,13 +26,21 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli ## Input fields +### Variant 1 (target.kind="selection") + | Field | Type | Required | Description | | --- | --- | --- | --- | -| `ref` | string | no | | -| `target` | SelectionTarget | no | SelectionTarget | -| `target.end` | SelectionPoint | no | SelectionPoint | -| `target.kind` | `"selection"` | no | Constant: `"selection"` | -| `target.start` | SelectionPoint | no | SelectionPoint | +| `target` | SelectionTarget | yes | SelectionTarget | +| `target.end` | SelectionPoint | yes | SelectionPoint | +| `target.kind` | `"selection"` | yes | Constant: `"selection"` | +| `target.start` | SelectionPoint | yes | SelectionPoint | +| `value` | boolean \\| null | no | One of: boolean, null | + +### Variant 2 + +| Field | Type | Required | Description | +| --- | --- | --- | --- | +| `ref` | string | yes | | | `value` | boolean \\| null | no | One of: boolean, null | ### Example request @@ -193,13 +201,35 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli ```json { - "allOf": [ + "oneOf": [ { - "$ref": "#/$defs/TargetLocator" + "additionalProperties": false, + "properties": { + "target": { + "$ref": "#/$defs/SelectionTarget" + }, + "value": { + "oneOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ] + } + }, + "required": [ + "target" + ], + "type": "object" }, { "additionalProperties": false, "properties": { + "ref": { + "type": "string" + }, "value": { "oneOf": [ { @@ -211,6 +241,9 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli ] } }, + "required": [ + "ref" + ], "type": "object" } ] diff --git a/apps/docs/document-api/reference/format/dstrike.mdx b/apps/docs/document-api/reference/format/dstrike.mdx index 7dd43f06d4..fd412503bc 100644 --- a/apps/docs/document-api/reference/format/dstrike.mdx +++ b/apps/docs/document-api/reference/format/dstrike.mdx @@ -26,13 +26,21 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli ## Input fields +### Variant 1 (target.kind="selection") + | Field | Type | Required | Description | | --- | --- | --- | --- | -| `ref` | string | no | | -| `target` | SelectionTarget | no | SelectionTarget | -| `target.end` | SelectionPoint | no | SelectionPoint | -| `target.kind` | `"selection"` | no | Constant: `"selection"` | -| `target.start` | SelectionPoint | no | SelectionPoint | +| `target` | SelectionTarget | yes | SelectionTarget | +| `target.end` | SelectionPoint | yes | SelectionPoint | +| `target.kind` | `"selection"` | yes | Constant: `"selection"` | +| `target.start` | SelectionPoint | yes | SelectionPoint | +| `value` | boolean \\| null | no | One of: boolean, null | + +### Variant 2 + +| Field | Type | Required | Description | +| --- | --- | --- | --- | +| `ref` | string | yes | | | `value` | boolean \\| null | no | One of: boolean, null | ### Example request @@ -193,13 +201,35 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli ```json { - "allOf": [ + "oneOf": [ { - "$ref": "#/$defs/TargetLocator" + "additionalProperties": false, + "properties": { + "target": { + "$ref": "#/$defs/SelectionTarget" + }, + "value": { + "oneOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ] + } + }, + "required": [ + "target" + ], + "type": "object" }, { "additionalProperties": false, "properties": { + "ref": { + "type": "string" + }, "value": { "oneOf": [ { @@ -211,6 +241,9 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli ] } }, + "required": [ + "ref" + ], "type": "object" } ] diff --git a/apps/docs/document-api/reference/format/east-asian-layout.mdx b/apps/docs/document-api/reference/format/east-asian-layout.mdx index ef555bcaf6..ace6aac506 100644 --- a/apps/docs/document-api/reference/format/east-asian-layout.mdx +++ b/apps/docs/document-api/reference/format/east-asian-layout.mdx @@ -26,13 +26,21 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli ## Input fields +### Variant 1 (target.kind="selection") + +| Field | Type | Required | Description | +| --- | --- | --- | --- | +| `target` | SelectionTarget | yes | SelectionTarget | +| `target.end` | SelectionPoint | yes | SelectionPoint | +| `target.kind` | `"selection"` | yes | Constant: `"selection"` | +| `target.start` | SelectionPoint | yes | SelectionPoint | +| `value` | object \\| null | yes | One of: object, null | + +### Variant 2 + | Field | Type | Required | Description | | --- | --- | --- | --- | -| `ref` | string | no | | -| `target` | SelectionTarget | no | SelectionTarget | -| `target.end` | SelectionPoint | no | SelectionPoint | -| `target.kind` | `"selection"` | no | Constant: `"selection"` | -| `target.start` | SelectionPoint | no | SelectionPoint | +| `ref` | string | yes | | | `value` | object \\| null | yes | One of: object, null | ### Example request @@ -196,13 +204,92 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli ```json { - "allOf": [ + "oneOf": [ { - "$ref": "#/$defs/TargetLocator" + "additionalProperties": false, + "properties": { + "target": { + "$ref": "#/$defs/SelectionTarget" + }, + "value": { + "oneOf": [ + { + "additionalProperties": false, + "minProperties": 1, + "properties": { + "combine": { + "oneOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ] + }, + "combineBrackets": { + "oneOf": [ + { + "minLength": 1, + "type": "string" + }, + { + "type": "null" + } + ] + }, + "id": { + "oneOf": [ + { + "minLength": 1, + "type": "string" + }, + { + "type": "null" + } + ] + }, + "vert": { + "oneOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ] + }, + "vertCompress": { + "oneOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ] + } + }, + "type": "object" + }, + { + "type": "null" + } + ] + } + }, + "required": [ + "target", + "value" + ], + "type": "object" }, { "additionalProperties": false, "properties": { + "ref": { + "type": "string" + }, "value": { "oneOf": [ { @@ -271,6 +358,7 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli } }, "required": [ + "ref", "value" ], "type": "object" diff --git a/apps/docs/document-api/reference/format/em.mdx b/apps/docs/document-api/reference/format/em.mdx index 5561ca3788..404315ca86 100644 --- a/apps/docs/document-api/reference/format/em.mdx +++ b/apps/docs/document-api/reference/format/em.mdx @@ -26,13 +26,21 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli ## Input fields +### Variant 1 (target.kind="selection") + | Field | Type | Required | Description | | --- | --- | --- | --- | -| `ref` | string | no | | -| `target` | SelectionTarget | no | SelectionTarget | -| `target.end` | SelectionPoint | no | SelectionPoint | -| `target.kind` | `"selection"` | no | Constant: `"selection"` | -| `target.start` | SelectionPoint | no | SelectionPoint | +| `target` | SelectionTarget | yes | SelectionTarget | +| `target.end` | SelectionPoint | yes | SelectionPoint | +| `target.kind` | `"selection"` | yes | Constant: `"selection"` | +| `target.start` | SelectionPoint | yes | SelectionPoint | +| `value` | string \\| null | yes | One of: string, null | + +### Variant 2 + +| Field | Type | Required | Description | +| --- | --- | --- | --- | +| `ref` | string | yes | | | `value` | string \\| null | yes | One of: string, null | ### Example request @@ -193,13 +201,37 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli ```json { - "allOf": [ + "oneOf": [ { - "$ref": "#/$defs/TargetLocator" + "additionalProperties": false, + "properties": { + "target": { + "$ref": "#/$defs/SelectionTarget" + }, + "value": { + "oneOf": [ + { + "minLength": 1, + "type": "string" + }, + { + "type": "null" + } + ] + } + }, + "required": [ + "target", + "value" + ], + "type": "object" }, { "additionalProperties": false, "properties": { + "ref": { + "type": "string" + }, "value": { "oneOf": [ { @@ -213,6 +245,7 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli } }, "required": [ + "ref", "value" ], "type": "object" diff --git a/apps/docs/document-api/reference/format/emboss.mdx b/apps/docs/document-api/reference/format/emboss.mdx index 38f64ffbb5..0870f50abd 100644 --- a/apps/docs/document-api/reference/format/emboss.mdx +++ b/apps/docs/document-api/reference/format/emboss.mdx @@ -26,13 +26,21 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli ## Input fields +### Variant 1 (target.kind="selection") + | Field | Type | Required | Description | | --- | --- | --- | --- | -| `ref` | string | no | | -| `target` | SelectionTarget | no | SelectionTarget | -| `target.end` | SelectionPoint | no | SelectionPoint | -| `target.kind` | `"selection"` | no | Constant: `"selection"` | -| `target.start` | SelectionPoint | no | SelectionPoint | +| `target` | SelectionTarget | yes | SelectionTarget | +| `target.end` | SelectionPoint | yes | SelectionPoint | +| `target.kind` | `"selection"` | yes | Constant: `"selection"` | +| `target.start` | SelectionPoint | yes | SelectionPoint | +| `value` | boolean \\| null | no | One of: boolean, null | + +### Variant 2 + +| Field | Type | Required | Description | +| --- | --- | --- | --- | +| `ref` | string | yes | | | `value` | boolean \\| null | no | One of: boolean, null | ### Example request @@ -193,13 +201,35 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli ```json { - "allOf": [ + "oneOf": [ { - "$ref": "#/$defs/TargetLocator" + "additionalProperties": false, + "properties": { + "target": { + "$ref": "#/$defs/SelectionTarget" + }, + "value": { + "oneOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ] + } + }, + "required": [ + "target" + ], + "type": "object" }, { "additionalProperties": false, "properties": { + "ref": { + "type": "string" + }, "value": { "oneOf": [ { @@ -211,6 +241,9 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli ] } }, + "required": [ + "ref" + ], "type": "object" } ] diff --git a/apps/docs/document-api/reference/format/fit-text.mdx b/apps/docs/document-api/reference/format/fit-text.mdx index 5f924f4eb1..b0bc6fb38e 100644 --- a/apps/docs/document-api/reference/format/fit-text.mdx +++ b/apps/docs/document-api/reference/format/fit-text.mdx @@ -26,13 +26,21 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli ## Input fields +### Variant 1 (target.kind="selection") + | Field | Type | Required | Description | | --- | --- | --- | --- | -| `ref` | string | no | | -| `target` | SelectionTarget | no | SelectionTarget | -| `target.end` | SelectionPoint | no | SelectionPoint | -| `target.kind` | `"selection"` | no | Constant: `"selection"` | -| `target.start` | SelectionPoint | no | SelectionPoint | +| `target` | SelectionTarget | yes | SelectionTarget | +| `target.end` | SelectionPoint | yes | SelectionPoint | +| `target.kind` | `"selection"` | yes | Constant: `"selection"` | +| `target.start` | SelectionPoint | yes | SelectionPoint | +| `value` | object \\| null | yes | One of: object, null | + +### Variant 2 + +| Field | Type | Required | Description | +| --- | --- | --- | --- | +| `ref` | string | yes | | | `value` | object \\| null | yes | One of: object, null | ### Example request @@ -196,13 +204,61 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli ```json { - "allOf": [ + "oneOf": [ { - "$ref": "#/$defs/TargetLocator" + "additionalProperties": false, + "properties": { + "target": { + "$ref": "#/$defs/SelectionTarget" + }, + "value": { + "oneOf": [ + { + "additionalProperties": false, + "minProperties": 1, + "properties": { + "id": { + "oneOf": [ + { + "minLength": 1, + "type": "string" + }, + { + "type": "null" + } + ] + }, + "val": { + "oneOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ] + } + }, + "type": "object" + }, + { + "type": "null" + } + ] + } + }, + "required": [ + "target", + "value" + ], + "type": "object" }, { "additionalProperties": false, "properties": { + "ref": { + "type": "string" + }, "value": { "oneOf": [ { @@ -240,6 +296,7 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli } }, "required": [ + "ref", "value" ], "type": "object" diff --git a/apps/docs/document-api/reference/format/font-family.mdx b/apps/docs/document-api/reference/format/font-family.mdx index b070bfcc25..e5e95275e3 100644 --- a/apps/docs/document-api/reference/format/font-family.mdx +++ b/apps/docs/document-api/reference/format/font-family.mdx @@ -26,13 +26,21 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli ## Input fields +### Variant 1 (target.kind="selection") + | Field | Type | Required | Description | | --- | --- | --- | --- | -| `ref` | string | no | | -| `target` | SelectionTarget | no | SelectionTarget | -| `target.end` | SelectionPoint | no | SelectionPoint | -| `target.kind` | `"selection"` | no | Constant: `"selection"` | -| `target.start` | SelectionPoint | no | SelectionPoint | +| `target` | SelectionTarget | yes | SelectionTarget | +| `target.end` | SelectionPoint | yes | SelectionPoint | +| `target.kind` | `"selection"` | yes | Constant: `"selection"` | +| `target.start` | SelectionPoint | yes | SelectionPoint | +| `value` | string \\| null | yes | One of: string, null | + +### Variant 2 + +| Field | Type | Required | Description | +| --- | --- | --- | --- | +| `ref` | string | yes | | | `value` | string \\| null | yes | One of: string, null | ### Example request @@ -193,13 +201,37 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli ```json { - "allOf": [ + "oneOf": [ { - "$ref": "#/$defs/TargetLocator" + "additionalProperties": false, + "properties": { + "target": { + "$ref": "#/$defs/SelectionTarget" + }, + "value": { + "oneOf": [ + { + "minLength": 1, + "type": "string" + }, + { + "type": "null" + } + ] + } + }, + "required": [ + "target", + "value" + ], + "type": "object" }, { "additionalProperties": false, "properties": { + "ref": { + "type": "string" + }, "value": { "oneOf": [ { @@ -213,6 +245,7 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli } }, "required": [ + "ref", "value" ], "type": "object" diff --git a/apps/docs/document-api/reference/format/font-size-cs.mdx b/apps/docs/document-api/reference/format/font-size-cs.mdx index 8e0245a068..567b086871 100644 --- a/apps/docs/document-api/reference/format/font-size-cs.mdx +++ b/apps/docs/document-api/reference/format/font-size-cs.mdx @@ -26,13 +26,21 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli ## Input fields +### Variant 1 (target.kind="selection") + | Field | Type | Required | Description | | --- | --- | --- | --- | -| `ref` | string | no | | -| `target` | SelectionTarget | no | SelectionTarget | -| `target.end` | SelectionPoint | no | SelectionPoint | -| `target.kind` | `"selection"` | no | Constant: `"selection"` | -| `target.start` | SelectionPoint | no | SelectionPoint | +| `target` | SelectionTarget | yes | SelectionTarget | +| `target.end` | SelectionPoint | yes | SelectionPoint | +| `target.kind` | `"selection"` | yes | Constant: `"selection"` | +| `target.start` | SelectionPoint | yes | SelectionPoint | +| `value` | number \\| null | yes | One of: number, null | + +### Variant 2 + +| Field | Type | Required | Description | +| --- | --- | --- | --- | +| `ref` | string | yes | | | `value` | number \\| null | yes | One of: number, null | ### Example request @@ -193,13 +201,36 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli ```json { - "allOf": [ + "oneOf": [ { - "$ref": "#/$defs/TargetLocator" + "additionalProperties": false, + "properties": { + "target": { + "$ref": "#/$defs/SelectionTarget" + }, + "value": { + "oneOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ] + } + }, + "required": [ + "target", + "value" + ], + "type": "object" }, { "additionalProperties": false, "properties": { + "ref": { + "type": "string" + }, "value": { "oneOf": [ { @@ -212,6 +243,7 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli } }, "required": [ + "ref", "value" ], "type": "object" diff --git a/apps/docs/document-api/reference/format/font-size.mdx b/apps/docs/document-api/reference/format/font-size.mdx index 56887154a5..7ffcb1c22c 100644 --- a/apps/docs/document-api/reference/format/font-size.mdx +++ b/apps/docs/document-api/reference/format/font-size.mdx @@ -26,13 +26,21 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli ## Input fields +### Variant 1 (target.kind="selection") + | Field | Type | Required | Description | | --- | --- | --- | --- | -| `ref` | string | no | | -| `target` | SelectionTarget | no | SelectionTarget | -| `target.end` | SelectionPoint | no | SelectionPoint | -| `target.kind` | `"selection"` | no | Constant: `"selection"` | -| `target.start` | SelectionPoint | no | SelectionPoint | +| `target` | SelectionTarget | yes | SelectionTarget | +| `target.end` | SelectionPoint | yes | SelectionPoint | +| `target.kind` | `"selection"` | yes | Constant: `"selection"` | +| `target.start` | SelectionPoint | yes | SelectionPoint | +| `value` | number \\| null | yes | One of: number, null | + +### Variant 2 + +| Field | Type | Required | Description | +| --- | --- | --- | --- | +| `ref` | string | yes | | | `value` | number \\| null | yes | One of: number, null | ### Example request @@ -193,13 +201,36 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli ```json { - "allOf": [ + "oneOf": [ { - "$ref": "#/$defs/TargetLocator" + "additionalProperties": false, + "properties": { + "target": { + "$ref": "#/$defs/SelectionTarget" + }, + "value": { + "oneOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ] + } + }, + "required": [ + "target", + "value" + ], + "type": "object" }, { "additionalProperties": false, "properties": { + "ref": { + "type": "string" + }, "value": { "oneOf": [ { @@ -212,6 +243,7 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli } }, "required": [ + "ref", "value" ], "type": "object" diff --git a/apps/docs/document-api/reference/format/highlight.mdx b/apps/docs/document-api/reference/format/highlight.mdx index e77aa0ce1f..949a1e1846 100644 --- a/apps/docs/document-api/reference/format/highlight.mdx +++ b/apps/docs/document-api/reference/format/highlight.mdx @@ -26,13 +26,21 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli ## Input fields +### Variant 1 (target.kind="selection") + | Field | Type | Required | Description | | --- | --- | --- | --- | -| `ref` | string | no | | -| `target` | SelectionTarget | no | SelectionTarget | -| `target.end` | SelectionPoint | no | SelectionPoint | -| `target.kind` | `"selection"` | no | Constant: `"selection"` | -| `target.start` | SelectionPoint | no | SelectionPoint | +| `target` | SelectionTarget | yes | SelectionTarget | +| `target.end` | SelectionPoint | yes | SelectionPoint | +| `target.kind` | `"selection"` | yes | Constant: `"selection"` | +| `target.start` | SelectionPoint | yes | SelectionPoint | +| `value` | string \\| null | yes | One of: string, null | + +### Variant 2 + +| Field | Type | Required | Description | +| --- | --- | --- | --- | +| `ref` | string | yes | | | `value` | string \\| null | yes | One of: string, null | ### Example request @@ -193,13 +201,37 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli ```json { - "allOf": [ + "oneOf": [ { - "$ref": "#/$defs/TargetLocator" + "additionalProperties": false, + "properties": { + "target": { + "$ref": "#/$defs/SelectionTarget" + }, + "value": { + "oneOf": [ + { + "minLength": 1, + "type": "string" + }, + { + "type": "null" + } + ] + } + }, + "required": [ + "target", + "value" + ], + "type": "object" }, { "additionalProperties": false, "properties": { + "ref": { + "type": "string" + }, "value": { "oneOf": [ { @@ -213,6 +245,7 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli } }, "required": [ + "ref", "value" ], "type": "object" diff --git a/apps/docs/document-api/reference/format/i-cs.mdx b/apps/docs/document-api/reference/format/i-cs.mdx index d81f96fcb0..ae728fe82d 100644 --- a/apps/docs/document-api/reference/format/i-cs.mdx +++ b/apps/docs/document-api/reference/format/i-cs.mdx @@ -26,13 +26,21 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli ## Input fields +### Variant 1 (target.kind="selection") + | Field | Type | Required | Description | | --- | --- | --- | --- | -| `ref` | string | no | | -| `target` | SelectionTarget | no | SelectionTarget | -| `target.end` | SelectionPoint | no | SelectionPoint | -| `target.kind` | `"selection"` | no | Constant: `"selection"` | -| `target.start` | SelectionPoint | no | SelectionPoint | +| `target` | SelectionTarget | yes | SelectionTarget | +| `target.end` | SelectionPoint | yes | SelectionPoint | +| `target.kind` | `"selection"` | yes | Constant: `"selection"` | +| `target.start` | SelectionPoint | yes | SelectionPoint | +| `value` | boolean \\| null | no | One of: boolean, null | + +### Variant 2 + +| Field | Type | Required | Description | +| --- | --- | --- | --- | +| `ref` | string | yes | | | `value` | boolean \\| null | no | One of: boolean, null | ### Example request @@ -193,13 +201,35 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli ```json { - "allOf": [ + "oneOf": [ { - "$ref": "#/$defs/TargetLocator" + "additionalProperties": false, + "properties": { + "target": { + "$ref": "#/$defs/SelectionTarget" + }, + "value": { + "oneOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ] + } + }, + "required": [ + "target" + ], + "type": "object" }, { "additionalProperties": false, "properties": { + "ref": { + "type": "string" + }, "value": { "oneOf": [ { @@ -211,6 +241,9 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli ] } }, + "required": [ + "ref" + ], "type": "object" } ] diff --git a/apps/docs/document-api/reference/format/imprint.mdx b/apps/docs/document-api/reference/format/imprint.mdx index ddabcf1af3..745aceee78 100644 --- a/apps/docs/document-api/reference/format/imprint.mdx +++ b/apps/docs/document-api/reference/format/imprint.mdx @@ -26,13 +26,21 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli ## Input fields +### Variant 1 (target.kind="selection") + | Field | Type | Required | Description | | --- | --- | --- | --- | -| `ref` | string | no | | -| `target` | SelectionTarget | no | SelectionTarget | -| `target.end` | SelectionPoint | no | SelectionPoint | -| `target.kind` | `"selection"` | no | Constant: `"selection"` | -| `target.start` | SelectionPoint | no | SelectionPoint | +| `target` | SelectionTarget | yes | SelectionTarget | +| `target.end` | SelectionPoint | yes | SelectionPoint | +| `target.kind` | `"selection"` | yes | Constant: `"selection"` | +| `target.start` | SelectionPoint | yes | SelectionPoint | +| `value` | boolean \\| null | no | One of: boolean, null | + +### Variant 2 + +| Field | Type | Required | Description | +| --- | --- | --- | --- | +| `ref` | string | yes | | | `value` | boolean \\| null | no | One of: boolean, null | ### Example request @@ -193,13 +201,35 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli ```json { - "allOf": [ + "oneOf": [ { - "$ref": "#/$defs/TargetLocator" + "additionalProperties": false, + "properties": { + "target": { + "$ref": "#/$defs/SelectionTarget" + }, + "value": { + "oneOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ] + } + }, + "required": [ + "target" + ], + "type": "object" }, { "additionalProperties": false, "properties": { + "ref": { + "type": "string" + }, "value": { "oneOf": [ { @@ -211,6 +241,9 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli ] } }, + "required": [ + "ref" + ], "type": "object" } ] diff --git a/apps/docs/document-api/reference/format/italic.mdx b/apps/docs/document-api/reference/format/italic.mdx index f07d79e02b..f152ea0e36 100644 --- a/apps/docs/document-api/reference/format/italic.mdx +++ b/apps/docs/document-api/reference/format/italic.mdx @@ -26,13 +26,21 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli ## Input fields +### Variant 1 (target.kind="selection") + | Field | Type | Required | Description | | --- | --- | --- | --- | -| `ref` | string | no | | -| `target` | SelectionTarget | no | SelectionTarget | -| `target.end` | SelectionPoint | no | SelectionPoint | -| `target.kind` | `"selection"` | no | Constant: `"selection"` | -| `target.start` | SelectionPoint | no | SelectionPoint | +| `target` | SelectionTarget | yes | SelectionTarget | +| `target.end` | SelectionPoint | yes | SelectionPoint | +| `target.kind` | `"selection"` | yes | Constant: `"selection"` | +| `target.start` | SelectionPoint | yes | SelectionPoint | +| `value` | boolean \\| null | no | One of: boolean, null | + +### Variant 2 + +| Field | Type | Required | Description | +| --- | --- | --- | --- | +| `ref` | string | yes | | | `value` | boolean \\| null | no | One of: boolean, null | ### Example request @@ -193,13 +201,35 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli ```json { - "allOf": [ + "oneOf": [ { - "$ref": "#/$defs/TargetLocator" + "additionalProperties": false, + "properties": { + "target": { + "$ref": "#/$defs/SelectionTarget" + }, + "value": { + "oneOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ] + } + }, + "required": [ + "target" + ], + "type": "object" }, { "additionalProperties": false, "properties": { + "ref": { + "type": "string" + }, "value": { "oneOf": [ { @@ -211,6 +241,9 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli ] } }, + "required": [ + "ref" + ], "type": "object" } ] diff --git a/apps/docs/document-api/reference/format/kerning.mdx b/apps/docs/document-api/reference/format/kerning.mdx index cc01f84966..a35bc80262 100644 --- a/apps/docs/document-api/reference/format/kerning.mdx +++ b/apps/docs/document-api/reference/format/kerning.mdx @@ -26,13 +26,21 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli ## Input fields +### Variant 1 (target.kind="selection") + | Field | Type | Required | Description | | --- | --- | --- | --- | -| `ref` | string | no | | -| `target` | SelectionTarget | no | SelectionTarget | -| `target.end` | SelectionPoint | no | SelectionPoint | -| `target.kind` | `"selection"` | no | Constant: `"selection"` | -| `target.start` | SelectionPoint | no | SelectionPoint | +| `target` | SelectionTarget | yes | SelectionTarget | +| `target.end` | SelectionPoint | yes | SelectionPoint | +| `target.kind` | `"selection"` | yes | Constant: `"selection"` | +| `target.start` | SelectionPoint | yes | SelectionPoint | +| `value` | number \\| null | yes | One of: number, null | + +### Variant 2 + +| Field | Type | Required | Description | +| --- | --- | --- | --- | +| `ref` | string | yes | | | `value` | number \\| null | yes | One of: number, null | ### Example request @@ -193,13 +201,36 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli ```json { - "allOf": [ + "oneOf": [ { - "$ref": "#/$defs/TargetLocator" + "additionalProperties": false, + "properties": { + "target": { + "$ref": "#/$defs/SelectionTarget" + }, + "value": { + "oneOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ] + } + }, + "required": [ + "target", + "value" + ], + "type": "object" }, { "additionalProperties": false, "properties": { + "ref": { + "type": "string" + }, "value": { "oneOf": [ { @@ -212,6 +243,7 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli } }, "required": [ + "ref", "value" ], "type": "object" diff --git a/apps/docs/document-api/reference/format/lang.mdx b/apps/docs/document-api/reference/format/lang.mdx index ccefa4508e..496ec8acf6 100644 --- a/apps/docs/document-api/reference/format/lang.mdx +++ b/apps/docs/document-api/reference/format/lang.mdx @@ -26,13 +26,21 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli ## Input fields +### Variant 1 (target.kind="selection") + +| Field | Type | Required | Description | +| --- | --- | --- | --- | +| `target` | SelectionTarget | yes | SelectionTarget | +| `target.end` | SelectionPoint | yes | SelectionPoint | +| `target.kind` | `"selection"` | yes | Constant: `"selection"` | +| `target.start` | SelectionPoint | yes | SelectionPoint | +| `value` | object \\| null | yes | One of: object, null | + +### Variant 2 + | Field | Type | Required | Description | | --- | --- | --- | --- | -| `ref` | string | no | | -| `target` | SelectionTarget | no | SelectionTarget | -| `target.end` | SelectionPoint | no | SelectionPoint | -| `target.kind` | `"selection"` | no | Constant: `"selection"` | -| `target.start` | SelectionPoint | no | SelectionPoint | +| `ref` | string | yes | | | `value` | object \\| null | yes | One of: object, null | ### Example request @@ -196,13 +204,73 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli ```json { - "allOf": [ + "oneOf": [ { - "$ref": "#/$defs/TargetLocator" + "additionalProperties": false, + "properties": { + "target": { + "$ref": "#/$defs/SelectionTarget" + }, + "value": { + "oneOf": [ + { + "additionalProperties": false, + "minProperties": 1, + "properties": { + "bidi": { + "oneOf": [ + { + "minLength": 1, + "type": "string" + }, + { + "type": "null" + } + ] + }, + "eastAsia": { + "oneOf": [ + { + "minLength": 1, + "type": "string" + }, + { + "type": "null" + } + ] + }, + "val": { + "oneOf": [ + { + "minLength": 1, + "type": "string" + }, + { + "type": "null" + } + ] + } + }, + "type": "object" + }, + { + "type": "null" + } + ] + } + }, + "required": [ + "target", + "value" + ], + "type": "object" }, { "additionalProperties": false, "properties": { + "ref": { + "type": "string" + }, "value": { "oneOf": [ { @@ -252,6 +320,7 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli } }, "required": [ + "ref", "value" ], "type": "object" diff --git a/apps/docs/document-api/reference/format/letter-spacing.mdx b/apps/docs/document-api/reference/format/letter-spacing.mdx index 2f64e23055..b626bc2948 100644 --- a/apps/docs/document-api/reference/format/letter-spacing.mdx +++ b/apps/docs/document-api/reference/format/letter-spacing.mdx @@ -26,13 +26,21 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli ## Input fields +### Variant 1 (target.kind="selection") + | Field | Type | Required | Description | | --- | --- | --- | --- | -| `ref` | string | no | | -| `target` | SelectionTarget | no | SelectionTarget | -| `target.end` | SelectionPoint | no | SelectionPoint | -| `target.kind` | `"selection"` | no | Constant: `"selection"` | -| `target.start` | SelectionPoint | no | SelectionPoint | +| `target` | SelectionTarget | yes | SelectionTarget | +| `target.end` | SelectionPoint | yes | SelectionPoint | +| `target.kind` | `"selection"` | yes | Constant: `"selection"` | +| `target.start` | SelectionPoint | yes | SelectionPoint | +| `value` | number \\| null | yes | One of: number, null | + +### Variant 2 + +| Field | Type | Required | Description | +| --- | --- | --- | --- | +| `ref` | string | yes | | | `value` | number \\| null | yes | One of: number, null | ### Example request @@ -193,13 +201,36 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli ```json { - "allOf": [ + "oneOf": [ { - "$ref": "#/$defs/TargetLocator" + "additionalProperties": false, + "properties": { + "target": { + "$ref": "#/$defs/SelectionTarget" + }, + "value": { + "oneOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ] + } + }, + "required": [ + "target", + "value" + ], + "type": "object" }, { "additionalProperties": false, "properties": { + "ref": { + "type": "string" + }, "value": { "oneOf": [ { @@ -212,6 +243,7 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli } }, "required": [ + "ref", "value" ], "type": "object" diff --git a/apps/docs/document-api/reference/format/ligatures.mdx b/apps/docs/document-api/reference/format/ligatures.mdx index d991702a8e..86070465fd 100644 --- a/apps/docs/document-api/reference/format/ligatures.mdx +++ b/apps/docs/document-api/reference/format/ligatures.mdx @@ -26,13 +26,21 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli ## Input fields +### Variant 1 (target.kind="selection") + | Field | Type | Required | Description | | --- | --- | --- | --- | -| `ref` | string | no | | -| `target` | SelectionTarget | no | SelectionTarget | -| `target.end` | SelectionPoint | no | SelectionPoint | -| `target.kind` | `"selection"` | no | Constant: `"selection"` | -| `target.start` | SelectionPoint | no | SelectionPoint | +| `target` | SelectionTarget | yes | SelectionTarget | +| `target.end` | SelectionPoint | yes | SelectionPoint | +| `target.kind` | `"selection"` | yes | Constant: `"selection"` | +| `target.start` | SelectionPoint | yes | SelectionPoint | +| `value` | string \\| null | yes | One of: string, null | + +### Variant 2 + +| Field | Type | Required | Description | +| --- | --- | --- | --- | +| `ref` | string | yes | | | `value` | string \\| null | yes | One of: string, null | ### Example request @@ -193,13 +201,37 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli ```json { - "allOf": [ + "oneOf": [ { - "$ref": "#/$defs/TargetLocator" + "additionalProperties": false, + "properties": { + "target": { + "$ref": "#/$defs/SelectionTarget" + }, + "value": { + "oneOf": [ + { + "minLength": 1, + "type": "string" + }, + { + "type": "null" + } + ] + } + }, + "required": [ + "target", + "value" + ], + "type": "object" }, { "additionalProperties": false, "properties": { + "ref": { + "type": "string" + }, "value": { "oneOf": [ { @@ -213,6 +245,7 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli } }, "required": [ + "ref", "value" ], "type": "object" diff --git a/apps/docs/document-api/reference/format/num-form.mdx b/apps/docs/document-api/reference/format/num-form.mdx index 6a028054b7..c967c5ede3 100644 --- a/apps/docs/document-api/reference/format/num-form.mdx +++ b/apps/docs/document-api/reference/format/num-form.mdx @@ -26,13 +26,21 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli ## Input fields +### Variant 1 (target.kind="selection") + | Field | Type | Required | Description | | --- | --- | --- | --- | -| `ref` | string | no | | -| `target` | SelectionTarget | no | SelectionTarget | -| `target.end` | SelectionPoint | no | SelectionPoint | -| `target.kind` | `"selection"` | no | Constant: `"selection"` | -| `target.start` | SelectionPoint | no | SelectionPoint | +| `target` | SelectionTarget | yes | SelectionTarget | +| `target.end` | SelectionPoint | yes | SelectionPoint | +| `target.kind` | `"selection"` | yes | Constant: `"selection"` | +| `target.start` | SelectionPoint | yes | SelectionPoint | +| `value` | string \\| null | yes | One of: string, null | + +### Variant 2 + +| Field | Type | Required | Description | +| --- | --- | --- | --- | +| `ref` | string | yes | | | `value` | string \\| null | yes | One of: string, null | ### Example request @@ -193,13 +201,37 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli ```json { - "allOf": [ + "oneOf": [ { - "$ref": "#/$defs/TargetLocator" + "additionalProperties": false, + "properties": { + "target": { + "$ref": "#/$defs/SelectionTarget" + }, + "value": { + "oneOf": [ + { + "minLength": 1, + "type": "string" + }, + { + "type": "null" + } + ] + } + }, + "required": [ + "target", + "value" + ], + "type": "object" }, { "additionalProperties": false, "properties": { + "ref": { + "type": "string" + }, "value": { "oneOf": [ { @@ -213,6 +245,7 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli } }, "required": [ + "ref", "value" ], "type": "object" diff --git a/apps/docs/document-api/reference/format/num-spacing.mdx b/apps/docs/document-api/reference/format/num-spacing.mdx index 25c0c716ec..92362b23f9 100644 --- a/apps/docs/document-api/reference/format/num-spacing.mdx +++ b/apps/docs/document-api/reference/format/num-spacing.mdx @@ -26,13 +26,21 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli ## Input fields +### Variant 1 (target.kind="selection") + | Field | Type | Required | Description | | --- | --- | --- | --- | -| `ref` | string | no | | -| `target` | SelectionTarget | no | SelectionTarget | -| `target.end` | SelectionPoint | no | SelectionPoint | -| `target.kind` | `"selection"` | no | Constant: `"selection"` | -| `target.start` | SelectionPoint | no | SelectionPoint | +| `target` | SelectionTarget | yes | SelectionTarget | +| `target.end` | SelectionPoint | yes | SelectionPoint | +| `target.kind` | `"selection"` | yes | Constant: `"selection"` | +| `target.start` | SelectionPoint | yes | SelectionPoint | +| `value` | string \\| null | yes | One of: string, null | + +### Variant 2 + +| Field | Type | Required | Description | +| --- | --- | --- | --- | +| `ref` | string | yes | | | `value` | string \\| null | yes | One of: string, null | ### Example request @@ -193,13 +201,37 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli ```json { - "allOf": [ + "oneOf": [ { - "$ref": "#/$defs/TargetLocator" + "additionalProperties": false, + "properties": { + "target": { + "$ref": "#/$defs/SelectionTarget" + }, + "value": { + "oneOf": [ + { + "minLength": 1, + "type": "string" + }, + { + "type": "null" + } + ] + } + }, + "required": [ + "target", + "value" + ], + "type": "object" }, { "additionalProperties": false, "properties": { + "ref": { + "type": "string" + }, "value": { "oneOf": [ { @@ -213,6 +245,7 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli } }, "required": [ + "ref", "value" ], "type": "object" diff --git a/apps/docs/document-api/reference/format/o-math.mdx b/apps/docs/document-api/reference/format/o-math.mdx index 3c53f68c7a..87b9e7d5af 100644 --- a/apps/docs/document-api/reference/format/o-math.mdx +++ b/apps/docs/document-api/reference/format/o-math.mdx @@ -26,13 +26,21 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli ## Input fields +### Variant 1 (target.kind="selection") + | Field | Type | Required | Description | | --- | --- | --- | --- | -| `ref` | string | no | | -| `target` | SelectionTarget | no | SelectionTarget | -| `target.end` | SelectionPoint | no | SelectionPoint | -| `target.kind` | `"selection"` | no | Constant: `"selection"` | -| `target.start` | SelectionPoint | no | SelectionPoint | +| `target` | SelectionTarget | yes | SelectionTarget | +| `target.end` | SelectionPoint | yes | SelectionPoint | +| `target.kind` | `"selection"` | yes | Constant: `"selection"` | +| `target.start` | SelectionPoint | yes | SelectionPoint | +| `value` | boolean \\| null | no | One of: boolean, null | + +### Variant 2 + +| Field | Type | Required | Description | +| --- | --- | --- | --- | +| `ref` | string | yes | | | `value` | boolean \\| null | no | One of: boolean, null | ### Example request @@ -193,13 +201,35 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli ```json { - "allOf": [ + "oneOf": [ { - "$ref": "#/$defs/TargetLocator" + "additionalProperties": false, + "properties": { + "target": { + "$ref": "#/$defs/SelectionTarget" + }, + "value": { + "oneOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ] + } + }, + "required": [ + "target" + ], + "type": "object" }, { "additionalProperties": false, "properties": { + "ref": { + "type": "string" + }, "value": { "oneOf": [ { @@ -211,6 +241,9 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli ] } }, + "required": [ + "ref" + ], "type": "object" } ] diff --git a/apps/docs/document-api/reference/format/outline.mdx b/apps/docs/document-api/reference/format/outline.mdx index 73853c338e..99b9ff949d 100644 --- a/apps/docs/document-api/reference/format/outline.mdx +++ b/apps/docs/document-api/reference/format/outline.mdx @@ -26,13 +26,21 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli ## Input fields +### Variant 1 (target.kind="selection") + | Field | Type | Required | Description | | --- | --- | --- | --- | -| `ref` | string | no | | -| `target` | SelectionTarget | no | SelectionTarget | -| `target.end` | SelectionPoint | no | SelectionPoint | -| `target.kind` | `"selection"` | no | Constant: `"selection"` | -| `target.start` | SelectionPoint | no | SelectionPoint | +| `target` | SelectionTarget | yes | SelectionTarget | +| `target.end` | SelectionPoint | yes | SelectionPoint | +| `target.kind` | `"selection"` | yes | Constant: `"selection"` | +| `target.start` | SelectionPoint | yes | SelectionPoint | +| `value` | boolean \\| null | no | One of: boolean, null | + +### Variant 2 + +| Field | Type | Required | Description | +| --- | --- | --- | --- | +| `ref` | string | yes | | | `value` | boolean \\| null | no | One of: boolean, null | ### Example request @@ -193,13 +201,35 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli ```json { - "allOf": [ + "oneOf": [ { - "$ref": "#/$defs/TargetLocator" + "additionalProperties": false, + "properties": { + "target": { + "$ref": "#/$defs/SelectionTarget" + }, + "value": { + "oneOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ] + } + }, + "required": [ + "target" + ], + "type": "object" }, { "additionalProperties": false, "properties": { + "ref": { + "type": "string" + }, "value": { "oneOf": [ { @@ -211,6 +241,9 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli ] } }, + "required": [ + "ref" + ], "type": "object" } ] diff --git a/apps/docs/document-api/reference/format/position.mdx b/apps/docs/document-api/reference/format/position.mdx index ded503db1b..a927fc0f9e 100644 --- a/apps/docs/document-api/reference/format/position.mdx +++ b/apps/docs/document-api/reference/format/position.mdx @@ -26,13 +26,21 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli ## Input fields +### Variant 1 (target.kind="selection") + | Field | Type | Required | Description | | --- | --- | --- | --- | -| `ref` | string | no | | -| `target` | SelectionTarget | no | SelectionTarget | -| `target.end` | SelectionPoint | no | SelectionPoint | -| `target.kind` | `"selection"` | no | Constant: `"selection"` | -| `target.start` | SelectionPoint | no | SelectionPoint | +| `target` | SelectionTarget | yes | SelectionTarget | +| `target.end` | SelectionPoint | yes | SelectionPoint | +| `target.kind` | `"selection"` | yes | Constant: `"selection"` | +| `target.start` | SelectionPoint | yes | SelectionPoint | +| `value` | number \\| null | yes | One of: number, null | + +### Variant 2 + +| Field | Type | Required | Description | +| --- | --- | --- | --- | +| `ref` | string | yes | | | `value` | number \\| null | yes | One of: number, null | ### Example request @@ -193,13 +201,36 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli ```json { - "allOf": [ + "oneOf": [ { - "$ref": "#/$defs/TargetLocator" + "additionalProperties": false, + "properties": { + "target": { + "$ref": "#/$defs/SelectionTarget" + }, + "value": { + "oneOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ] + } + }, + "required": [ + "target", + "value" + ], + "type": "object" }, { "additionalProperties": false, "properties": { + "ref": { + "type": "string" + }, "value": { "oneOf": [ { @@ -212,6 +243,7 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli } }, "required": [ + "ref", "value" ], "type": "object" diff --git a/apps/docs/document-api/reference/format/r-fonts.mdx b/apps/docs/document-api/reference/format/r-fonts.mdx index 7a553ef0e3..c13e4294d5 100644 --- a/apps/docs/document-api/reference/format/r-fonts.mdx +++ b/apps/docs/document-api/reference/format/r-fonts.mdx @@ -26,13 +26,21 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli ## Input fields +### Variant 1 (target.kind="selection") + | Field | Type | Required | Description | | --- | --- | --- | --- | -| `ref` | string | no | | -| `target` | SelectionTarget | no | SelectionTarget | -| `target.end` | SelectionPoint | no | SelectionPoint | -| `target.kind` | `"selection"` | no | Constant: `"selection"` | -| `target.start` | SelectionPoint | no | SelectionPoint | +| `target` | SelectionTarget | yes | SelectionTarget | +| `target.end` | SelectionPoint | yes | SelectionPoint | +| `target.kind` | `"selection"` | yes | Constant: `"selection"` | +| `target.start` | SelectionPoint | yes | SelectionPoint | +| `value` | object \\| null | yes | One of: object, null | + +### Variant 2 + +| Field | Type | Required | Description | +| --- | --- | --- | --- | +| `ref` | string | yes | | | `value` | object \\| null | yes | One of: object, null | ### Example request @@ -196,13 +204,139 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli ```json { - "allOf": [ + "oneOf": [ { - "$ref": "#/$defs/TargetLocator" + "additionalProperties": false, + "properties": { + "target": { + "$ref": "#/$defs/SelectionTarget" + }, + "value": { + "oneOf": [ + { + "additionalProperties": false, + "minProperties": 1, + "properties": { + "ascii": { + "oneOf": [ + { + "minLength": 1, + "type": "string" + }, + { + "type": "null" + } + ] + }, + "asciiTheme": { + "oneOf": [ + { + "minLength": 1, + "type": "string" + }, + { + "type": "null" + } + ] + }, + "cs": { + "oneOf": [ + { + "minLength": 1, + "type": "string" + }, + { + "type": "null" + } + ] + }, + "csTheme": { + "oneOf": [ + { + "minLength": 1, + "type": "string" + }, + { + "type": "null" + } + ] + }, + "eastAsia": { + "oneOf": [ + { + "minLength": 1, + "type": "string" + }, + { + "type": "null" + } + ] + }, + "eastAsiaTheme": { + "oneOf": [ + { + "minLength": 1, + "type": "string" + }, + { + "type": "null" + } + ] + }, + "hAnsi": { + "oneOf": [ + { + "minLength": 1, + "type": "string" + }, + { + "type": "null" + } + ] + }, + "hAnsiTheme": { + "oneOf": [ + { + "minLength": 1, + "type": "string" + }, + { + "type": "null" + } + ] + }, + "hint": { + "oneOf": [ + { + "minLength": 1, + "type": "string" + }, + { + "type": "null" + } + ] + } + }, + "type": "object" + }, + { + "type": "null" + } + ] + } + }, + "required": [ + "target", + "value" + ], + "type": "object" }, { "additionalProperties": false, "properties": { + "ref": { + "type": "string" + }, "value": { "oneOf": [ { @@ -318,6 +452,7 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli } }, "required": [ + "ref", "value" ], "type": "object" diff --git a/apps/docs/document-api/reference/format/r-style.mdx b/apps/docs/document-api/reference/format/r-style.mdx index 6eab873abb..9c0d232d85 100644 --- a/apps/docs/document-api/reference/format/r-style.mdx +++ b/apps/docs/document-api/reference/format/r-style.mdx @@ -26,13 +26,21 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli ## Input fields +### Variant 1 (target.kind="selection") + | Field | Type | Required | Description | | --- | --- | --- | --- | -| `ref` | string | no | | -| `target` | SelectionTarget | no | SelectionTarget | -| `target.end` | SelectionPoint | no | SelectionPoint | -| `target.kind` | `"selection"` | no | Constant: `"selection"` | -| `target.start` | SelectionPoint | no | SelectionPoint | +| `target` | SelectionTarget | yes | SelectionTarget | +| `target.end` | SelectionPoint | yes | SelectionPoint | +| `target.kind` | `"selection"` | yes | Constant: `"selection"` | +| `target.start` | SelectionPoint | yes | SelectionPoint | +| `value` | string \\| null | yes | One of: string, null | + +### Variant 2 + +| Field | Type | Required | Description | +| --- | --- | --- | --- | +| `ref` | string | yes | | | `value` | string \\| null | yes | One of: string, null | ### Example request @@ -193,13 +201,37 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli ```json { - "allOf": [ + "oneOf": [ { - "$ref": "#/$defs/TargetLocator" + "additionalProperties": false, + "properties": { + "target": { + "$ref": "#/$defs/SelectionTarget" + }, + "value": { + "oneOf": [ + { + "minLength": 1, + "type": "string" + }, + { + "type": "null" + } + ] + } + }, + "required": [ + "target", + "value" + ], + "type": "object" }, { "additionalProperties": false, "properties": { + "ref": { + "type": "string" + }, "value": { "oneOf": [ { @@ -213,6 +245,7 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli } }, "required": [ + "ref", "value" ], "type": "object" diff --git a/apps/docs/document-api/reference/format/rtl.mdx b/apps/docs/document-api/reference/format/rtl.mdx index 7b543ac7e1..7492a60d5c 100644 --- a/apps/docs/document-api/reference/format/rtl.mdx +++ b/apps/docs/document-api/reference/format/rtl.mdx @@ -26,13 +26,21 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli ## Input fields +### Variant 1 (target.kind="selection") + | Field | Type | Required | Description | | --- | --- | --- | --- | -| `ref` | string | no | | -| `target` | SelectionTarget | no | SelectionTarget | -| `target.end` | SelectionPoint | no | SelectionPoint | -| `target.kind` | `"selection"` | no | Constant: `"selection"` | -| `target.start` | SelectionPoint | no | SelectionPoint | +| `target` | SelectionTarget | yes | SelectionTarget | +| `target.end` | SelectionPoint | yes | SelectionPoint | +| `target.kind` | `"selection"` | yes | Constant: `"selection"` | +| `target.start` | SelectionPoint | yes | SelectionPoint | +| `value` | boolean \\| null | no | One of: boolean, null | + +### Variant 2 + +| Field | Type | Required | Description | +| --- | --- | --- | --- | +| `ref` | string | yes | | | `value` | boolean \\| null | no | One of: boolean, null | ### Example request @@ -193,13 +201,35 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli ```json { - "allOf": [ + "oneOf": [ { - "$ref": "#/$defs/TargetLocator" + "additionalProperties": false, + "properties": { + "target": { + "$ref": "#/$defs/SelectionTarget" + }, + "value": { + "oneOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ] + } + }, + "required": [ + "target" + ], + "type": "object" }, { "additionalProperties": false, "properties": { + "ref": { + "type": "string" + }, "value": { "oneOf": [ { @@ -211,6 +241,9 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli ] } }, + "required": [ + "ref" + ], "type": "object" } ] diff --git a/apps/docs/document-api/reference/format/shading.mdx b/apps/docs/document-api/reference/format/shading.mdx index 358551aa15..de11933981 100644 --- a/apps/docs/document-api/reference/format/shading.mdx +++ b/apps/docs/document-api/reference/format/shading.mdx @@ -26,13 +26,21 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli ## Input fields +### Variant 1 (target.kind="selection") + +| Field | Type | Required | Description | +| --- | --- | --- | --- | +| `target` | SelectionTarget | yes | SelectionTarget | +| `target.end` | SelectionPoint | yes | SelectionPoint | +| `target.kind` | `"selection"` | yes | Constant: `"selection"` | +| `target.start` | SelectionPoint | yes | SelectionPoint | +| `value` | object \\| null | yes | One of: object, null | + +### Variant 2 + | Field | Type | Required | Description | | --- | --- | --- | --- | -| `ref` | string | no | | -| `target` | SelectionTarget | no | SelectionTarget | -| `target.end` | SelectionPoint | no | SelectionPoint | -| `target.kind` | `"selection"` | no | Constant: `"selection"` | -| `target.start` | SelectionPoint | no | SelectionPoint | +| `ref` | string | yes | | | `value` | object \\| null | yes | One of: object, null | ### Example request @@ -196,13 +204,73 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli ```json { - "allOf": [ + "oneOf": [ { - "$ref": "#/$defs/TargetLocator" + "additionalProperties": false, + "properties": { + "target": { + "$ref": "#/$defs/SelectionTarget" + }, + "value": { + "oneOf": [ + { + "additionalProperties": false, + "minProperties": 1, + "properties": { + "color": { + "oneOf": [ + { + "minLength": 1, + "type": "string" + }, + { + "type": "null" + } + ] + }, + "fill": { + "oneOf": [ + { + "minLength": 1, + "type": "string" + }, + { + "type": "null" + } + ] + }, + "val": { + "oneOf": [ + { + "minLength": 1, + "type": "string" + }, + { + "type": "null" + } + ] + } + }, + "type": "object" + }, + { + "type": "null" + } + ] + } + }, + "required": [ + "target", + "value" + ], + "type": "object" }, { "additionalProperties": false, "properties": { + "ref": { + "type": "string" + }, "value": { "oneOf": [ { @@ -252,6 +320,7 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli } }, "required": [ + "ref", "value" ], "type": "object" diff --git a/apps/docs/document-api/reference/format/shadow.mdx b/apps/docs/document-api/reference/format/shadow.mdx index ca0a2d5c34..7cd7a9a9f2 100644 --- a/apps/docs/document-api/reference/format/shadow.mdx +++ b/apps/docs/document-api/reference/format/shadow.mdx @@ -26,13 +26,21 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli ## Input fields +### Variant 1 (target.kind="selection") + | Field | Type | Required | Description | | --- | --- | --- | --- | -| `ref` | string | no | | -| `target` | SelectionTarget | no | SelectionTarget | -| `target.end` | SelectionPoint | no | SelectionPoint | -| `target.kind` | `"selection"` | no | Constant: `"selection"` | -| `target.start` | SelectionPoint | no | SelectionPoint | +| `target` | SelectionTarget | yes | SelectionTarget | +| `target.end` | SelectionPoint | yes | SelectionPoint | +| `target.kind` | `"selection"` | yes | Constant: `"selection"` | +| `target.start` | SelectionPoint | yes | SelectionPoint | +| `value` | boolean \\| null | no | One of: boolean, null | + +### Variant 2 + +| Field | Type | Required | Description | +| --- | --- | --- | --- | +| `ref` | string | yes | | | `value` | boolean \\| null | no | One of: boolean, null | ### Example request @@ -193,13 +201,35 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli ```json { - "allOf": [ + "oneOf": [ { - "$ref": "#/$defs/TargetLocator" + "additionalProperties": false, + "properties": { + "target": { + "$ref": "#/$defs/SelectionTarget" + }, + "value": { + "oneOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ] + } + }, + "required": [ + "target" + ], + "type": "object" }, { "additionalProperties": false, "properties": { + "ref": { + "type": "string" + }, "value": { "oneOf": [ { @@ -211,6 +241,9 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli ] } }, + "required": [ + "ref" + ], "type": "object" } ] diff --git a/apps/docs/document-api/reference/format/small-caps.mdx b/apps/docs/document-api/reference/format/small-caps.mdx index 763f025f79..85ef01c8d5 100644 --- a/apps/docs/document-api/reference/format/small-caps.mdx +++ b/apps/docs/document-api/reference/format/small-caps.mdx @@ -26,13 +26,21 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli ## Input fields +### Variant 1 (target.kind="selection") + | Field | Type | Required | Description | | --- | --- | --- | --- | -| `ref` | string | no | | -| `target` | SelectionTarget | no | SelectionTarget | -| `target.end` | SelectionPoint | no | SelectionPoint | -| `target.kind` | `"selection"` | no | Constant: `"selection"` | -| `target.start` | SelectionPoint | no | SelectionPoint | +| `target` | SelectionTarget | yes | SelectionTarget | +| `target.end` | SelectionPoint | yes | SelectionPoint | +| `target.kind` | `"selection"` | yes | Constant: `"selection"` | +| `target.start` | SelectionPoint | yes | SelectionPoint | +| `value` | boolean \\| null | no | One of: boolean, null | + +### Variant 2 + +| Field | Type | Required | Description | +| --- | --- | --- | --- | +| `ref` | string | yes | | | `value` | boolean \\| null | no | One of: boolean, null | ### Example request @@ -193,13 +201,35 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli ```json { - "allOf": [ + "oneOf": [ { - "$ref": "#/$defs/TargetLocator" + "additionalProperties": false, + "properties": { + "target": { + "$ref": "#/$defs/SelectionTarget" + }, + "value": { + "oneOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ] + } + }, + "required": [ + "target" + ], + "type": "object" }, { "additionalProperties": false, "properties": { + "ref": { + "type": "string" + }, "value": { "oneOf": [ { @@ -211,6 +241,9 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli ] } }, + "required": [ + "ref" + ], "type": "object" } ] diff --git a/apps/docs/document-api/reference/format/snap-to-grid.mdx b/apps/docs/document-api/reference/format/snap-to-grid.mdx index dbae541da0..6381068677 100644 --- a/apps/docs/document-api/reference/format/snap-to-grid.mdx +++ b/apps/docs/document-api/reference/format/snap-to-grid.mdx @@ -26,13 +26,21 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli ## Input fields +### Variant 1 (target.kind="selection") + | Field | Type | Required | Description | | --- | --- | --- | --- | -| `ref` | string | no | | -| `target` | SelectionTarget | no | SelectionTarget | -| `target.end` | SelectionPoint | no | SelectionPoint | -| `target.kind` | `"selection"` | no | Constant: `"selection"` | -| `target.start` | SelectionPoint | no | SelectionPoint | +| `target` | SelectionTarget | yes | SelectionTarget | +| `target.end` | SelectionPoint | yes | SelectionPoint | +| `target.kind` | `"selection"` | yes | Constant: `"selection"` | +| `target.start` | SelectionPoint | yes | SelectionPoint | +| `value` | boolean \\| null | no | One of: boolean, null | + +### Variant 2 + +| Field | Type | Required | Description | +| --- | --- | --- | --- | +| `ref` | string | yes | | | `value` | boolean \\| null | no | One of: boolean, null | ### Example request @@ -193,13 +201,35 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli ```json { - "allOf": [ + "oneOf": [ { - "$ref": "#/$defs/TargetLocator" + "additionalProperties": false, + "properties": { + "target": { + "$ref": "#/$defs/SelectionTarget" + }, + "value": { + "oneOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ] + } + }, + "required": [ + "target" + ], + "type": "object" }, { "additionalProperties": false, "properties": { + "ref": { + "type": "string" + }, "value": { "oneOf": [ { @@ -211,6 +241,9 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli ] } }, + "required": [ + "ref" + ], "type": "object" } ] diff --git a/apps/docs/document-api/reference/format/spec-vanish.mdx b/apps/docs/document-api/reference/format/spec-vanish.mdx index 46239814f5..363f38907a 100644 --- a/apps/docs/document-api/reference/format/spec-vanish.mdx +++ b/apps/docs/document-api/reference/format/spec-vanish.mdx @@ -26,13 +26,21 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli ## Input fields +### Variant 1 (target.kind="selection") + | Field | Type | Required | Description | | --- | --- | --- | --- | -| `ref` | string | no | | -| `target` | SelectionTarget | no | SelectionTarget | -| `target.end` | SelectionPoint | no | SelectionPoint | -| `target.kind` | `"selection"` | no | Constant: `"selection"` | -| `target.start` | SelectionPoint | no | SelectionPoint | +| `target` | SelectionTarget | yes | SelectionTarget | +| `target.end` | SelectionPoint | yes | SelectionPoint | +| `target.kind` | `"selection"` | yes | Constant: `"selection"` | +| `target.start` | SelectionPoint | yes | SelectionPoint | +| `value` | boolean \\| null | no | One of: boolean, null | + +### Variant 2 + +| Field | Type | Required | Description | +| --- | --- | --- | --- | +| `ref` | string | yes | | | `value` | boolean \\| null | no | One of: boolean, null | ### Example request @@ -193,13 +201,35 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli ```json { - "allOf": [ + "oneOf": [ { - "$ref": "#/$defs/TargetLocator" + "additionalProperties": false, + "properties": { + "target": { + "$ref": "#/$defs/SelectionTarget" + }, + "value": { + "oneOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ] + } + }, + "required": [ + "target" + ], + "type": "object" }, { "additionalProperties": false, "properties": { + "ref": { + "type": "string" + }, "value": { "oneOf": [ { @@ -211,6 +241,9 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli ] } }, + "required": [ + "ref" + ], "type": "object" } ] diff --git a/apps/docs/document-api/reference/format/strike.mdx b/apps/docs/document-api/reference/format/strike.mdx index 46c2a031e7..893936d966 100644 --- a/apps/docs/document-api/reference/format/strike.mdx +++ b/apps/docs/document-api/reference/format/strike.mdx @@ -26,13 +26,21 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli ## Input fields +### Variant 1 (target.kind="selection") + | Field | Type | Required | Description | | --- | --- | --- | --- | -| `ref` | string | no | | -| `target` | SelectionTarget | no | SelectionTarget | -| `target.end` | SelectionPoint | no | SelectionPoint | -| `target.kind` | `"selection"` | no | Constant: `"selection"` | -| `target.start` | SelectionPoint | no | SelectionPoint | +| `target` | SelectionTarget | yes | SelectionTarget | +| `target.end` | SelectionPoint | yes | SelectionPoint | +| `target.kind` | `"selection"` | yes | Constant: `"selection"` | +| `target.start` | SelectionPoint | yes | SelectionPoint | +| `value` | boolean \\| null | no | One of: boolean, null | + +### Variant 2 + +| Field | Type | Required | Description | +| --- | --- | --- | --- | +| `ref` | string | yes | | | `value` | boolean \\| null | no | One of: boolean, null | ### Example request @@ -193,13 +201,35 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli ```json { - "allOf": [ + "oneOf": [ { - "$ref": "#/$defs/TargetLocator" + "additionalProperties": false, + "properties": { + "target": { + "$ref": "#/$defs/SelectionTarget" + }, + "value": { + "oneOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ] + } + }, + "required": [ + "target" + ], + "type": "object" }, { "additionalProperties": false, "properties": { + "ref": { + "type": "string" + }, "value": { "oneOf": [ { @@ -211,6 +241,9 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli ] } }, + "required": [ + "ref" + ], "type": "object" } ] diff --git a/apps/docs/document-api/reference/format/stylistic-sets.mdx b/apps/docs/document-api/reference/format/stylistic-sets.mdx index 5e8a0d12d9..c8bf9dc322 100644 --- a/apps/docs/document-api/reference/format/stylistic-sets.mdx +++ b/apps/docs/document-api/reference/format/stylistic-sets.mdx @@ -26,13 +26,21 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli ## Input fields +### Variant 1 (target.kind="selection") + +| Field | Type | Required | Description | +| --- | --- | --- | --- | +| `target` | SelectionTarget | yes | SelectionTarget | +| `target.end` | SelectionPoint | yes | SelectionPoint | +| `target.kind` | `"selection"` | yes | Constant: `"selection"` | +| `target.start` | SelectionPoint | yes | SelectionPoint | +| `value` | object[] \\| null | yes | One of: object[], null | + +### Variant 2 + | Field | Type | Required | Description | | --- | --- | --- | --- | -| `ref` | string | no | | -| `target` | SelectionTarget | no | SelectionTarget | -| `target.end` | SelectionPoint | no | SelectionPoint | -| `target.kind` | `"selection"` | no | Constant: `"selection"` | -| `target.start` | SelectionPoint | no | SelectionPoint | +| `ref` | string | yes | | | `value` | object[] \\| null | yes | One of: object[], null | ### Example request @@ -198,13 +206,52 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli ```json { - "allOf": [ + "oneOf": [ { - "$ref": "#/$defs/TargetLocator" + "additionalProperties": false, + "properties": { + "target": { + "$ref": "#/$defs/SelectionTarget" + }, + "value": { + "oneOf": [ + { + "items": { + "additionalProperties": false, + "properties": { + "id": { + "type": "number" + }, + "val": { + "type": "boolean" + } + }, + "required": [ + "id" + ], + "type": "object" + }, + "minItems": 1, + "type": "array" + }, + { + "type": "null" + } + ] + } + }, + "required": [ + "target", + "value" + ], + "type": "object" }, { "additionalProperties": false, "properties": { + "ref": { + "type": "string" + }, "value": { "oneOf": [ { @@ -233,6 +280,7 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli } }, "required": [ + "ref", "value" ], "type": "object" diff --git a/apps/docs/document-api/reference/format/underline.mdx b/apps/docs/document-api/reference/format/underline.mdx index 7523bb9fdc..a0327df84b 100644 --- a/apps/docs/document-api/reference/format/underline.mdx +++ b/apps/docs/document-api/reference/format/underline.mdx @@ -26,13 +26,21 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli ## Input fields +### Variant 1 (target.kind="selection") + | Field | Type | Required | Description | | --- | --- | --- | --- | -| `ref` | string | no | | -| `target` | SelectionTarget | no | SelectionTarget | -| `target.end` | SelectionPoint | no | SelectionPoint | -| `target.kind` | `"selection"` | no | Constant: `"selection"` | -| `target.start` | SelectionPoint | no | SelectionPoint | +| `target` | SelectionTarget | yes | SelectionTarget | +| `target.end` | SelectionPoint | yes | SelectionPoint | +| `target.kind` | `"selection"` | yes | Constant: `"selection"` | +| `target.start` | SelectionPoint | yes | SelectionPoint | +| `value` | boolean \\| null \\| object | no | One of: boolean, null, object | + +### Variant 2 + +| Field | Type | Required | Description | +| --- | --- | --- | --- | +| `ref` | string | yes | | | `value` | boolean \\| null \\| object | no | One of: boolean, null, object | ### Example request @@ -193,13 +201,75 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli ```json { - "allOf": [ + "oneOf": [ { - "$ref": "#/$defs/TargetLocator" + "additionalProperties": false, + "properties": { + "target": { + "$ref": "#/$defs/SelectionTarget" + }, + "value": { + "oneOf": [ + { + "type": "boolean" + }, + { + "type": "null" + }, + { + "additionalProperties": false, + "minProperties": 1, + "properties": { + "color": { + "oneOf": [ + { + "minLength": 1, + "type": "string" + }, + { + "type": "null" + } + ] + }, + "style": { + "oneOf": [ + { + "minLength": 1, + "type": "string" + }, + { + "type": "null" + } + ] + }, + "themeColor": { + "oneOf": [ + { + "minLength": 1, + "type": "string" + }, + { + "type": "null" + } + ] + } + }, + "type": "object" + } + ] + } + }, + "required": [ + "target" + ], + "type": "object" }, { "additionalProperties": false, "properties": { + "ref": { + "type": "string" + }, "value": { "oneOf": [ { @@ -251,6 +321,9 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli ] } }, + "required": [ + "ref" + ], "type": "object" } ] diff --git a/apps/docs/document-api/reference/format/vanish.mdx b/apps/docs/document-api/reference/format/vanish.mdx index ab44297641..5259ee2184 100644 --- a/apps/docs/document-api/reference/format/vanish.mdx +++ b/apps/docs/document-api/reference/format/vanish.mdx @@ -26,13 +26,21 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli ## Input fields +### Variant 1 (target.kind="selection") + | Field | Type | Required | Description | | --- | --- | --- | --- | -| `ref` | string | no | | -| `target` | SelectionTarget | no | SelectionTarget | -| `target.end` | SelectionPoint | no | SelectionPoint | -| `target.kind` | `"selection"` | no | Constant: `"selection"` | -| `target.start` | SelectionPoint | no | SelectionPoint | +| `target` | SelectionTarget | yes | SelectionTarget | +| `target.end` | SelectionPoint | yes | SelectionPoint | +| `target.kind` | `"selection"` | yes | Constant: `"selection"` | +| `target.start` | SelectionPoint | yes | SelectionPoint | +| `value` | boolean \\| null | no | One of: boolean, null | + +### Variant 2 + +| Field | Type | Required | Description | +| --- | --- | --- | --- | +| `ref` | string | yes | | | `value` | boolean \\| null | no | One of: boolean, null | ### Example request @@ -193,13 +201,35 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli ```json { - "allOf": [ + "oneOf": [ { - "$ref": "#/$defs/TargetLocator" + "additionalProperties": false, + "properties": { + "target": { + "$ref": "#/$defs/SelectionTarget" + }, + "value": { + "oneOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ] + } + }, + "required": [ + "target" + ], + "type": "object" }, { "additionalProperties": false, "properties": { + "ref": { + "type": "string" + }, "value": { "oneOf": [ { @@ -211,6 +241,9 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli ] } }, + "required": [ + "ref" + ], "type": "object" } ] diff --git a/apps/docs/document-api/reference/format/vert-align.mdx b/apps/docs/document-api/reference/format/vert-align.mdx index 74d8adf43f..4f15b65e94 100644 --- a/apps/docs/document-api/reference/format/vert-align.mdx +++ b/apps/docs/document-api/reference/format/vert-align.mdx @@ -26,13 +26,21 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli ## Input fields +### Variant 1 (target.kind="selection") + +| Field | Type | Required | Description | +| --- | --- | --- | --- | +| `target` | SelectionTarget | yes | SelectionTarget | +| `target.end` | SelectionPoint | yes | SelectionPoint | +| `target.kind` | `"selection"` | yes | Constant: `"selection"` | +| `target.start` | SelectionPoint | yes | SelectionPoint | +| `value` | enum \\| null | yes | One of: enum, null | + +### Variant 2 + | Field | Type | Required | Description | | --- | --- | --- | --- | -| `ref` | string | no | | -| `target` | SelectionTarget | no | SelectionTarget | -| `target.end` | SelectionPoint | no | SelectionPoint | -| `target.kind` | `"selection"` | no | Constant: `"selection"` | -| `target.start` | SelectionPoint | no | SelectionPoint | +| `ref` | string | yes | | | `value` | enum \\| null | yes | One of: enum, null | ### Example request @@ -193,13 +201,40 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli ```json { - "allOf": [ + "oneOf": [ { - "$ref": "#/$defs/TargetLocator" + "additionalProperties": false, + "properties": { + "target": { + "$ref": "#/$defs/SelectionTarget" + }, + "value": { + "oneOf": [ + { + "enum": [ + "superscript", + "subscript", + "baseline" + ] + }, + { + "type": "null" + } + ] + } + }, + "required": [ + "target", + "value" + ], + "type": "object" }, { "additionalProperties": false, "properties": { + "ref": { + "type": "string" + }, "value": { "oneOf": [ { @@ -216,6 +251,7 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli } }, "required": [ + "ref", "value" ], "type": "object" diff --git a/apps/docs/document-api/reference/format/web-hidden.mdx b/apps/docs/document-api/reference/format/web-hidden.mdx index ca93221879..7f02108c2c 100644 --- a/apps/docs/document-api/reference/format/web-hidden.mdx +++ b/apps/docs/document-api/reference/format/web-hidden.mdx @@ -26,13 +26,21 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli ## Input fields +### Variant 1 (target.kind="selection") + | Field | Type | Required | Description | | --- | --- | --- | --- | -| `ref` | string | no | | -| `target` | SelectionTarget | no | SelectionTarget | -| `target.end` | SelectionPoint | no | SelectionPoint | -| `target.kind` | `"selection"` | no | Constant: `"selection"` | -| `target.start` | SelectionPoint | no | SelectionPoint | +| `target` | SelectionTarget | yes | SelectionTarget | +| `target.end` | SelectionPoint | yes | SelectionPoint | +| `target.kind` | `"selection"` | yes | Constant: `"selection"` | +| `target.start` | SelectionPoint | yes | SelectionPoint | +| `value` | boolean \\| null | no | One of: boolean, null | + +### Variant 2 + +| Field | Type | Required | Description | +| --- | --- | --- | --- | +| `ref` | string | yes | | | `value` | boolean \\| null | no | One of: boolean, null | ### Example request @@ -193,13 +201,35 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli ```json { - "allOf": [ + "oneOf": [ { - "$ref": "#/$defs/TargetLocator" + "additionalProperties": false, + "properties": { + "target": { + "$ref": "#/$defs/SelectionTarget" + }, + "value": { + "oneOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ] + } + }, + "required": [ + "target" + ], + "type": "object" }, { "additionalProperties": false, "properties": { + "ref": { + "type": "string" + }, "value": { "oneOf": [ { @@ -211,6 +241,9 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli ] } }, + "required": [ + "ref" + ], "type": "object" } ] diff --git a/apps/docs/document-api/reference/get-node-by-id.mdx b/apps/docs/document-api/reference/get-node-by-id.mdx index 343007b5a6..8e109619f8 100644 --- a/apps/docs/document-api/reference/get-node-by-id.mdx +++ b/apps/docs/document-api/reference/get-node-by-id.mdx @@ -44,19 +44,7 @@ Returns an SDNodeResult envelope with the projected SDM/1 node and canonical add | Field | Type | Required | Description | | --- | --- | --- | --- | -| `address` | object | yes | | -| `address.anchor` | object | no | | -| `address.anchor.end` | object | no | | -| `address.anchor.end.blockId` | string | no | | -| `address.anchor.end.offset` | integer | no | | -| `address.anchor.start` | object | no | | -| `address.anchor.start.blockId` | string | no | | -| `address.anchor.start.offset` | integer | no | | -| `address.evaluatedRevision` | string | no | | -| `address.kind` | enum | yes | `"content"`, `"inline"`, `"annotation"`, `"section"` | -| `address.nodeId` | string | no | | -| `address.path` | string \\| integer[] | no | | -| `address.stability` | enum | yes | `"stable"`, `"ephemeral"` | +| `address` | NodeAddress | yes | NodeAddress | | `context` | object | no | | | `node` | object | yes | | @@ -65,19 +53,9 @@ Returns an SDNodeResult envelope with the projected SDM/1 node and canonical add ```json { "address": { - "anchor": { - "end": { - "blockId": "block-abc123", - "offset": 0 - }, - "start": { - "blockId": "block-abc123", - "offset": 0 - } - }, - "kind": "content", + "kind": "block", "nodeId": "node-def456", - "stability": "stable" + "nodeType": "paragraph" }, "context": {}, "node": {} @@ -130,85 +108,7 @@ Returns an SDNodeResult envelope with the projected SDM/1 node and canonical add "additionalProperties": false, "properties": { "address": { - "additionalProperties": false, - "properties": { - "anchor": { - "additionalProperties": false, - "properties": { - "end": { - "additionalProperties": false, - "properties": { - "blockId": { - "type": "string" - }, - "offset": { - "type": "integer" - } - }, - "required": [ - "blockId", - "offset" - ], - "type": "object" - }, - "start": { - "additionalProperties": false, - "properties": { - "blockId": { - "type": "string" - }, - "offset": { - "type": "integer" - } - }, - "required": [ - "blockId", - "offset" - ], - "type": "object" - } - }, - "type": "object" - }, - "evaluatedRevision": { - "type": "string" - }, - "kind": { - "enum": [ - "content", - "inline", - "annotation", - "section" - ] - }, - "nodeId": { - "type": "string" - }, - "path": { - "items": { - "oneOf": [ - { - "type": "string" - }, - { - "type": "integer" - } - ] - }, - "type": "array" - }, - "stability": { - "enum": [ - "stable", - "ephemeral" - ] - } - }, - "required": [ - "kind", - "stability" - ], - "type": "object" + "$ref": "#/$defs/NodeAddress" }, "context": { "type": "object" diff --git a/apps/docs/document-api/reference/get-node.mdx b/apps/docs/document-api/reference/get-node.mdx index de5d899c9a..61b83b612b 100644 --- a/apps/docs/document-api/reference/get-node.mdx +++ b/apps/docs/document-api/reference/get-node.mdx @@ -62,19 +62,7 @@ Returns an SDNodeResult envelope with the projected SDM/1 node and canonical add | Field | Type | Required | Description | | --- | --- | --- | --- | -| `address` | object | yes | | -| `address.anchor` | object | no | | -| `address.anchor.end` | object | no | | -| `address.anchor.end.blockId` | string | no | | -| `address.anchor.end.offset` | integer | no | | -| `address.anchor.start` | object | no | | -| `address.anchor.start.blockId` | string | no | | -| `address.anchor.start.offset` | integer | no | | -| `address.evaluatedRevision` | string | no | | -| `address.kind` | enum | yes | `"content"`, `"inline"`, `"annotation"`, `"section"` | -| `address.nodeId` | string | no | | -| `address.path` | string \\| integer[] | no | | -| `address.stability` | enum | yes | `"stable"`, `"ephemeral"` | +| `address` | NodeAddress | yes | NodeAddress | | `context` | object | no | | | `node` | object | yes | | @@ -83,19 +71,9 @@ Returns an SDNodeResult envelope with the projected SDM/1 node and canonical add ```json { "address": { - "anchor": { - "end": { - "blockId": "block-abc123", - "offset": 0 - }, - "start": { - "blockId": "block-abc123", - "offset": 0 - } - }, - "kind": "content", + "kind": "block", "nodeId": "node-def456", - "stability": "stable" + "nodeType": "paragraph" }, "context": {}, "node": {} @@ -127,85 +105,7 @@ Returns an SDNodeResult envelope with the projected SDM/1 node and canonical add "additionalProperties": false, "properties": { "address": { - "additionalProperties": false, - "properties": { - "anchor": { - "additionalProperties": false, - "properties": { - "end": { - "additionalProperties": false, - "properties": { - "blockId": { - "type": "string" - }, - "offset": { - "type": "integer" - } - }, - "required": [ - "blockId", - "offset" - ], - "type": "object" - }, - "start": { - "additionalProperties": false, - "properties": { - "blockId": { - "type": "string" - }, - "offset": { - "type": "integer" - } - }, - "required": [ - "blockId", - "offset" - ], - "type": "object" - } - }, - "type": "object" - }, - "evaluatedRevision": { - "type": "string" - }, - "kind": { - "enum": [ - "content", - "inline", - "annotation", - "section" - ] - }, - "nodeId": { - "type": "string" - }, - "path": { - "items": { - "oneOf": [ - { - "type": "string" - }, - { - "type": "integer" - } - ] - }, - "type": "array" - }, - "stability": { - "enum": [ - "stable", - "ephemeral" - ] - } - }, - "required": [ - "kind", - "stability" - ], - "type": "object" + "$ref": "#/$defs/NodeAddress" }, "context": { "type": "object" diff --git a/apps/docs/document-api/reference/history/redo.mdx b/apps/docs/document-api/reference/history/redo.mdx index e349560b74..a0dc7448d8 100644 --- a/apps/docs/document-api/reference/history/redo.mdx +++ b/apps/docs/document-api/reference/history/redo.mdx @@ -22,7 +22,7 @@ Redo the most recently undone action in the active editor. ## Expected result -Returns a HistoryActionResult with noop flag and revision before/after; noop is true when the redo stack is empty. +Returns a HistoryActionResult with noop flag, reason (EMPTY_REDO_STACK | NO_EFFECT when noop), and revision before/after. ## Input fields diff --git a/apps/docs/document-api/reference/history/undo.mdx b/apps/docs/document-api/reference/history/undo.mdx index c94bcb0ca9..10a5f77cde 100644 --- a/apps/docs/document-api/reference/history/undo.mdx +++ b/apps/docs/document-api/reference/history/undo.mdx @@ -22,7 +22,7 @@ Undo the most recent history-safe mutation in the active editor. ## Expected result -Returns a HistoryActionResult with noop flag and revision before/after; noop is true when the undo stack is empty. +Returns a HistoryActionResult with noop flag, reason (EMPTY_UNDO_STACK | NO_EFFECT when noop), and revision before/after. ## Input fields diff --git a/apps/docs/document-api/reference/hyperlinks/list.mdx b/apps/docs/document-api/reference/hyperlinks/list.mdx index 74c3978873..9d554fb7b4 100644 --- a/apps/docs/document-api/reference/hyperlinks/list.mdx +++ b/apps/docs/document-api/reference/hyperlinks/list.mdx @@ -33,7 +33,10 @@ Returns a HyperlinksListResult with an array of hyperlink discovery items and pa | `limit` | integer | no | | | `offset` | integer | no | | | `textPattern` | string | no | | -| `within` | NodeAddress | no | NodeAddress | +| `within` | BlockNodeAddress | no | BlockNodeAddress | +| `within.kind` | `"block"` | no | Constant: `"block"` | +| `within.nodeId` | string | no | | +| `within.nodeType` | enum | no | `"paragraph"`, `"heading"`, `"listItem"`, `"table"`, `"tableRow"`, `"tableCell"`, `"tableOfContents"`, `"image"`, `"sdt"` | ### Example request @@ -128,7 +131,7 @@ Returns a HyperlinksListResult with an array of hyperlink discovery items and pa "type": "string" }, "within": { - "$ref": "#/$defs/NodeAddress" + "$ref": "#/$defs/BlockNodeAddress" } }, "type": "object" diff --git a/apps/docs/document-api/reference/index.mdx b/apps/docs/document-api/reference/index.mdx index a889f4d3e1..447f5e75c7 100644 --- a/apps/docs/document-api/reference/index.mdx +++ b/apps/docs/document-api/reference/index.mdx @@ -21,7 +21,7 @@ Document API is currently alpha and subject to breaking changes. | Namespace | Canonical ops | Aliases | Total surface | Reference | | --- | --- | --- | --- | --- | | Core | 13 | 0 | 13 | [Open](/document-api/reference/core/index) | -| Blocks | 1 | 0 | 1 | [Open](/document-api/reference/blocks/index) | +| Blocks | 3 | 0 | 3 | [Open](/document-api/reference/blocks/index) | | Capabilities | 1 | 0 | 1 | [Open](/document-api/reference/capabilities/index) | | Create | 6 | 0 | 6 | [Open](/document-api/reference/create/index) | | Sections | 18 | 0 | 18 | [Open](/document-api/reference/sections/index) | @@ -60,7 +60,7 @@ The tables below are grouped by namespace. | Operation | API member path | Description | | --- | --- | --- | | get | editor.doc.get(...) | Read the full document as an SDDocument structure. | -| find | editor.doc.find(...) | Search the document for text or node matches using SDM/1 selectors. | +| find | editor.doc.find(...) | Search the document for text or node matches using SDM/1 selectors. Returns discovery-grade results — for mutation targeting, use query.match instead. | | getNode | editor.doc.getNode(...) | Retrieve a single node by target position. | | getNodeById | editor.doc.getNodeById(...) | Retrieve a single node by its unique ID. | | getText | editor.doc.getText(...) | Extract the plain-text content of the document. | @@ -69,15 +69,17 @@ The tables below are grouped by namespace. | markdownToFragment | editor.doc.markdownToFragment(...) | Convert a Markdown string into an SDM/1 structural fragment. | | info | editor.doc.info(...) | Return document metadata including revision, node count, and capabilities. | | clearContent | editor.doc.clearContent(...) | Clear all document body content, leaving a single empty paragraph. | -| insert | editor.doc.insert(...) | Insert content at a target position, or at the end of the document when target is omitted. Accepts two input shapes: legacy string-based (value + type) or structural SDFragment (content). Supports text (default), markdown, and html content types via the `type` field in legacy mode. Structural mode accepts an SDFragment with typed nodes (paragraphs, tables, images, etc.). | -| replace | editor.doc.replace(...) | Replace content at a contiguous document selection. Text path accepts a SelectionTarget or ref plus replacement text. Structural path accepts an SDAddress, SelectionTarget, or ref plus SDFragment content. | +| insert | editor.doc.insert(...) | Insert content into the document. Two input shapes: legacy string-based (value + type) inserts inline content at a text position within an existing block; structural SDFragment (content) inserts one or more blocks as siblings relative to a BlockNodeAddress target. When target is omitted, content appends at the end of the document. Legacy mode supports text (default), markdown, and html content types via the `type` field. Structural mode uses `placement` (before/after/insideStart/insideEnd) to position relative to the target block. | +| replace | editor.doc.replace(...) | Replace content at a contiguous document selection. Text path accepts a SelectionTarget or ref plus replacement text. Structural path accepts a BlockNodeAddress (replaces whole block), SelectionTarget (expands to full covered block boundaries), or ref plus SDFragment content. | | delete | editor.doc.delete(...) | Delete content at a contiguous document selection. Accepts a SelectionTarget or mutation-ready ref. Supports cross-block deletion and optional block-edge expansion via behavior mode. | #### Blocks | Operation | API member path | Description | | --- | --- | --- | -| blocks.delete | editor.doc.blocks.delete(...) | Delete an entire block node (paragraph, heading, list item, table, or sdt) deterministically by block address. | +| blocks.list | editor.doc.blocks.list(...) | List top-level blocks in document order with IDs, types, and text previews. Supports pagination via offset/limit and optional nodeType filtering. | +| blocks.delete | editor.doc.blocks.delete(...) | Delete an entire block node (paragraph, heading, list item, table, image, or sdt) deterministically. | +| blocks.deleteRange | editor.doc.blocks.deleteRange(...) | Delete a contiguous range of top-level blocks between two endpoints (inclusive). Both endpoints must be direct children of the document node. Supports dry-run preview. | #### Capabilities @@ -89,7 +91,7 @@ The tables below are grouped by namespace. | Operation | API member path | Description | | --- | --- | --- | -| create.paragraph | editor.doc.create.paragraph(...) | Create a new paragraph at the target position. | +| create.paragraph | editor.doc.create.paragraph(...) | Create a standalone paragraph at the target position. To add a list item, use lists.insert instead. | | create.heading | editor.doc.create.heading(...) | Create a new heading at the target position. | | create.sectionBreak | editor.doc.create.sectionBreak(...) | Create a section break at the target location with optional initial section properties. | | create.table | editor.doc.create.table(...) | Create a new table at the target position. | @@ -181,7 +183,7 @@ The tables below are grouped by namespace. | --- | --- | --- | | lists.list | editor.doc.lists.list(...) | List all list nodes in the document, optionally filtered by scope. | | lists.get | editor.doc.lists.get(...) | Retrieve a specific list node by target. | -| lists.insert | editor.doc.lists.insert(...) | Insert a new list at the target position. | +| lists.insert | editor.doc.lists.insert(...) | Insert a new list item before or after an existing list item. The new item inherits the target list context. | | lists.create | editor.doc.lists.create(...) | Create a new list from one or more paragraphs, or convert existing paragraphs into a new list. | | lists.attach | editor.doc.lists.attach(...) | Convert non-list paragraphs to list items under an existing list sequence. | | lists.detach | editor.doc.lists.detach(...) | Remove numbering properties from list items, converting them to plain paragraphs. | @@ -231,7 +233,7 @@ The tables below are grouped by namespace. | Operation | API member path | Description | | --- | --- | --- | -| query.match | editor.doc.query.match(...) | Deterministic selector-based search with cardinality contracts for mutation targeting. | +| query.match | editor.doc.query.match(...) | Deterministic selector-based search returning mutation-grade addresses and text ranges. Use this to discover targets before any mutation. | #### Mutations diff --git a/apps/docs/document-api/reference/insert.mdx b/apps/docs/document-api/reference/insert.mdx index aea983981b..3253612f16 100644 --- a/apps/docs/document-api/reference/insert.mdx +++ b/apps/docs/document-api/reference/insert.mdx @@ -1,7 +1,7 @@ --- title: insert sidebarTitle: insert -description: "Insert content at a target position, or at the end of the document when target is omitted. Accepts two input shapes: legacy string-based (value + type) or structural SDFragment (content). Supports text (default), markdown, and html content types via the `type` field in legacy mode. Structural mode accepts an SDFragment with typed nodes (paragraphs, tables, images, etc.)." +description: "Insert content into the document. Two input shapes: legacy string-based (value + type) inserts inline content at a text position within an existing block; structural SDFragment (content) inserts one or more blocks as siblings relative to a BlockNodeAddress target. When target is omitted, content appends at the end of the document. Legacy mode supports text (default), markdown, and html content types via the `type` field. Structural mode uses `placement` (before/after/insideStart/insideEnd) to position relative to the target block." --- {/* GENERATED FILE: DO NOT EDIT. Regenerate via `pnpm run docapi:sync`. */} @@ -10,7 +10,7 @@ description: "Insert content at a target position, or at the end of the document ## Summary -Insert content at a target position, or at the end of the document when target is omitted. Accepts two input shapes: legacy string-based (value + type) or structural SDFragment (content). Supports text (default), markdown, and html content types via the `type` field in legacy mode. Structural mode accepts an SDFragment with typed nodes (paragraphs, tables, images, etc.). +Insert content into the document. Two input shapes: legacy string-based (value + type) inserts inline content at a text position within an existing block; structural SDFragment (content) inserts one or more blocks as siblings relative to a BlockNodeAddress target. When target is omitted, content appends at the end of the document. Legacy mode supports text (default), markdown, and html content types via the `type` field. Structural mode uses `placement` (before/after/insideStart/insideEnd) to position relative to the target block. - Operation ID: `insert` - API member path: `editor.doc.insert(...)` @@ -64,36 +64,14 @@ Returns a TextMutationReceipt with applied status; receipt reports NO_OP if the | `evaluatedRevision.after` | string | no | | | `evaluatedRevision.before` | string | no | | | `resolution` | object | no | | -| `resolution.requestedTarget` | object | no | | -| `resolution.requestedTarget.anchor` | object | no | | -| `resolution.requestedTarget.anchor.end` | object | no | | -| `resolution.requestedTarget.anchor.end.blockId` | string | no | | -| `resolution.requestedTarget.anchor.end.offset` | integer | no | | -| `resolution.requestedTarget.anchor.start` | object | no | | -| `resolution.requestedTarget.anchor.start.blockId` | string | no | | -| `resolution.requestedTarget.anchor.start.offset` | integer | no | | -| `resolution.requestedTarget.evaluatedRevision` | string | no | | -| `resolution.requestedTarget.kind` | enum | no | `"content"`, `"inline"`, `"annotation"`, `"section"` | -| `resolution.requestedTarget.nodeId` | string | no | | -| `resolution.requestedTarget.path` | string \\| integer[] | no | | -| `resolution.requestedTarget.stability` | enum | no | `"stable"`, `"ephemeral"` | +| `resolution.range` | TextMutationRange | no | TextMutationRange | +| `resolution.range.from` | integer | no | | +| `resolution.range.to` | integer | no | | | `resolution.selectionTarget` | SelectionTarget | no | SelectionTarget | | `resolution.selectionTarget.end` | SelectionPoint | no | SelectionPoint | | `resolution.selectionTarget.kind` | `"selection"` | no | Constant: `"selection"` | | `resolution.selectionTarget.start` | SelectionPoint | no | SelectionPoint | -| `resolution.target` | object | no | | -| `resolution.target.anchor` | object | no | | -| `resolution.target.anchor.end` | object | no | | -| `resolution.target.anchor.end.blockId` | string | no | | -| `resolution.target.anchor.end.offset` | integer | no | | -| `resolution.target.anchor.start` | object | no | | -| `resolution.target.anchor.start.blockId` | string | no | | -| `resolution.target.anchor.start.offset` | integer | no | | -| `resolution.target.evaluatedRevision` | string | no | | -| `resolution.target.kind` | enum | no | `"content"`, `"inline"`, `"annotation"`, `"section"` | -| `resolution.target.nodeId` | string | no | | -| `resolution.target.path` | string \\| integer[] | no | | -| `resolution.target.stability` | enum | no | `"stable"`, `"ephemeral"` | +| `resolution.target` | TextAddress \\| BlockNodeAddress | no | One of: TextAddress, BlockNodeAddress | | `success` | `true` | yes | Constant: `true` | ### Variant 2 (resolution.selectionTarget.kind="selection") @@ -108,36 +86,14 @@ Returns a TextMutationReceipt with applied status; receipt reports NO_OP if the | `failure.details` | any | no | | | `failure.message` | string | yes | | | `resolution` | object | no | | -| `resolution.requestedTarget` | object | no | | -| `resolution.requestedTarget.anchor` | object | no | | -| `resolution.requestedTarget.anchor.end` | object | no | | -| `resolution.requestedTarget.anchor.end.blockId` | string | no | | -| `resolution.requestedTarget.anchor.end.offset` | integer | no | | -| `resolution.requestedTarget.anchor.start` | object | no | | -| `resolution.requestedTarget.anchor.start.blockId` | string | no | | -| `resolution.requestedTarget.anchor.start.offset` | integer | no | | -| `resolution.requestedTarget.evaluatedRevision` | string | no | | -| `resolution.requestedTarget.kind` | enum | no | `"content"`, `"inline"`, `"annotation"`, `"section"` | -| `resolution.requestedTarget.nodeId` | string | no | | -| `resolution.requestedTarget.path` | string \\| integer[] | no | | -| `resolution.requestedTarget.stability` | enum | no | `"stable"`, `"ephemeral"` | +| `resolution.range` | TextMutationRange | no | TextMutationRange | +| `resolution.range.from` | integer | no | | +| `resolution.range.to` | integer | no | | | `resolution.selectionTarget` | SelectionTarget | no | SelectionTarget | | `resolution.selectionTarget.end` | SelectionPoint | no | SelectionPoint | | `resolution.selectionTarget.kind` | `"selection"` | no | Constant: `"selection"` | | `resolution.selectionTarget.start` | SelectionPoint | no | SelectionPoint | -| `resolution.target` | object | no | | -| `resolution.target.anchor` | object | no | | -| `resolution.target.anchor.end` | object | no | | -| `resolution.target.anchor.end.blockId` | string | no | | -| `resolution.target.anchor.end.offset` | integer | no | | -| `resolution.target.anchor.start` | object | no | | -| `resolution.target.anchor.start.blockId` | string | no | | -| `resolution.target.anchor.start.offset` | integer | no | | -| `resolution.target.evaluatedRevision` | string | no | | -| `resolution.target.kind` | enum | no | `"content"`, `"inline"`, `"annotation"`, `"section"` | -| `resolution.target.nodeId` | string | no | | -| `resolution.target.path` | string \\| integer[] | no | | -| `resolution.target.stability` | enum | no | `"stable"`, `"ephemeral"` | +| `resolution.target` | TextAddress \\| BlockNodeAddress | no | One of: TextAddress, BlockNodeAddress | | `success` | `false` | yes | Constant: `false` | ### Example response @@ -149,20 +105,9 @@ Returns a TextMutationReceipt with applied status; receipt reports NO_OP if the "before": "example" }, "resolution": { - "requestedTarget": { - "anchor": { - "end": { - "blockId": "block-abc123", - "offset": 0 - }, - "start": { - "blockId": "block-abc123", - "offset": 0 - } - }, - "kind": "content", - "nodeId": "node-def456", - "stability": "stable" + "range": { + "from": 0, + "to": 10 }, "selectionTarget": { "end": { @@ -178,19 +123,12 @@ Returns a TextMutationReceipt with applied status; receipt reports NO_OP if the } }, "target": { - "anchor": { - "end": { - "blockId": "block-abc123", - "offset": 0 - }, - "start": { - "blockId": "block-abc123", - "offset": 0 - } - }, - "kind": "content", - "nodeId": "node-def456", - "stability": "stable" + "blockId": "block-abc123", + "kind": "text", + "range": { + "end": 10, + "start": 0 + } } }, "success": true @@ -282,174 +220,26 @@ Returns a TextMutationReceipt with applied status; receipt reports NO_OP if the "resolution": { "additionalProperties": false, "properties": { - "requestedTarget": { - "additionalProperties": false, - "properties": { - "anchor": { - "additionalProperties": false, - "properties": { - "end": { - "additionalProperties": false, - "properties": { - "blockId": { - "type": "string" - }, - "offset": { - "type": "integer" - } - }, - "required": [ - "blockId", - "offset" - ], - "type": "object" - }, - "start": { - "additionalProperties": false, - "properties": { - "blockId": { - "type": "string" - }, - "offset": { - "type": "integer" - } - }, - "required": [ - "blockId", - "offset" - ], - "type": "object" - } - }, - "type": "object" - }, - "evaluatedRevision": { - "type": "string" - }, - "kind": { - "enum": [ - "content", - "inline", - "annotation", - "section" - ] - }, - "nodeId": { - "type": "string" - }, - "path": { - "items": { - "oneOf": [ - { - "type": "string" - }, - { - "type": "integer" - } - ] - }, - "type": "array" - }, - "stability": { - "enum": [ - "stable", - "ephemeral" - ] - } - }, - "required": [ - "kind", - "stability" - ], - "type": "object" + "range": { + "$ref": "#/$defs/TextMutationRange" }, "selectionTarget": { "$ref": "#/$defs/SelectionTarget" }, "target": { - "additionalProperties": false, - "properties": { - "anchor": { - "additionalProperties": false, - "properties": { - "end": { - "additionalProperties": false, - "properties": { - "blockId": { - "type": "string" - }, - "offset": { - "type": "integer" - } - }, - "required": [ - "blockId", - "offset" - ], - "type": "object" - }, - "start": { - "additionalProperties": false, - "properties": { - "blockId": { - "type": "string" - }, - "offset": { - "type": "integer" - } - }, - "required": [ - "blockId", - "offset" - ], - "type": "object" - } - }, - "type": "object" + "oneOf": [ + { + "$ref": "#/$defs/TextAddress" }, - "evaluatedRevision": { - "type": "string" - }, - "kind": { - "enum": [ - "content", - "inline", - "annotation", - "section" - ] - }, - "nodeId": { - "type": "string" - }, - "path": { - "items": { - "oneOf": [ - { - "type": "string" - }, - { - "type": "integer" - } - ] - }, - "type": "array" - }, - "stability": { - "enum": [ - "stable", - "ephemeral" - ] + { + "$ref": "#/$defs/BlockNodeAddress" } - }, - "required": [ - "kind", - "stability" - ], - "type": "object" + ] } }, "required": [ - "target" + "target", + "range" ], "type": "object" }, @@ -516,174 +306,26 @@ Returns a TextMutationReceipt with applied status; receipt reports NO_OP if the "resolution": { "additionalProperties": false, "properties": { - "requestedTarget": { - "additionalProperties": false, - "properties": { - "anchor": { - "additionalProperties": false, - "properties": { - "end": { - "additionalProperties": false, - "properties": { - "blockId": { - "type": "string" - }, - "offset": { - "type": "integer" - } - }, - "required": [ - "blockId", - "offset" - ], - "type": "object" - }, - "start": { - "additionalProperties": false, - "properties": { - "blockId": { - "type": "string" - }, - "offset": { - "type": "integer" - } - }, - "required": [ - "blockId", - "offset" - ], - "type": "object" - } - }, - "type": "object" - }, - "evaluatedRevision": { - "type": "string" - }, - "kind": { - "enum": [ - "content", - "inline", - "annotation", - "section" - ] - }, - "nodeId": { - "type": "string" - }, - "path": { - "items": { - "oneOf": [ - { - "type": "string" - }, - { - "type": "integer" - } - ] - }, - "type": "array" - }, - "stability": { - "enum": [ - "stable", - "ephemeral" - ] - } - }, - "required": [ - "kind", - "stability" - ], - "type": "object" + "range": { + "$ref": "#/$defs/TextMutationRange" }, "selectionTarget": { "$ref": "#/$defs/SelectionTarget" }, "target": { - "additionalProperties": false, - "properties": { - "anchor": { - "additionalProperties": false, - "properties": { - "end": { - "additionalProperties": false, - "properties": { - "blockId": { - "type": "string" - }, - "offset": { - "type": "integer" - } - }, - "required": [ - "blockId", - "offset" - ], - "type": "object" - }, - "start": { - "additionalProperties": false, - "properties": { - "blockId": { - "type": "string" - }, - "offset": { - "type": "integer" - } - }, - "required": [ - "blockId", - "offset" - ], - "type": "object" - } - }, - "type": "object" - }, - "evaluatedRevision": { - "type": "string" - }, - "kind": { - "enum": [ - "content", - "inline", - "annotation", - "section" - ] + "oneOf": [ + { + "$ref": "#/$defs/TextAddress" }, - "nodeId": { - "type": "string" - }, - "path": { - "items": { - "oneOf": [ - { - "type": "string" - }, - { - "type": "integer" - } - ] - }, - "type": "array" - }, - "stability": { - "enum": [ - "stable", - "ephemeral" - ] + { + "$ref": "#/$defs/BlockNodeAddress" } - }, - "required": [ - "kind", - "stability" - ], - "type": "object" + ] } }, "required": [ - "target" + "target", + "range" ], "type": "object" }, @@ -726,174 +368,26 @@ Returns a TextMutationReceipt with applied status; receipt reports NO_OP if the "resolution": { "additionalProperties": false, "properties": { - "requestedTarget": { - "additionalProperties": false, - "properties": { - "anchor": { - "additionalProperties": false, - "properties": { - "end": { - "additionalProperties": false, - "properties": { - "blockId": { - "type": "string" - }, - "offset": { - "type": "integer" - } - }, - "required": [ - "blockId", - "offset" - ], - "type": "object" - }, - "start": { - "additionalProperties": false, - "properties": { - "blockId": { - "type": "string" - }, - "offset": { - "type": "integer" - } - }, - "required": [ - "blockId", - "offset" - ], - "type": "object" - } - }, - "type": "object" - }, - "evaluatedRevision": { - "type": "string" - }, - "kind": { - "enum": [ - "content", - "inline", - "annotation", - "section" - ] - }, - "nodeId": { - "type": "string" - }, - "path": { - "items": { - "oneOf": [ - { - "type": "string" - }, - { - "type": "integer" - } - ] - }, - "type": "array" - }, - "stability": { - "enum": [ - "stable", - "ephemeral" - ] - } - }, - "required": [ - "kind", - "stability" - ], - "type": "object" + "range": { + "$ref": "#/$defs/TextMutationRange" }, "selectionTarget": { "$ref": "#/$defs/SelectionTarget" }, "target": { - "additionalProperties": false, - "properties": { - "anchor": { - "additionalProperties": false, - "properties": { - "end": { - "additionalProperties": false, - "properties": { - "blockId": { - "type": "string" - }, - "offset": { - "type": "integer" - } - }, - "required": [ - "blockId", - "offset" - ], - "type": "object" - }, - "start": { - "additionalProperties": false, - "properties": { - "blockId": { - "type": "string" - }, - "offset": { - "type": "integer" - } - }, - "required": [ - "blockId", - "offset" - ], - "type": "object" - } - }, - "type": "object" + "oneOf": [ + { + "$ref": "#/$defs/TextAddress" }, - "evaluatedRevision": { - "type": "string" - }, - "kind": { - "enum": [ - "content", - "inline", - "annotation", - "section" - ] - }, - "nodeId": { - "type": "string" - }, - "path": { - "items": { - "oneOf": [ - { - "type": "string" - }, - { - "type": "integer" - } - ] - }, - "type": "array" - }, - "stability": { - "enum": [ - "stable", - "ephemeral" - ] + { + "$ref": "#/$defs/BlockNodeAddress" } - }, - "required": [ - "kind", - "stability" - ], - "type": "object" + ] } }, "required": [ - "target" + "target", + "range" ], "type": "object" }, @@ -965,174 +459,26 @@ Returns a TextMutationReceipt with applied status; receipt reports NO_OP if the "resolution": { "additionalProperties": false, "properties": { - "requestedTarget": { - "additionalProperties": false, - "properties": { - "anchor": { - "additionalProperties": false, - "properties": { - "end": { - "additionalProperties": false, - "properties": { - "blockId": { - "type": "string" - }, - "offset": { - "type": "integer" - } - }, - "required": [ - "blockId", - "offset" - ], - "type": "object" - }, - "start": { - "additionalProperties": false, - "properties": { - "blockId": { - "type": "string" - }, - "offset": { - "type": "integer" - } - }, - "required": [ - "blockId", - "offset" - ], - "type": "object" - } - }, - "type": "object" - }, - "evaluatedRevision": { - "type": "string" - }, - "kind": { - "enum": [ - "content", - "inline", - "annotation", - "section" - ] - }, - "nodeId": { - "type": "string" - }, - "path": { - "items": { - "oneOf": [ - { - "type": "string" - }, - { - "type": "integer" - } - ] - }, - "type": "array" - }, - "stability": { - "enum": [ - "stable", - "ephemeral" - ] - } - }, - "required": [ - "kind", - "stability" - ], - "type": "object" + "range": { + "$ref": "#/$defs/TextMutationRange" }, "selectionTarget": { "$ref": "#/$defs/SelectionTarget" }, "target": { - "additionalProperties": false, - "properties": { - "anchor": { - "additionalProperties": false, - "properties": { - "end": { - "additionalProperties": false, - "properties": { - "blockId": { - "type": "string" - }, - "offset": { - "type": "integer" - } - }, - "required": [ - "blockId", - "offset" - ], - "type": "object" - }, - "start": { - "additionalProperties": false, - "properties": { - "blockId": { - "type": "string" - }, - "offset": { - "type": "integer" - } - }, - "required": [ - "blockId", - "offset" - ], - "type": "object" - } - }, - "type": "object" - }, - "evaluatedRevision": { - "type": "string" + "oneOf": [ + { + "$ref": "#/$defs/TextAddress" }, - "kind": { - "enum": [ - "content", - "inline", - "annotation", - "section" - ] - }, - "nodeId": { - "type": "string" - }, - "path": { - "items": { - "oneOf": [ - { - "type": "string" - }, - { - "type": "integer" - } - ] - }, - "type": "array" - }, - "stability": { - "enum": [ - "stable", - "ephemeral" - ] + { + "$ref": "#/$defs/BlockNodeAddress" } - }, - "required": [ - "kind", - "stability" - ], - "type": "object" + ] } }, "required": [ - "target" + "target", + "range" ], "type": "object" }, diff --git a/apps/docs/document-api/reference/lists/insert.mdx b/apps/docs/document-api/reference/lists/insert.mdx index 8b507ffb60..d7d8720ef4 100644 --- a/apps/docs/document-api/reference/lists/insert.mdx +++ b/apps/docs/document-api/reference/lists/insert.mdx @@ -1,7 +1,7 @@ --- title: lists.insert sidebarTitle: lists.insert -description: Insert a new list at the target position. +description: Insert a new list item before or after an existing list item. The new item inherits the target list context. --- {/* GENERATED FILE: DO NOT EDIT. Regenerate via `pnpm run docapi:sync`. */} @@ -10,7 +10,7 @@ description: Insert a new list at the target position. ## Summary -Insert a new list at the target position. +Insert a new list item before or after an existing list item. The new item inherits the target list context. - Operation ID: `lists.insert` - API member path: `editor.doc.lists.insert(...)` diff --git a/apps/docs/document-api/reference/mutations/apply.mdx b/apps/docs/document-api/reference/mutations/apply.mdx index 251189e6ca..0a57f2e1b2 100644 --- a/apps/docs/document-api/reference/mutations/apply.mdx +++ b/apps/docs/document-api/reference/mutations/apply.mdx @@ -475,7 +475,7 @@ The runtime capability snapshot also exposes this allowlist at `planEngine.suppo ] }, "within": { - "$ref": "#/$defs/NodeAddress" + "$ref": "#/$defs/BlockNodeAddress" } }, "required": [ @@ -496,7 +496,7 @@ The runtime capability snapshot also exposes this allowlist at `planEngine.suppo "type": "string" }, "within": { - "$ref": "#/$defs/NodeAddress" + "$ref": "#/$defs/BlockNodeAddress" } }, "required": [ @@ -718,7 +718,7 @@ The runtime capability snapshot also exposes this allowlist at `planEngine.suppo ] }, "within": { - "$ref": "#/$defs/NodeAddress" + "$ref": "#/$defs/BlockNodeAddress" } }, "required": [ @@ -846,7 +846,7 @@ The runtime capability snapshot also exposes this allowlist at `planEngine.suppo ] }, "within": { - "$ref": "#/$defs/NodeAddress" + "$ref": "#/$defs/BlockNodeAddress" } }, "required": [ @@ -867,7 +867,7 @@ The runtime capability snapshot also exposes this allowlist at `planEngine.suppo "type": "string" }, "within": { - "$ref": "#/$defs/NodeAddress" + "$ref": "#/$defs/BlockNodeAddress" } }, "required": [ @@ -1822,7 +1822,7 @@ The runtime capability snapshot also exposes this allowlist at `planEngine.suppo ] }, "within": { - "$ref": "#/$defs/NodeAddress" + "$ref": "#/$defs/BlockNodeAddress" } }, "required": [ @@ -1843,7 +1843,7 @@ The runtime capability snapshot also exposes this allowlist at `planEngine.suppo "type": "string" }, "within": { - "$ref": "#/$defs/NodeAddress" + "$ref": "#/$defs/BlockNodeAddress" } }, "required": [ @@ -1983,7 +1983,7 @@ The runtime capability snapshot also exposes this allowlist at `planEngine.suppo ] }, "within": { - "$ref": "#/$defs/NodeAddress" + "$ref": "#/$defs/BlockNodeAddress" } }, "required": [ diff --git a/apps/docs/document-api/reference/mutations/preview.mdx b/apps/docs/document-api/reference/mutations/preview.mdx index 1193559c50..ed6d4a6342 100644 --- a/apps/docs/document-api/reference/mutations/preview.mdx +++ b/apps/docs/document-api/reference/mutations/preview.mdx @@ -461,7 +461,7 @@ The runtime capability snapshot also exposes this allowlist at `planEngine.suppo ] }, "within": { - "$ref": "#/$defs/NodeAddress" + "$ref": "#/$defs/BlockNodeAddress" } }, "required": [ @@ -482,7 +482,7 @@ The runtime capability snapshot also exposes this allowlist at `planEngine.suppo "type": "string" }, "within": { - "$ref": "#/$defs/NodeAddress" + "$ref": "#/$defs/BlockNodeAddress" } }, "required": [ @@ -704,7 +704,7 @@ The runtime capability snapshot also exposes this allowlist at `planEngine.suppo ] }, "within": { - "$ref": "#/$defs/NodeAddress" + "$ref": "#/$defs/BlockNodeAddress" } }, "required": [ @@ -832,7 +832,7 @@ The runtime capability snapshot also exposes this allowlist at `planEngine.suppo ] }, "within": { - "$ref": "#/$defs/NodeAddress" + "$ref": "#/$defs/BlockNodeAddress" } }, "required": [ @@ -853,7 +853,7 @@ The runtime capability snapshot also exposes this allowlist at `planEngine.suppo "type": "string" }, "within": { - "$ref": "#/$defs/NodeAddress" + "$ref": "#/$defs/BlockNodeAddress" } }, "required": [ @@ -1808,7 +1808,7 @@ The runtime capability snapshot also exposes this allowlist at `planEngine.suppo ] }, "within": { - "$ref": "#/$defs/NodeAddress" + "$ref": "#/$defs/BlockNodeAddress" } }, "required": [ @@ -1829,7 +1829,7 @@ The runtime capability snapshot also exposes this allowlist at `planEngine.suppo "type": "string" }, "within": { - "$ref": "#/$defs/NodeAddress" + "$ref": "#/$defs/BlockNodeAddress" } }, "required": [ @@ -1969,7 +1969,7 @@ The runtime capability snapshot also exposes this allowlist at `planEngine.suppo ] }, "within": { - "$ref": "#/$defs/NodeAddress" + "$ref": "#/$defs/BlockNodeAddress" } }, "required": [ diff --git a/apps/docs/document-api/reference/query/match.mdx b/apps/docs/document-api/reference/query/match.mdx index ab0498f536..8fd898726c 100644 --- a/apps/docs/document-api/reference/query/match.mdx +++ b/apps/docs/document-api/reference/query/match.mdx @@ -1,7 +1,7 @@ --- title: query.match sidebarTitle: query.match -description: Deterministic selector-based search with cardinality contracts for mutation targeting. +description: Deterministic selector-based search returning mutation-grade addresses and text ranges. Use this to discover targets before any mutation. --- {/* GENERATED FILE: DO NOT EDIT. Regenerate via `pnpm run docapi:sync`. */} @@ -10,7 +10,7 @@ description: Deterministic selector-based search with cardinality contracts for ## Summary -Deterministic selector-based search with cardinality contracts for mutation targeting. +Deterministic selector-based search returning mutation-grade addresses and text ranges. Use this to discover targets before any mutation. - Operation ID: `query.match` - API member path: `editor.doc.query.match(...)` @@ -34,7 +34,10 @@ Returns a QueryMatchOutput with the resolved target address and cardinality meta | `offset` | integer | no | | | `require` | enum | no | `"any"`, `"first"`, `"exactlyOne"`, `"all"` | | `select` | object(type="text") \\| object(type="node") | yes | One of: object(type="text"), object(type="node") | -| `within` | NodeAddress | no | NodeAddress | +| `within` | BlockNodeAddress | no | BlockNodeAddress | +| `within.kind` | `"block"` | no | Constant: `"block"` | +| `within.nodeId` | string | no | | +| `within.nodeType` | enum | no | `"paragraph"`, `"heading"`, `"listItem"`, `"table"`, `"tableRow"`, `"tableCell"`, `"tableOfContents"`, `"image"`, `"sdt"` | ### Example request @@ -280,7 +283,7 @@ Returns a QueryMatchOutput with the resolved target address and cardinality meta ] }, "within": { - "$ref": "#/$defs/NodeAddress" + "$ref": "#/$defs/BlockNodeAddress" } }, "required": [ @@ -306,7 +309,7 @@ Returns a QueryMatchOutput with the resolved target address and cardinality meta "additionalProperties": false, "properties": { "address": { - "$ref": "#/$defs/NodeAddress" + "$ref": "#/$defs/BlockNodeAddress" }, "blocks": { "items": { diff --git a/apps/docs/document-api/reference/replace.mdx b/apps/docs/document-api/reference/replace.mdx index 4c443f24f8..f5654cab7f 100644 --- a/apps/docs/document-api/reference/replace.mdx +++ b/apps/docs/document-api/reference/replace.mdx @@ -1,7 +1,7 @@ --- title: replace sidebarTitle: replace -description: Replace content at a contiguous document selection. Text path accepts a SelectionTarget or ref plus replacement text. Structural path accepts an SDAddress, SelectionTarget, or ref plus SDFragment content. +description: Replace content at a contiguous document selection. Text path accepts a SelectionTarget or ref plus replacement text. Structural path accepts a BlockNodeAddress (replaces whole block), SelectionTarget (expands to full covered block boundaries), or ref plus SDFragment content. --- {/* GENERATED FILE: DO NOT EDIT. Regenerate via `pnpm run docapi:sync`. */} @@ -10,7 +10,7 @@ description: Replace content at a contiguous document selection. Text path accep ## Summary -Replace content at a contiguous document selection. Text path accepts a SelectionTarget or ref plus replacement text. Structural path accepts an SDAddress, SelectionTarget, or ref plus SDFragment content. +Replace content at a contiguous document selection. Text path accepts a SelectionTarget or ref plus replacement text. Structural path accepts a BlockNodeAddress (replaces whole block), SelectionTarget (expands to full covered block boundaries), or ref plus SDFragment content. - Operation ID: `replace` - API member path: `editor.doc.replace(...)` @@ -28,23 +28,11 @@ Returns an SDMutationReceipt with applied status; receipt reports NO_OP if the t ### Variant 1 -| Field | Type | Required | Description | -| --- | --- | --- | --- | -| `ref` | string | no | | -| `target` | SelectionTarget | no | SelectionTarget | -| `target.end` | SelectionPoint | no | SelectionPoint | -| `target.kind` | `"selection"` | no | Constant: `"selection"` | -| `target.start` | SelectionPoint | no | SelectionPoint | -| `text` | string | yes | | +_No fields._ ### Variant 2 -| Field | Type | Required | Description | -| --- | --- | --- | --- | -| `content` | object | yes | | -| `nestingPolicy` | object | no | | -| `ref` | string | no | | -| `target` | object \\| TextAddress \\| SelectionTarget | no | One of: object, TextAddress, SelectionTarget | +_No fields._ ### Example request @@ -77,36 +65,14 @@ Returns an SDMutationReceipt with applied status; receipt reports NO_OP if the t | `evaluatedRevision.after` | string | no | | | `evaluatedRevision.before` | string | no | | | `resolution` | object | no | | -| `resolution.requestedTarget` | object | no | | -| `resolution.requestedTarget.anchor` | object | no | | -| `resolution.requestedTarget.anchor.end` | object | no | | -| `resolution.requestedTarget.anchor.end.blockId` | string | no | | -| `resolution.requestedTarget.anchor.end.offset` | integer | no | | -| `resolution.requestedTarget.anchor.start` | object | no | | -| `resolution.requestedTarget.anchor.start.blockId` | string | no | | -| `resolution.requestedTarget.anchor.start.offset` | integer | no | | -| `resolution.requestedTarget.evaluatedRevision` | string | no | | -| `resolution.requestedTarget.kind` | enum | no | `"content"`, `"inline"`, `"annotation"`, `"section"` | -| `resolution.requestedTarget.nodeId` | string | no | | -| `resolution.requestedTarget.path` | string \\| integer[] | no | | -| `resolution.requestedTarget.stability` | enum | no | `"stable"`, `"ephemeral"` | +| `resolution.range` | TextMutationRange | no | TextMutationRange | +| `resolution.range.from` | integer | no | | +| `resolution.range.to` | integer | no | | | `resolution.selectionTarget` | SelectionTarget | no | SelectionTarget | | `resolution.selectionTarget.end` | SelectionPoint | no | SelectionPoint | | `resolution.selectionTarget.kind` | `"selection"` | no | Constant: `"selection"` | | `resolution.selectionTarget.start` | SelectionPoint | no | SelectionPoint | -| `resolution.target` | object | no | | -| `resolution.target.anchor` | object | no | | -| `resolution.target.anchor.end` | object | no | | -| `resolution.target.anchor.end.blockId` | string | no | | -| `resolution.target.anchor.end.offset` | integer | no | | -| `resolution.target.anchor.start` | object | no | | -| `resolution.target.anchor.start.blockId` | string | no | | -| `resolution.target.anchor.start.offset` | integer | no | | -| `resolution.target.evaluatedRevision` | string | no | | -| `resolution.target.kind` | enum | no | `"content"`, `"inline"`, `"annotation"`, `"section"` | -| `resolution.target.nodeId` | string | no | | -| `resolution.target.path` | string \\| integer[] | no | | -| `resolution.target.stability` | enum | no | `"stable"`, `"ephemeral"` | +| `resolution.target` | TextAddress \\| BlockNodeAddress | no | One of: TextAddress, BlockNodeAddress | | `success` | `true` | yes | Constant: `true` | ### Variant 2 (resolution.selectionTarget.kind="selection") @@ -121,36 +87,14 @@ Returns an SDMutationReceipt with applied status; receipt reports NO_OP if the t | `failure.details` | any | no | | | `failure.message` | string | yes | | | `resolution` | object | no | | -| `resolution.requestedTarget` | object | no | | -| `resolution.requestedTarget.anchor` | object | no | | -| `resolution.requestedTarget.anchor.end` | object | no | | -| `resolution.requestedTarget.anchor.end.blockId` | string | no | | -| `resolution.requestedTarget.anchor.end.offset` | integer | no | | -| `resolution.requestedTarget.anchor.start` | object | no | | -| `resolution.requestedTarget.anchor.start.blockId` | string | no | | -| `resolution.requestedTarget.anchor.start.offset` | integer | no | | -| `resolution.requestedTarget.evaluatedRevision` | string | no | | -| `resolution.requestedTarget.kind` | enum | no | `"content"`, `"inline"`, `"annotation"`, `"section"` | -| `resolution.requestedTarget.nodeId` | string | no | | -| `resolution.requestedTarget.path` | string \\| integer[] | no | | -| `resolution.requestedTarget.stability` | enum | no | `"stable"`, `"ephemeral"` | +| `resolution.range` | TextMutationRange | no | TextMutationRange | +| `resolution.range.from` | integer | no | | +| `resolution.range.to` | integer | no | | | `resolution.selectionTarget` | SelectionTarget | no | SelectionTarget | | `resolution.selectionTarget.end` | SelectionPoint | no | SelectionPoint | | `resolution.selectionTarget.kind` | `"selection"` | no | Constant: `"selection"` | | `resolution.selectionTarget.start` | SelectionPoint | no | SelectionPoint | -| `resolution.target` | object | no | | -| `resolution.target.anchor` | object | no | | -| `resolution.target.anchor.end` | object | no | | -| `resolution.target.anchor.end.blockId` | string | no | | -| `resolution.target.anchor.end.offset` | integer | no | | -| `resolution.target.anchor.start` | object | no | | -| `resolution.target.anchor.start.blockId` | string | no | | -| `resolution.target.anchor.start.offset` | integer | no | | -| `resolution.target.evaluatedRevision` | string | no | | -| `resolution.target.kind` | enum | no | `"content"`, `"inline"`, `"annotation"`, `"section"` | -| `resolution.target.nodeId` | string | no | | -| `resolution.target.path` | string \\| integer[] | no | | -| `resolution.target.stability` | enum | no | `"stable"`, `"ephemeral"` | +| `resolution.target` | TextAddress \\| BlockNodeAddress | no | One of: TextAddress, BlockNodeAddress | | `success` | `false` | yes | Constant: `false` | ### Example response @@ -162,20 +106,9 @@ Returns an SDMutationReceipt with applied status; receipt reports NO_OP if the t "before": "example" }, "resolution": { - "requestedTarget": { - "anchor": { - "end": { - "blockId": "block-abc123", - "offset": 0 - }, - "start": { - "blockId": "block-abc123", - "offset": 0 - } - }, - "kind": "content", - "nodeId": "node-def456", - "stability": "stable" + "range": { + "from": 0, + "to": 10 }, "selectionTarget": { "end": { @@ -191,19 +124,12 @@ Returns an SDMutationReceipt with applied status; receipt reports NO_OP if the t } }, "target": { - "anchor": { - "end": { - "blockId": "block-abc123", - "offset": 0 - }, - "start": { - "blockId": "block-abc123", - "offset": 0 - } - }, - "kind": "content", - "nodeId": "node-def456", - "stability": "stable" + "blockId": "block-abc123", + "kind": "text", + "range": { + "end": 10, + "start": 0 + } } }, "success": true @@ -244,18 +170,35 @@ Returns an SDMutationReceipt with applied status; receipt reports NO_OP if the t { "oneOf": [ { - "allOf": [ + "oneOf": [ { - "$ref": "#/$defs/TargetLocator" + "additionalProperties": false, + "properties": { + "target": { + "$ref": "#/$defs/SelectionTarget" + }, + "text": { + "type": "string" + } + }, + "required": [ + "target", + "text" + ], + "type": "object" }, { "additionalProperties": false, "properties": { + "ref": { + "type": "string" + }, "text": { "type": "string" } }, "required": [ + "ref", "text" ], "type": "object" @@ -263,123 +206,7 @@ Returns an SDMutationReceipt with applied status; receipt reports NO_OP if the t ] }, { - "allOf": [ - { - "oneOf": [ - { - "additionalProperties": false, - "properties": { - "target": { - "oneOf": [ - { - "additionalProperties": false, - "properties": { - "anchor": { - "additionalProperties": false, - "properties": { - "end": { - "additionalProperties": false, - "properties": { - "blockId": { - "type": "string" - }, - "offset": { - "type": "integer" - } - }, - "required": [ - "blockId", - "offset" - ], - "type": "object" - }, - "start": { - "additionalProperties": false, - "properties": { - "blockId": { - "type": "string" - }, - "offset": { - "type": "integer" - } - }, - "required": [ - "blockId", - "offset" - ], - "type": "object" - } - }, - "type": "object" - }, - "evaluatedRevision": { - "type": "string" - }, - "kind": { - "enum": [ - "content", - "inline", - "annotation", - "section" - ] - }, - "nodeId": { - "type": "string" - }, - "path": { - "items": { - "oneOf": [ - { - "type": "string" - }, - { - "type": "integer" - } - ] - }, - "type": "array" - }, - "stability": { - "enum": [ - "stable", - "ephemeral" - ] - } - }, - "required": [ - "kind", - "stability" - ], - "type": "object" - }, - { - "$ref": "#/$defs/TextAddress" - }, - { - "$ref": "#/$defs/SelectionTarget" - } - ] - } - }, - "required": [ - "target" - ], - "type": "object" - }, - { - "additionalProperties": false, - "properties": { - "ref": { - "type": "string" - } - }, - "required": [ - "ref" - ], - "type": "object" - } - ] - }, + "oneOf": [ { "additionalProperties": false, "properties": { @@ -389,94 +216,10 @@ Returns an SDMutationReceipt with applied status; receipt reports NO_OP if the t "nestingPolicy": { "type": "object" }, - "ref": { - "type": "string" - }, "target": { "oneOf": [ { - "additionalProperties": false, - "properties": { - "anchor": { - "additionalProperties": false, - "properties": { - "end": { - "additionalProperties": false, - "properties": { - "blockId": { - "type": "string" - }, - "offset": { - "type": "integer" - } - }, - "required": [ - "blockId", - "offset" - ], - "type": "object" - }, - "start": { - "additionalProperties": false, - "properties": { - "blockId": { - "type": "string" - }, - "offset": { - "type": "integer" - } - }, - "required": [ - "blockId", - "offset" - ], - "type": "object" - } - }, - "type": "object" - }, - "evaluatedRevision": { - "type": "string" - }, - "kind": { - "enum": [ - "content", - "inline", - "annotation", - "section" - ] - }, - "nodeId": { - "type": "string" - }, - "path": { - "items": { - "oneOf": [ - { - "type": "string" - }, - { - "type": "integer" - } - ] - }, - "type": "array" - }, - "stability": { - "enum": [ - "stable", - "ephemeral" - ] - } - }, - "required": [ - "kind", - "stability" - ], - "type": "object" - }, - { - "$ref": "#/$defs/TextAddress" + "$ref": "#/$defs/BlockNodeAddress" }, { "$ref": "#/$defs/SelectionTarget" @@ -485,6 +228,26 @@ Returns an SDMutationReceipt with applied status; receipt reports NO_OP if the t } }, "required": [ + "target", + "content" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "content": { + "type": "object" + }, + "nestingPolicy": { + "type": "object" + }, + "ref": { + "type": "string" + } + }, + "required": [ + "ref", "content" ], "type": "object" @@ -522,174 +285,26 @@ Returns an SDMutationReceipt with applied status; receipt reports NO_OP if the t "resolution": { "additionalProperties": false, "properties": { - "requestedTarget": { - "additionalProperties": false, - "properties": { - "anchor": { - "additionalProperties": false, - "properties": { - "end": { - "additionalProperties": false, - "properties": { - "blockId": { - "type": "string" - }, - "offset": { - "type": "integer" - } - }, - "required": [ - "blockId", - "offset" - ], - "type": "object" - }, - "start": { - "additionalProperties": false, - "properties": { - "blockId": { - "type": "string" - }, - "offset": { - "type": "integer" - } - }, - "required": [ - "blockId", - "offset" - ], - "type": "object" - } - }, - "type": "object" - }, - "evaluatedRevision": { - "type": "string" - }, - "kind": { - "enum": [ - "content", - "inline", - "annotation", - "section" - ] - }, - "nodeId": { - "type": "string" - }, - "path": { - "items": { - "oneOf": [ - { - "type": "string" - }, - { - "type": "integer" - } - ] - }, - "type": "array" - }, - "stability": { - "enum": [ - "stable", - "ephemeral" - ] - } - }, - "required": [ - "kind", - "stability" - ], - "type": "object" + "range": { + "$ref": "#/$defs/TextMutationRange" }, "selectionTarget": { "$ref": "#/$defs/SelectionTarget" }, "target": { - "additionalProperties": false, - "properties": { - "anchor": { - "additionalProperties": false, - "properties": { - "end": { - "additionalProperties": false, - "properties": { - "blockId": { - "type": "string" - }, - "offset": { - "type": "integer" - } - }, - "required": [ - "blockId", - "offset" - ], - "type": "object" - }, - "start": { - "additionalProperties": false, - "properties": { - "blockId": { - "type": "string" - }, - "offset": { - "type": "integer" - } - }, - "required": [ - "blockId", - "offset" - ], - "type": "object" - } - }, - "type": "object" - }, - "evaluatedRevision": { - "type": "string" - }, - "kind": { - "enum": [ - "content", - "inline", - "annotation", - "section" - ] - }, - "nodeId": { - "type": "string" - }, - "path": { - "items": { - "oneOf": [ - { - "type": "string" - }, - { - "type": "integer" - } - ] - }, - "type": "array" + "oneOf": [ + { + "$ref": "#/$defs/TextAddress" }, - "stability": { - "enum": [ - "stable", - "ephemeral" - ] + { + "$ref": "#/$defs/BlockNodeAddress" } - }, - "required": [ - "kind", - "stability" - ], - "type": "object" + ] } }, "required": [ - "target" + "target", + "range" ], "type": "object" }, @@ -754,174 +369,26 @@ Returns an SDMutationReceipt with applied status; receipt reports NO_OP if the t "resolution": { "additionalProperties": false, "properties": { - "requestedTarget": { - "additionalProperties": false, - "properties": { - "anchor": { - "additionalProperties": false, - "properties": { - "end": { - "additionalProperties": false, - "properties": { - "blockId": { - "type": "string" - }, - "offset": { - "type": "integer" - } - }, - "required": [ - "blockId", - "offset" - ], - "type": "object" - }, - "start": { - "additionalProperties": false, - "properties": { - "blockId": { - "type": "string" - }, - "offset": { - "type": "integer" - } - }, - "required": [ - "blockId", - "offset" - ], - "type": "object" - } - }, - "type": "object" - }, - "evaluatedRevision": { - "type": "string" - }, - "kind": { - "enum": [ - "content", - "inline", - "annotation", - "section" - ] - }, - "nodeId": { - "type": "string" - }, - "path": { - "items": { - "oneOf": [ - { - "type": "string" - }, - { - "type": "integer" - } - ] - }, - "type": "array" - }, - "stability": { - "enum": [ - "stable", - "ephemeral" - ] - } - }, - "required": [ - "kind", - "stability" - ], - "type": "object" + "range": { + "$ref": "#/$defs/TextMutationRange" }, "selectionTarget": { "$ref": "#/$defs/SelectionTarget" }, "target": { - "additionalProperties": false, - "properties": { - "anchor": { - "additionalProperties": false, - "properties": { - "end": { - "additionalProperties": false, - "properties": { - "blockId": { - "type": "string" - }, - "offset": { - "type": "integer" - } - }, - "required": [ - "blockId", - "offset" - ], - "type": "object" - }, - "start": { - "additionalProperties": false, - "properties": { - "blockId": { - "type": "string" - }, - "offset": { - "type": "integer" - } - }, - "required": [ - "blockId", - "offset" - ], - "type": "object" - } - }, - "type": "object" - }, - "evaluatedRevision": { - "type": "string" - }, - "kind": { - "enum": [ - "content", - "inline", - "annotation", - "section" - ] - }, - "nodeId": { - "type": "string" - }, - "path": { - "items": { - "oneOf": [ - { - "type": "string" - }, - { - "type": "integer" - } - ] - }, - "type": "array" + "oneOf": [ + { + "$ref": "#/$defs/TextAddress" }, - "stability": { - "enum": [ - "stable", - "ephemeral" - ] + { + "$ref": "#/$defs/BlockNodeAddress" } - }, - "required": [ - "kind", - "stability" - ], - "type": "object" + ] } }, "required": [ - "target" + "target", + "range" ], "type": "object" }, @@ -964,174 +431,26 @@ Returns an SDMutationReceipt with applied status; receipt reports NO_OP if the t "resolution": { "additionalProperties": false, "properties": { - "requestedTarget": { - "additionalProperties": false, - "properties": { - "anchor": { - "additionalProperties": false, - "properties": { - "end": { - "additionalProperties": false, - "properties": { - "blockId": { - "type": "string" - }, - "offset": { - "type": "integer" - } - }, - "required": [ - "blockId", - "offset" - ], - "type": "object" - }, - "start": { - "additionalProperties": false, - "properties": { - "blockId": { - "type": "string" - }, - "offset": { - "type": "integer" - } - }, - "required": [ - "blockId", - "offset" - ], - "type": "object" - } - }, - "type": "object" - }, - "evaluatedRevision": { - "type": "string" - }, - "kind": { - "enum": [ - "content", - "inline", - "annotation", - "section" - ] - }, - "nodeId": { - "type": "string" - }, - "path": { - "items": { - "oneOf": [ - { - "type": "string" - }, - { - "type": "integer" - } - ] - }, - "type": "array" - }, - "stability": { - "enum": [ - "stable", - "ephemeral" - ] - } - }, - "required": [ - "kind", - "stability" - ], - "type": "object" + "range": { + "$ref": "#/$defs/TextMutationRange" }, "selectionTarget": { "$ref": "#/$defs/SelectionTarget" }, "target": { - "additionalProperties": false, - "properties": { - "anchor": { - "additionalProperties": false, - "properties": { - "end": { - "additionalProperties": false, - "properties": { - "blockId": { - "type": "string" - }, - "offset": { - "type": "integer" - } - }, - "required": [ - "blockId", - "offset" - ], - "type": "object" - }, - "start": { - "additionalProperties": false, - "properties": { - "blockId": { - "type": "string" - }, - "offset": { - "type": "integer" - } - }, - "required": [ - "blockId", - "offset" - ], - "type": "object" - } - }, - "type": "object" - }, - "evaluatedRevision": { - "type": "string" - }, - "kind": { - "enum": [ - "content", - "inline", - "annotation", - "section" - ] - }, - "nodeId": { - "type": "string" - }, - "path": { - "items": { - "oneOf": [ - { - "type": "string" - }, - { - "type": "integer" - } - ] - }, - "type": "array" + "oneOf": [ + { + "$ref": "#/$defs/TextAddress" }, - "stability": { - "enum": [ - "stable", - "ephemeral" - ] + { + "$ref": "#/$defs/BlockNodeAddress" } - }, - "required": [ - "kind", - "stability" - ], - "type": "object" + ] } }, "required": [ - "target" + "target", + "range" ], "type": "object" }, @@ -1201,174 +520,26 @@ Returns an SDMutationReceipt with applied status; receipt reports NO_OP if the t "resolution": { "additionalProperties": false, "properties": { - "requestedTarget": { - "additionalProperties": false, - "properties": { - "anchor": { - "additionalProperties": false, - "properties": { - "end": { - "additionalProperties": false, - "properties": { - "blockId": { - "type": "string" - }, - "offset": { - "type": "integer" - } - }, - "required": [ - "blockId", - "offset" - ], - "type": "object" - }, - "start": { - "additionalProperties": false, - "properties": { - "blockId": { - "type": "string" - }, - "offset": { - "type": "integer" - } - }, - "required": [ - "blockId", - "offset" - ], - "type": "object" - } - }, - "type": "object" - }, - "evaluatedRevision": { - "type": "string" - }, - "kind": { - "enum": [ - "content", - "inline", - "annotation", - "section" - ] - }, - "nodeId": { - "type": "string" - }, - "path": { - "items": { - "oneOf": [ - { - "type": "string" - }, - { - "type": "integer" - } - ] - }, - "type": "array" - }, - "stability": { - "enum": [ - "stable", - "ephemeral" - ] - } - }, - "required": [ - "kind", - "stability" - ], - "type": "object" + "range": { + "$ref": "#/$defs/TextMutationRange" }, "selectionTarget": { "$ref": "#/$defs/SelectionTarget" }, "target": { - "additionalProperties": false, - "properties": { - "anchor": { - "additionalProperties": false, - "properties": { - "end": { - "additionalProperties": false, - "properties": { - "blockId": { - "type": "string" - }, - "offset": { - "type": "integer" - } - }, - "required": [ - "blockId", - "offset" - ], - "type": "object" - }, - "start": { - "additionalProperties": false, - "properties": { - "blockId": { - "type": "string" - }, - "offset": { - "type": "integer" - } - }, - "required": [ - "blockId", - "offset" - ], - "type": "object" - } - }, - "type": "object" - }, - "evaluatedRevision": { - "type": "string" - }, - "kind": { - "enum": [ - "content", - "inline", - "annotation", - "section" - ] - }, - "nodeId": { - "type": "string" - }, - "path": { - "items": { - "oneOf": [ - { - "type": "string" - }, - { - "type": "integer" - } - ] - }, - "type": "array" + "oneOf": [ + { + "$ref": "#/$defs/TextAddress" }, - "stability": { - "enum": [ - "stable", - "ephemeral" - ] + { + "$ref": "#/$defs/BlockNodeAddress" } - }, - "required": [ - "kind", - "stability" - ], - "type": "object" + ] } }, "required": [ - "target" + "target", + "range" ], "type": "object" }, diff --git a/apps/docs/document-engine/sdks.mdx b/apps/docs/document-engine/sdks.mdx index edb0cb2a57..65ea0d3cf2 100644 --- a/apps/docs/document-engine/sdks.mdx +++ b/apps/docs/document-engine/sdks.mdx @@ -367,7 +367,7 @@ The SDKs expose all operations from the [Document API](/document-api/overview) p | Operation | CLI command | Description | | --- | --- | --- | | `doc.get` | `get` | Read the full document as an SDDocument structure. | -| `doc.find` | `find` | Search the document for text or node matches using SDM/1 selectors. | +| `doc.find` | `find` | Search the document for text or node matches using SDM/1 selectors. Returns discovery-grade results — for mutation targeting, use query.match instead. | | `doc.getNode` | `get-node` | Retrieve a single node by target position. | | `doc.getNodeById` | `get-node-by-id` | Retrieve a single node by its unique ID. | | `doc.getText` | `get-text` | Extract the plain-text content of the document. | @@ -376,11 +376,14 @@ The SDKs expose all operations from the [Document API](/document-api/overview) p | `doc.markdownToFragment` | `markdown-to-fragment` | Convert a Markdown string into an SDM/1 structural fragment. | | `doc.info` | `info` | Return document metadata including revision, node count, and capabilities. | | `doc.clearContent` | `clear-content` | Clear all document body content, leaving a single empty paragraph. | -| `doc.insert` | `insert` | Insert content at a target position, or at the end of the document when target is omitted. Accepts two input shapes: legacy string-based (value + type) or structural SDFragment (content). Supports text (default), markdown, and html content types via the `type` field in legacy mode. Structural mode accepts an SDFragment with typed nodes (paragraphs, tables, images, etc.). | -| `doc.replace` | `replace` | Replace content at a target position with new content. Accepts two input shapes: legacy string-based (text) or structural SDFragment (content). Structural mode replaces the target range with typed nodes (paragraphs, tables, images, etc.). | -| `doc.delete` | `delete` | Delete content at a target position. | +| `doc.insert` | `insert` | Insert content into the document. Two input shapes: legacy string-based (value + type) inserts inline content at a text position within an existing block; structural SDFragment (content) inserts one or more blocks as siblings relative to a BlockNodeAddress target. When target is omitted, content appends at the end of the document. Legacy mode supports text (default), markdown, and html content types via the `type` field. Structural mode uses `placement` (before/after/insideStart/insideEnd) to position relative to the target block. | +| `doc.replace` | `replace` | Replace content at a contiguous document selection. Text path accepts a SelectionTarget or ref plus replacement text. Structural path accepts a BlockNodeAddress (replaces whole block), SelectionTarget (expands to full covered block boundaries), or ref plus SDFragment content. | +| `doc.delete` | `delete` | Delete content at a contiguous document selection. Accepts a SelectionTarget or mutation-ready ref. Supports cross-block deletion and optional block-edge expansion via behavior mode. | +| `doc.blocks.list` | `blocks list` | List top-level blocks in document order with IDs, types, and text previews. Supports pagination via offset/limit and optional nodeType filtering. | | `doc.blocks.delete` | `blocks delete` | Delete an entire block node (paragraph, heading, list item, table, image, or sdt) deterministically. | -| `doc.query.match` | `query match` | Deterministic selector-based search with cardinality contracts for mutation targeting. | +| `doc.blocks.deleteRange` | `blocks delete-range` | Delete a contiguous range of top-level blocks between two endpoints (inclusive). Both endpoints must be direct children of the document node. Supports dry-run preview. | +| `doc.query.match` | `query match` | Deterministic selector-based search returning mutation-grade addresses and text ranges. Use this to discover targets before any mutation. | +| `doc.ranges.resolve` | `ranges resolve` | Resolve two explicit anchors into a contiguous document range. Returns a transparent SelectionTarget, a mutation-ready ref, and preview metadata. Stateless and deterministic. | | `doc.mutations.preview` | `mutations preview` | Dry-run a mutation plan, returning resolved targets without applying changes. | | `doc.mutations.apply` | `mutations apply` | Execute a mutation plan atomically against the document. | | `doc.capabilities.get` | `capabilities` | Query runtime capabilities supported by the current document engine. | @@ -592,7 +595,7 @@ The SDKs expose all operations from the [Document API](/document-api/overview) p | Operation | CLI command | Description | | --- | --- | --- | -| `doc.create.paragraph` | `create paragraph` | Create a new paragraph at the target position. | +| `doc.create.paragraph` | `create paragraph` | Create a standalone paragraph at the target position. To add a list item, use lists.insert instead. | | `doc.create.heading` | `create heading` | Create a new heading at the target position. | | `doc.create.sectionBreak` | `create section-break` | Create a section break at the target location with optional initial section properties. | | `doc.create.table` | `create table` | Create a new table at the target position. | @@ -628,7 +631,7 @@ The SDKs expose all operations from the [Document API](/document-api/overview) p | --- | --- | --- | | `doc.lists.list` | `lists list` | List all list nodes in the document, optionally filtered by scope. | | `doc.lists.get` | `lists get` | Retrieve a specific list node by target. | -| `doc.lists.insert` | `lists insert` | Insert a new list at the target position. | +| `doc.lists.insert` | `lists insert` | Insert a new list item before or after an existing list item. The new item inherits the target list context. | | `doc.lists.create` | `lists create` | Create a new list from one or more paragraphs, or convert existing paragraphs into a new list. | | `doc.lists.attach` | `lists attach` | Convert non-list paragraphs to list items under an existing list sequence. | | `doc.lists.detach` | `lists detach` | Remove numbering properties from list items, converting them to plain paragraphs. | @@ -799,7 +802,7 @@ The SDKs expose all operations from the [Document API](/document-api/overview) p | Operation | CLI command | Description | | --- | --- | --- | | `doc.get` | `get` | Read the full document as an SDDocument structure. | -| `doc.find` | `find` | Search the document for text or node matches using SDM/1 selectors. | +| `doc.find` | `find` | Search the document for text or node matches using SDM/1 selectors. Returns discovery-grade results — for mutation targeting, use query.match instead. | | `doc.get_node` | `get-node` | Retrieve a single node by target position. | | `doc.get_node_by_id` | `get-node-by-id` | Retrieve a single node by its unique ID. | | `doc.get_text` | `get-text` | Extract the plain-text content of the document. | @@ -808,11 +811,14 @@ The SDKs expose all operations from the [Document API](/document-api/overview) p | `doc.markdown_to_fragment` | `markdown-to-fragment` | Convert a Markdown string into an SDM/1 structural fragment. | | `doc.info` | `info` | Return document metadata including revision, node count, and capabilities. | | `doc.clear_content` | `clear-content` | Clear all document body content, leaving a single empty paragraph. | -| `doc.insert` | `insert` | Insert content at a target position, or at the end of the document when target is omitted. Accepts two input shapes: legacy string-based (value + type) or structural SDFragment (content). Supports text (default), markdown, and html content types via the `type` field in legacy mode. Structural mode accepts an SDFragment with typed nodes (paragraphs, tables, images, etc.). | -| `doc.replace` | `replace` | Replace content at a target position with new content. Accepts two input shapes: legacy string-based (text) or structural SDFragment (content). Structural mode replaces the target range with typed nodes (paragraphs, tables, images, etc.). | -| `doc.delete` | `delete` | Delete content at a target position. | +| `doc.insert` | `insert` | Insert content into the document. Two input shapes: legacy string-based (value + type) inserts inline content at a text position within an existing block; structural SDFragment (content) inserts one or more blocks as siblings relative to a BlockNodeAddress target. When target is omitted, content appends at the end of the document. Legacy mode supports text (default), markdown, and html content types via the `type` field. Structural mode uses `placement` (before/after/insideStart/insideEnd) to position relative to the target block. | +| `doc.replace` | `replace` | Replace content at a contiguous document selection. Text path accepts a SelectionTarget or ref plus replacement text. Structural path accepts a BlockNodeAddress (replaces whole block), SelectionTarget (expands to full covered block boundaries), or ref plus SDFragment content. | +| `doc.delete` | `delete` | Delete content at a contiguous document selection. Accepts a SelectionTarget or mutation-ready ref. Supports cross-block deletion and optional block-edge expansion via behavior mode. | +| `doc.blocks.list` | `blocks list` | List top-level blocks in document order with IDs, types, and text previews. Supports pagination via offset/limit and optional nodeType filtering. | | `doc.blocks.delete` | `blocks delete` | Delete an entire block node (paragraph, heading, list item, table, image, or sdt) deterministically. | -| `doc.query.match` | `query match` | Deterministic selector-based search with cardinality contracts for mutation targeting. | +| `doc.blocks.delete_range` | `blocks delete-range` | Delete a contiguous range of top-level blocks between two endpoints (inclusive). Both endpoints must be direct children of the document node. Supports dry-run preview. | +| `doc.query.match` | `query match` | Deterministic selector-based search returning mutation-grade addresses and text ranges. Use this to discover targets before any mutation. | +| `doc.ranges.resolve` | `ranges resolve` | Resolve two explicit anchors into a contiguous document range. Returns a transparent SelectionTarget, a mutation-ready ref, and preview metadata. Stateless and deterministic. | | `doc.mutations.preview` | `mutations preview` | Dry-run a mutation plan, returning resolved targets without applying changes. | | `doc.mutations.apply` | `mutations apply` | Execute a mutation plan atomically against the document. | | `doc.capabilities.get` | `capabilities` | Query runtime capabilities supported by the current document engine. | @@ -1024,7 +1030,7 @@ The SDKs expose all operations from the [Document API](/document-api/overview) p | Operation | CLI command | Description | | --- | --- | --- | -| `doc.create.paragraph` | `create paragraph` | Create a new paragraph at the target position. | +| `doc.create.paragraph` | `create paragraph` | Create a standalone paragraph at the target position. To add a list item, use lists.insert instead. | | `doc.create.heading` | `create heading` | Create a new heading at the target position. | | `doc.create.section_break` | `create section-break` | Create a section break at the target location with optional initial section properties. | | `doc.create.table` | `create table` | Create a new table at the target position. | @@ -1060,7 +1066,7 @@ The SDKs expose all operations from the [Document API](/document-api/overview) p | --- | --- | --- | | `doc.lists.list` | `lists list` | List all list nodes in the document, optionally filtered by scope. | | `doc.lists.get` | `lists get` | Retrieve a specific list node by target. | -| `doc.lists.insert` | `lists insert` | Insert a new list at the target position. | +| `doc.lists.insert` | `lists insert` | Insert a new list item before or after an existing list item. The new item inherits the target list context. | | `doc.lists.create` | `lists create` | Create a new list from one or more paragraphs, or convert existing paragraphs into a new list. | | `doc.lists.attach` | `lists attach` | Convert non-list paragraphs to list items under an existing list sequence. | | `doc.lists.detach` | `lists detach` | Remove numbering properties from list items, converting them to plain paragraphs. | diff --git a/packages/document-api/scripts/lib/contract-output-artifacts.ts b/packages/document-api/scripts/lib/contract-output-artifacts.ts index b314a1a101..e5ef87ba57 100644 --- a/packages/document-api/scripts/lib/contract-output-artifacts.ts +++ b/packages/document-api/scripts/lib/contract-output-artifacts.ts @@ -113,7 +113,7 @@ const DEFAULT_REMEDIATION_BY_CODE: Record = { // SDM/1 structural codes INVALID_PAYLOAD: 'Check fragment structure: every node needs a valid kind and required payload fields.', CAPABILITY_UNSUPPORTED: 'This node kind or operation is not supported by the current engine. Check capabilities.', - ADDRESS_STALE: 'The SDAddress was obtained before a mutation and is no longer valid. Re-resolve the address.', + ADDRESS_STALE: 'The address was obtained before a mutation and is no longer valid. Re-resolve the address.', DUPLICATE_ID: 'A node ID in the fragment conflicts with an existing document node. Use unique IDs or omit them.', INVALID_CONTEXT: 'The target context does not allow this content (e.g., inserting block content inside an inline context).', diff --git a/packages/document-api/src/README.md b/packages/document-api/src/README.md index 4bda4d3807..4310ba89b9 100644 --- a/packages/document-api/src/README.md +++ b/packages/document-api/src/README.md @@ -37,12 +37,12 @@ lives in adapter layers that map engine behavior into discovery envelopes and ot ## Selector Semantics - For dual-context types (`sdt`, `image`), selectors without an explicit `kind` may return both block and inline matches. -- For `find`, set `kind: 'content'` or `kind: 'inline'` on `{ type: 'node' }` selectors when you need only one context. +- For `find`, set `kind: 'block'` or `kind: 'inline'` on `{ type: 'node' }` selectors when you need only one context. ## Find Result Contract - `find` always returns `SDFindResult` with `items: SDNodeResult[]`. -- Each item has `{ node, address }`, where `address` is an `SDAddress`. +- Each item has `{ node, address }`, where `address` is a `NodeAddress`. - For precise text spans/runs (for direct mutation targeting), use `query.match`, which returns `blocks[].range` and run-level metadata. - `insert` supports canonical `TextAddress` targeting or default insertion point when target is omitted. - Structural creation is exposed under `create.*` (for example `create.paragraph`), separate from text mutations. diff --git a/packages/document-api/src/contract/operation-definitions.ts b/packages/document-api/src/contract/operation-definitions.ts index 1b29ba994f..899a55378e 100644 --- a/packages/document-api/src/contract/operation-definitions.ts +++ b/packages/document-api/src/contract/operation-definitions.ts @@ -376,11 +376,12 @@ export const OPERATION_DEFINITIONS = { insert: { memberPath: 'insert', description: - 'Insert inline content at a text position within an existing block, or at the end of the document when target is omitted. ' + - 'This is NOT for creating sibling blocks — use create.paragraph, create.heading, or lists.insert for that. ' + - 'Accepts two input shapes: legacy string-based (value + type) or structural SDFragment (content). ' + - 'Supports text (default), markdown, and html content types via the `type` field in legacy mode. ' + - 'Structural mode accepts an SDFragment with typed nodes (paragraphs, tables, images, etc.).', + 'Insert content into the document. Two input shapes: ' + + 'legacy string-based (value + type) inserts inline content at a text position within an existing block; ' + + 'structural SDFragment (content) inserts one or more blocks as siblings relative to a BlockNodeAddress target. ' + + 'When target is omitted, content appends at the end of the document. ' + + 'Legacy mode supports text (default), markdown, and html content types via the `type` field. ' + + 'Structural mode uses `placement` (before/after/insideStart/insideEnd) to position relative to the target block.', expectedResult: 'Returns a TextMutationReceipt with applied status; receipt reports NO_OP if the insertion point is invalid or content is empty.', requiresDocumentContext: true, @@ -423,7 +424,7 @@ export const OPERATION_DEFINITIONS = { description: 'Replace content at a contiguous document selection. ' + 'Text path accepts a SelectionTarget or ref plus replacement text. ' + - 'Structural path accepts an SDAddress, SelectionTarget, or ref plus SDFragment content.', + 'Structural path accepts a BlockNodeAddress (replaces whole block), SelectionTarget (expands to full covered block boundaries), or ref plus SDFragment content.', expectedResult: 'Returns an SDMutationReceipt with applied status; receipt reports NO_OP if the target range already contains identical content.', requiresDocumentContext: true, diff --git a/packages/document-api/src/contract/schemas.ts b/packages/document-api/src/contract/schemas.ts index 413497f508..6f5ffc6e55 100644 --- a/packages/document-api/src/contract/schemas.ts +++ b/packages/document-api/src/contract/schemas.ts @@ -807,8 +807,8 @@ const sdTextSelectorSchema = objectSchema( const sdNodeSelectorSchema = objectSchema( { type: { const: 'node' }, - kind: { enum: ['content', 'inline'] }, - nodeKind: { type: 'string' }, + kind: { enum: ['block', 'inline'] }, + nodeType: { type: 'string' }, }, ['type'], ); @@ -817,20 +817,7 @@ const sdSelectorSchema: JsonSchema = { oneOf: [sdTextSelectorSchema, sdNodeSelectorSchema], }; -const sdAddressSchema = objectSchema( - { - kind: { enum: ['content', 'inline', 'annotation', 'section'] }, - stability: { enum: ['stable', 'ephemeral'] }, - nodeId: { type: 'string' }, - anchor: objectSchema({ - start: objectSchema({ blockId: { type: 'string' }, offset: { type: 'integer' } }, ['blockId', 'offset']), - end: objectSchema({ blockId: { type: 'string' }, offset: { type: 'integer' } }, ['blockId', 'offset']), - }), - evaluatedRevision: { type: 'string' }, - path: arraySchema({ oneOf: [{ type: 'string' }, { type: 'integer' }] }), - }, - ['kind', 'stability'], -); +// sdAddressSchema removed — replaced by blockNodeAddressSchema, nodeAddressSchema, textAddressSchema const sdReadOptionsSchema = objectSchema({ includeResolved: { type: 'boolean' }, @@ -841,7 +828,7 @@ const sdReadOptionsSchema = objectSchema({ const sdFindInputSchema = objectSchema( { select: sdSelectorSchema, - within: sdAddressSchema, + within: blockNodeAddressSchema, limit: { type: 'integer' }, offset: { type: 'integer' }, options: sdReadOptionsSchema, @@ -852,7 +839,7 @@ const sdFindInputSchema = objectSchema( const sdNodeResultSchema = objectSchema( { node: { type: 'object' }, - address: sdAddressSchema, + address: nodeAddressSchema, context: { type: 'object' }, }, ['node', 'address'], @@ -874,11 +861,11 @@ const sdFindResultSchema = objectSchema( const sdMutationResolutionSchema = objectSchema( { - requestedTarget: sdAddressSchema, - target: sdAddressSchema, + target: { oneOf: [textAddressSchema, blockNodeAddressSchema] }, + range: textMutationRangeSchema, selectionTarget: selectionTargetSchema, }, - ['target'], + ['target', 'range'], ); const sdMutationSuccessSchema = objectSchema( @@ -2589,7 +2576,7 @@ const operationSchemas: Record = { oneOf: [ objectSchema( { - target: { oneOf: [sdAddressSchema, textAddressSchema, selectionTargetSchema] }, + target: { oneOf: [blockNodeAddressSchema, selectionTargetSchema] }, content: { type: 'object' }, nestingPolicy: { type: 'object' }, }, @@ -3923,7 +3910,7 @@ const operationSchemas: Record = { input: objectSchema( { select: { oneOf: [textSelectorSchema, nodeSelectorSchema] }, - within: nodeAddressSchema, + within: blockNodeAddressSchema, require: { enum: ['any', 'first', 'exactlyOne', 'all'] }, mode: { enum: ['strict', 'candidates'] }, includeNodes: { type: 'boolean' }, @@ -3941,7 +3928,7 @@ const operationSchemas: Record = { const textMatchItemSchema = discoveryItemSchema( { matchKind: { const: 'text' }, - address: nodeAddressSchema, + address: blockNodeAddressSchema, target: selectionTargetSchema, snippet: { type: 'string' }, highlightRange: rangeSchema, @@ -3976,7 +3963,7 @@ const operationSchemas: Record = { { by: { const: 'select', type: 'string' }, select: { oneOf: [textSelectorSchema, nodeSelectorSchema] }, - within: nodeAddressSchema, + within: blockNodeAddressSchema, require: { enum: ['first', 'exactlyOne', 'all'] }, }, ['by', 'select', 'require'], @@ -3986,7 +3973,7 @@ const operationSchemas: Record = { { by: { const: 'ref', type: 'string' }, ref: { type: 'string' }, - within: nodeAddressSchema, + within: blockNodeAddressSchema, }, ['by', 'ref'], ); @@ -4006,7 +3993,7 @@ const operationSchemas: Record = { { by: { const: 'select', type: 'string' }, select: { oneOf: [textSelectorSchema, nodeSelectorSchema] }, - within: nodeAddressSchema, + within: blockNodeAddressSchema, require: { enum: ['first', 'exactlyOne'] }, }, ['by', 'select', 'require'], @@ -4017,7 +4004,7 @@ const operationSchemas: Record = { { by: { const: 'select', type: 'string' }, select: { oneOf: [textSelectorSchema, nodeSelectorSchema] }, - within: nodeAddressSchema, + within: blockNodeAddressSchema, }, ['by', 'select'], ); @@ -5564,7 +5551,7 @@ const operationSchemas: Record = { // --- hyperlinks.* --- 'hyperlinks.list': { input: objectSchema({ - within: nodeAddressSchema, + within: blockNodeAddressSchema, hrefPattern: { type: 'string' }, anchor: { type: 'string' }, textPattern: { type: 'string' }, diff --git a/packages/document-api/src/find/find.test.ts b/packages/document-api/src/find/find.test.ts index 5b81dcaad2..1c34d8303c 100644 --- a/packages/document-api/src/find/find.test.ts +++ b/packages/document-api/src/find/find.test.ts @@ -169,7 +169,7 @@ describe('executeFind', () => { }; const adapter: FindAdapter = { find: vi.fn(() => sdResult) }; const input: SDFindInput = { - select: { type: 'node', nodeKind: 'paragraph' }, + select: { type: 'node', nodeType: 'paragraph' }, limit: 5, }; diff --git a/packages/document-api/src/find/find.ts b/packages/document-api/src/find/find.ts index 0e0c8295a7..1fa5d92e55 100644 --- a/packages/document-api/src/find/find.ts +++ b/packages/document-api/src/find/find.ts @@ -1,5 +1,6 @@ -import type { NodeAddress, NodeSelector, Query, FindOutput, Selector, TextSelector } from '../types/index.js'; +import type { BlockNodeAddress, NodeSelector, Query, FindOutput, Selector, TextSelector } from '../types/index.js'; import type { SDFindInput, SDFindResult } from '../types/sd-envelope.js'; +import { DocumentApiValidationError } from '../errors.js'; /** * Options for the `find` method when using a selector shorthand. @@ -9,8 +10,8 @@ export interface FindOptions { limit?: number; /** Number of results to skip before returning matches. */ offset?: number; - /** Constrain the search to descendants of the specified node. */ - within?: NodeAddress; + /** Constrain the search to descendants of the specified block node. */ + within?: BlockNodeAddress; /** Cardinality requirement for the result set. */ require?: Query['require']; /** Whether to hydrate `result.nodes` for matched addresses. */ @@ -43,7 +44,8 @@ export interface FindAdapter { /** Normalizes a selector shorthand into its canonical discriminated-union form. * Strips any non-selector properties so callers that pass an object with extra - * fields (e.g. SDK-shaped flat params) don't pollute the select object. */ + * fields (e.g. SDK-shaped flat params) don't pollute the select object. + * Rejects legacy `nodeKind` and `kind: 'content'` vocabulary with actionable errors. */ function normalizeSelector(selector: Selector): NodeSelector | TextSelector { if ('type' in selector) { if (selector.type === 'text') { @@ -56,6 +58,22 @@ function normalizeSelector(selector: Selector): NodeSelector | TextSelector { }; } if (selector.type === 'node') { + const raw = selector as unknown as Record; + if ('nodeKind' in raw && raw.nodeKind != null) { + throw new DocumentApiValidationError( + 'INVALID_INPUT', + `"nodeKind" is no longer supported on node selectors. Use "nodeType" instead: ` + + `{ type: 'node', nodeType: '${String(raw.nodeKind)}' }.`, + { field: 'select.nodeKind', value: raw.nodeKind }, + ); + } + if (raw.kind === 'content') { + throw new DocumentApiValidationError( + 'INVALID_INPUT', + `kind: 'content' is no longer supported on node selectors. Use kind: 'block' instead.`, + { field: 'select.kind', value: raw.kind }, + ); + } const node = selector as NodeSelector; return { type: 'node', diff --git a/packages/document-api/src/hyperlinks/hyperlinks.types.ts b/packages/document-api/src/hyperlinks/hyperlinks.types.ts index 61c11a7c37..20d6bdfba4 100644 --- a/packages/document-api/src/hyperlinks/hyperlinks.types.ts +++ b/packages/document-api/src/hyperlinks/hyperlinks.types.ts @@ -1,4 +1,4 @@ -import type { InlineNodeAddress, NodeAddress } from '../types/base.js'; +import type { BlockNodeAddress, InlineNodeAddress, NodeAddress } from '../types/base.js'; import type { TextAddress } from '../types/address.js'; import type { DiscoveryOutput } from '../types/discovery.js'; import type { ReceiptFailure } from '../types/receipt.js'; @@ -121,7 +121,7 @@ export type HyperlinksListResult = DiscoveryOutput; // --------------------------------------------------------------------------- export interface HyperlinksListQuery { - within?: NodeAddress; + within?: BlockNodeAddress; hrefPattern?: string; anchor?: string; textPattern?: string; diff --git a/packages/document-api/src/index.test.ts b/packages/document-api/src/index.test.ts index 21ddd305ce..d36a261011 100644 --- a/packages/document-api/src/index.test.ts +++ b/packages/document-api/src/index.test.ts @@ -112,10 +112,9 @@ function makeWriteAdapter(): WriteAdapter { success: true as const, resolution: { target: { - kind: 'content' as const, - stability: 'stable' as const, - nodeId: 'p1', - anchor: { start: { blockId: 'p1', offset: 0 }, end: { blockId: 'p1', offset: 0 } }, + kind: 'text' as const, + blockId: 'p1', + range: { start: 0, end: 0 }, }, }, }; @@ -356,7 +355,7 @@ const PARAGRAPH_ADDRESS: NodeAddress = { kind: 'block', nodeType: 'paragraph', n const PARAGRAPH_NODE_RESULT: SDNodeResult = { node: { kind: 'paragraph', paragraph: { inlines: [] } }, - address: { kind: 'content', stability: 'stable', nodeId: 'p1' }, + address: { kind: 'block', nodeType: 'paragraph', nodeId: 'p1' }, }; const FIND_RESULT: SDFindResult = { @@ -383,7 +382,7 @@ describe('createDocumentApi', () => { lists: makeListsAdapter(), }); - const input = { select: { type: 'node' as const, nodeKind: 'paragraph' } }; + const input = { select: { type: 'node' as const, nodeType: 'paragraph' as const } }; const result = api.find(input); expect(result).toEqual(FIND_RESULT); @@ -1656,7 +1655,7 @@ describe('createDocumentApi', () => { lists: makeListsAdapter(), }); - const sdTarget = { kind: 'content' as const, stability: 'stable' as const, nodeId: 'p1' }; + const sdTarget = { kind: 'block' as const, nodeType: 'paragraph' as const, nodeId: 'p1' }; api.replace({ target: sdTarget, content: { type: 'paragraph', content: [{ type: 'text', text: 'new' }] } }); expect(writeAdpt.replaceStructured).toHaveBeenCalledTimes(1); expect(writeAdpt.write).not.toHaveBeenCalled(); @@ -1664,13 +1663,13 @@ describe('createDocumentApi', () => { it('rejects structural replace with empty fragment', () => { const api = makeApi(); - const sdTarget = { kind: 'content' as const, stability: 'stable' as const, nodeId: 'p1' }; + const sdTarget = { kind: 'block' as const, nodeType: 'paragraph' as const, nodeId: 'p1' }; expect(() => api.replace({ target: sdTarget, content: [] } as any)).toThrow(/at least one node/); }); it('rejects structural replace with invalid nestingPolicy.tables', () => { const api = makeApi(); - const sdTarget = { kind: 'content' as const, stability: 'stable' as const, nodeId: 'p1' }; + const sdTarget = { kind: 'block' as const, nodeType: 'paragraph' as const, nodeId: 'p1' }; expect(() => api.replace({ target: sdTarget, content: { type: 'paragraph' }, nestingPolicy: { tables: 'yes' } } as any), ).toThrow(/nestingPolicy\.tables must be one of/); diff --git a/packages/document-api/src/index.ts b/packages/document-api/src/index.ts index 3b6b766f2a..6cb6a2e691 100644 --- a/packages/document-api/src/index.ts +++ b/packages/document-api/src/index.ts @@ -45,6 +45,8 @@ import type { Query, QueryMatchInput, QueryMatchOutput, + TextSelector, + NodeSelector, FindOutput, Receipt, Selector, @@ -1275,8 +1277,9 @@ export type { } from './comments/comments.js'; export type { CommentInfo, CommentsListQuery, CommentsListResult } from './comments/comments.types.js'; export { DocumentApiValidationError, toSDError } from './errors.js'; -export { textReceiptToSDReceipt } from './receipt-bridge.js'; -export { isSDAddress, isValidTarget } from './validation-primitives.js'; +export { textReceiptToSDReceipt, buildStructuralReceipt } from './receipt-bridge.js'; +export type { StructuralReceiptParams } from './receipt-bridge.js'; +export { isBlockNodeAddress } from './validation-primitives.js'; export type { InsertInput, InsertContentType, LegacyInsertInput } from './insert/insert.js'; export { isStructuralInsertInput } from './insert/insert.js'; export type { ReplaceInput, TextReplaceInput } from './replace/replace.js'; @@ -1342,7 +1345,10 @@ export interface CapabilitiesApi { } export interface QueryApi { + /** Canonical nested input. */ match(input: QueryMatchInput): QueryMatchOutput; + /** TS shorthand: pass a TextSelector or NodeSelector directly (normalized to `{ select: ... }` internally). */ + match(selector: TextSelector | NodeSelector): QueryMatchOutput; } export interface MutationsApi { @@ -2776,8 +2782,17 @@ export function createDocumentApi(adapters: DocumentApiAdapters): DocumentApi { }, }, query: { - match(input: QueryMatchInput): QueryMatchOutput { - return adapters.query.match(input); + match(input: QueryMatchInput | TextSelector | NodeSelector): QueryMatchOutput { + if (!input || typeof input !== 'object') { + throw new DocumentApiValidationError( + 'INVALID_INPUT', + 'query.match requires a QueryMatchInput or selector object.', + { value: input }, + ); + } + // Normalize flat selector shorthand to canonical nested form. + const normalized: QueryMatchInput = 'select' in input ? input : { select: input }; + return adapters.query.match(normalized); }, }, ranges: { diff --git a/packages/document-api/src/insert/insert.ts b/packages/document-api/src/insert/insert.ts index 8812912213..cb401071c0 100644 --- a/packages/document-api/src/insert/insert.ts +++ b/packages/document-api/src/insert/insert.ts @@ -7,7 +7,7 @@ import { DocumentApiValidationError } from '../errors.js'; import { isRecord, isTextAddress, - isValidTarget, + isBlockNodeAddress, assertNoUnknownFields, validateNestingPolicyValue, } from '../validation-primitives.js'; @@ -165,11 +165,10 @@ function validateStructuralInsertInput(input: Record): void { const { target, content, placement, nestingPolicy } = input; - // Structural path accepts both SDAddress and TextAddress - if (target !== undefined && !isValidTarget(target)) { + if (target !== undefined && !isBlockNodeAddress(target)) { throw new DocumentApiValidationError( 'INVALID_TARGET', - 'target must be a valid address (SDAddress or TextAddress).', + 'target must be a BlockNodeAddress ({ kind: "block", nodeType, nodeId }).', { field: 'target', value: target, diff --git a/packages/document-api/src/overview-examples.test.ts b/packages/document-api/src/overview-examples.test.ts index f161ccde2e..ab6d6e1352 100644 --- a/packages/document-api/src/overview-examples.test.ts +++ b/packages/document-api/src/overview-examples.test.ts @@ -77,10 +77,9 @@ function makeSDMutationReceipt() { success: true as const, resolution: { target: { - kind: 'content' as const, - stability: 'stable' as const, - nodeId: 'p1', - anchor: { start: { blockId: 'p1', offset: 0 }, end: { blockId: 'p1', offset: 3 } }, + kind: 'text' as const, + blockId: 'p1', + range: { start: 0, end: 3 }, }, }, }; @@ -547,7 +546,7 @@ describe('overview.mdx examples', () => { const preview = doc.insert({ target, value: 'hello' }, { dryRun: true }); // preview.success tells you whether the insert would succeed - // preview.resolution shows the resolved target (SDAddress) + // preview.resolution shows the resolved target (TextAddress) expect(preview).toHaveProperty('success'); expect(preview).toHaveProperty('resolution'); @@ -601,6 +600,24 @@ describe('common-workflows.mdx: Find text and insert at position', () => { expect(result.success).toBe(true); }); + + it('query.match accepts flat TextSelector shorthand', () => { + const doc = makeApi(); + + // Shorthand: pass TextSelector directly instead of { select: ... } + const match = doc.query.match({ type: 'text', pattern: 'Materials and methods' }); + + expect(match.items).toBeDefined(); + }); + + it('query.match accepts flat NodeSelector shorthand', () => { + const doc = makeApi(); + + // Shorthand: pass NodeSelector directly instead of { select: ... } + const match = doc.query.match({ type: 'node', nodeType: 'paragraph' }); + + expect(match.items).toBeDefined(); + }); }); // --------------------------------------------------------------------------- @@ -629,7 +646,7 @@ describe('src/README.md workflow examples', () => { const doc = makeApi(); const receipt = doc.insert({ value: 'new content' }, { changeMode: 'tracked' }); - // receipt.resolution.target contains the resolved insertion point (SDAddress) + // receipt.resolution.target contains the resolved insertion point (TextAddress) expect(receipt.resolution).toBeDefined(); expect(receipt.resolution!.target).toBeDefined(); diff --git a/packages/document-api/src/receipt-bridge.ts b/packages/document-api/src/receipt-bridge.ts index fea447d2cb..ba408e76ed 100644 --- a/packages/document-api/src/receipt-bridge.ts +++ b/packages/document-api/src/receipt-bridge.ts @@ -1,27 +1,30 @@ /** - * Bridge utilities for converting between TextMutationReceipt and SDMutationReceipt. + * Bridge utilities for converting internal receipt types to SDMutationReceipt. * - * The legacy text write pipeline returns TextMutationReceipt internally. - * The public insert/replace API returns SDMutationReceipt for all branches. - * This module handles the conversion at the API boundary. + * Two paths produce SDMutationReceipts: + * 1. Text pipeline: TextMutationReceipt → SDMutationReceipt (via {@link textReceiptToSDReceipt}) + * 2. Structural pipeline: direct construction (via {@link buildStructuralReceipt}) */ -import type { TextMutationReceipt, SDMutationReceipt, SDError } from './types/index.js'; -import type { SDAddress } from './types/sd-envelope.js'; -import type { TextAddress } from './types/address.js'; +import type { + TextMutationReceipt, + TextMutationResolution, + TextMutationRange, + SDMutationReceipt, + SDError, + SelectionTarget, + MutationResolutionTarget, +} from './types/index.js'; /** - * Converts a TextAddress into an SDAddress for receipt resolution. + * Builds the public receipt resolution from a TextMutationResolution. + * Passes through `target` (TextAddress) and optional `selectionTarget` directly. */ -function textAddressToSDAddress(textAddr: TextAddress): SDAddress { +function buildResolution(resolution: TextMutationResolution): SDMutationReceipt['resolution'] { return { - kind: 'content', - stability: 'stable', - nodeId: textAddr.blockId, - anchor: { - start: { blockId: textAddr.blockId, offset: textAddr.range.start }, - end: { blockId: textAddr.blockId, offset: textAddr.range.end }, - }, + target: resolution.target, + range: resolution.range, + ...(resolution.selectionTarget ? { selectionTarget: resolution.selectionTarget } : {}), }; } @@ -29,28 +32,14 @@ function textAddressToSDAddress(textAddr: TextAddress): SDAddress { * Wraps a TextMutationReceipt into an SDMutationReceipt at the public API boundary. * * - Success/failure semantics are preserved. - * - TextAddress resolution is converted to SDAddress resolution. - * - Failure codes from the text pipeline are mapped through the receipt. + * - Resolution is passed through directly (both use TextAddress). + * - Failure codes from the text pipeline are mapped to SDErrorCode. */ -/** - * Builds the SDMutationReceipt resolution object from a TextMutationResolution. - * Carries through selectionTarget for cross-block mutations. - */ -function buildSDResolution( - resolution: import('./types/index.js').TextMutationResolution, -): SDMutationReceipt['resolution'] { - return { - ...(resolution.requestedTarget ? { requestedTarget: textAddressToSDAddress(resolution.requestedTarget) } : {}), - target: textAddressToSDAddress(resolution.target), - ...(resolution.selectionTarget ? { selectionTarget: resolution.selectionTarget } : undefined), - }; -} - export function textReceiptToSDReceipt(receipt: TextMutationReceipt): SDMutationReceipt { if (receipt.success) { return { success: true, - resolution: receipt.resolution ? buildSDResolution(receipt.resolution) : undefined, + resolution: receipt.resolution ? buildResolution(receipt.resolution) : undefined, }; } @@ -80,6 +69,53 @@ export function textReceiptToSDReceipt(receipt: TextMutationReceipt): SDMutation return { success: false, failure, - resolution: receipt.resolution ? buildSDResolution(receipt.resolution) : undefined, + resolution: receipt.resolution ? buildResolution(receipt.resolution) : undefined, + }; +} + +// --------------------------------------------------------------------------- +// Structural receipt builder +// --------------------------------------------------------------------------- + +/** Parameters for building a structural mutation receipt. */ +export interface StructuralReceiptParams { + target: MutationResolutionTarget; + range: TextMutationRange; + selectionTarget?: SelectionTarget; +} + +/** + * Builds an SDMutationReceipt for structural (block-level) mutations. + * + * Unlike {@link textReceiptToSDReceipt} which converts from the internal + * text pipeline, this constructs a receipt directly — preserving the + * original `BlockNodeAddress` target instead of normalizing it to a + * synthetic `TextAddress`. + */ +export function buildStructuralReceipt(success: true, params: StructuralReceiptParams): SDMutationReceipt; +export function buildStructuralReceipt( + success: false, + params: StructuralReceiptParams, + failure: { code: string; message: string }, +): SDMutationReceipt; +export function buildStructuralReceipt( + success: boolean, + params: StructuralReceiptParams, + failure?: { code: string; message: string }, +): SDMutationReceipt { + const resolution: SDMutationReceipt['resolution'] = { + target: params.target, + range: params.range, + ...(params.selectionTarget ? { selectionTarget: params.selectionTarget } : {}), + }; + + if (success) { + return { success: true, resolution }; + } + + return { + success: false, + failure: { code: (failure?.code ?? 'INTERNAL_ERROR') as SDError['code'], message: failure?.message ?? '' }, + resolution, }; } diff --git a/packages/document-api/src/replace/replace.ts b/packages/document-api/src/replace/replace.ts index f880c9b694..c11abe45dc 100644 --- a/packages/document-api/src/replace/replace.ts +++ b/packages/document-api/src/replace/replace.ts @@ -6,7 +6,7 @@ * - Structural replacement (`content` field): continues through WriteAdapter.replaceStructured. * * Text path accepts `SelectionTarget` or `ref`. Structural path accepts - * `SDAddress`, `SelectionTarget`, or `ref`. + * `BlockNodeAddress`, `SelectionTarget`, or `ref`. */ import type { MutationOptions } from '../types/mutation-plan.types.js'; @@ -20,8 +20,7 @@ import { normalizeMutationOptions } from '../write/write.js'; import { DocumentApiValidationError } from '../errors.js'; import { isRecord, - isSDAddress, - isTextAddress, + isBlockNodeAddress, assertNoUnknownFields, validateNestingPolicyValue, } from '../validation-primitives.js'; @@ -180,12 +179,11 @@ function validateStructuralReplaceInput(input: Record): void { }); } - if (hasTarget && !isSDAddress(target) && !isTextAddress(target) && !isSelectionTarget(target)) { - throw new DocumentApiValidationError( - 'INVALID_TARGET', - 'target must be a valid address (SDAddress, TextAddress, or SelectionTarget).', - { field: 'target', value: target }, - ); + if (hasTarget && !isBlockNodeAddress(target) && !isSelectionTarget(target)) { + throw new DocumentApiValidationError('INVALID_TARGET', 'target must be a BlockNodeAddress or SelectionTarget.', { + field: 'target', + value: target, + }); } if (hasRef && typeof refValue !== 'string') { diff --git a/packages/document-api/src/types/discovery.ts b/packages/document-api/src/types/discovery.ts index 0597d18734..bdb982cad0 100644 --- a/packages/document-api/src/types/discovery.ts +++ b/packages/document-api/src/types/discovery.ts @@ -155,10 +155,10 @@ export function buildDiscoveryResult(params: { } /** - * Derives a mutation target from a discovery item, suitable for passing to + * Derives an apply-ready target from a discovery item, suitable for passing to * `mutations.apply` step `where` clauses. */ -export function toMutationTarget( +export function toApplyTarget( item: DiscoveryItem, evaluatedRevision: string, ): { where: { by: 'ref'; ref: string }; expectedRevision: string } { diff --git a/packages/document-api/src/types/fragment.ts b/packages/document-api/src/types/fragment.ts index b16cd03a80..eaee9f3cfe 100644 --- a/packages/document-api/src/types/fragment.ts +++ b/packages/document-api/src/types/fragment.ts @@ -11,7 +11,7 @@ * sd-nodes.ts — all concrete node interfaces + SDContentNode/SDInlineNode unions * sd-styles.ts — style dictionaries, theme, document defaults * sd-sections.ts — sections, numbering, annotations, reference catalogs - * sd-envelope.ts — SDAddress, SDNodeResult, SDFindResult, SDReadOptions + * sd-envelope.ts — SDNodeResult, SDFindResult, SDReadOptions * sd-contract.ts — SDErrorCode, SDError, SDMutationReceipt, SDDiagnostic * fragment.ts — (this file) SDFragment, SDDocument, kind constants, barrel re-exports */ diff --git a/packages/document-api/src/types/mutation-plan.types.ts b/packages/document-api/src/types/mutation-plan.types.ts index 9dcdd13cd2..611af81fb1 100644 --- a/packages/document-api/src/types/mutation-plan.types.ts +++ b/packages/document-api/src/types/mutation-plan.types.ts @@ -5,7 +5,7 @@ * that changes document state is a step dispatched by the plan engine. */ -import type { NodeAddress } from './base.js'; +import type { BlockNodeAddress } from './base.js'; import type { TextAddress, TrackedChangeAddress, SelectionTarget, DeleteBehavior } from './address.js'; import type { TextSelector, NodeSelector } from './query.js'; import type { InsertStylePolicy, StylePolicy } from './style-policy.types.js'; @@ -20,14 +20,14 @@ import type { Placement, NestingPolicy } from './placement.js'; export type SelectWhere = { by: 'select'; select: TextSelector | NodeSelector; - within?: NodeAddress; + within?: BlockNodeAddress; require: 'first' | 'exactlyOne' | 'all'; }; export type RefWhere = { by: 'ref'; ref: string; - within?: NodeAddress; + within?: BlockNodeAddress; }; export type TargetWhere = { @@ -40,7 +40,7 @@ export type StepWhere = SelectWhere | RefWhere | TargetWhere; export type AssertWhere = { by: 'select'; select: TextSelector | NodeSelector; - within?: NodeAddress; + within?: BlockNodeAddress; }; // --------------------------------------------------------------------------- @@ -97,7 +97,7 @@ export type TextInsertStep = { where: { by: 'select'; select: TextSelector | NodeSelector; - within?: NodeAddress; + within?: BlockNodeAddress; require: 'first' | 'exactlyOne'; }; args: { diff --git a/packages/document-api/src/types/query-match.types.ts b/packages/document-api/src/types/query-match.types.ts index ab30cdcdf9..14bd1eadba 100644 --- a/packages/document-api/src/types/query-match.types.ts +++ b/packages/document-api/src/types/query-match.types.ts @@ -8,7 +8,7 @@ * See plans/query-match-blocks-runs-plan.md for design decisions D1–D20. */ -import type { BlockNodeType, NodeAddress } from './base.js'; +import type { BlockNodeAddress, BlockNodeType, NodeAddress } from './base.js'; import type { SelectionTarget } from './address.js'; import type { TextSelector, NodeSelector } from './query.js'; import type { DiscoveryItem, DiscoveryOutput, DiscoveryResult } from './discovery.js'; @@ -153,8 +153,8 @@ export interface MatchBlock { export interface TextMatchDomain { /** Discriminator — always `'text'` for text-selector matches. */ matchKind: 'text'; - /** Address of the first matched block in document order (D14). */ - address: NodeAddress; + /** Address of the containing block in document order (D14). Text matches always yield the block. */ + address: BlockNodeAddress; /** * Canonical mutation-ready selection target for this text match. * @@ -220,7 +220,7 @@ export interface QueryMatchMeta { export interface QueryMatchInput { select: TextSelector | NodeSelector; - within?: NodeAddress; + within?: BlockNodeAddress; require?: CardinalityRequirement; /** Match evaluation mode. `'candidates'` (default) returns best-effort matches; `'strict'` enforces exact semantics (future). */ mode?: 'strict' | 'candidates'; diff --git a/packages/document-api/src/types/query.ts b/packages/document-api/src/types/query.ts index 7668ff715a..29e3bee061 100644 --- a/packages/document-api/src/types/query.ts +++ b/packages/document-api/src/types/query.ts @@ -1,4 +1,4 @@ -import type { NodeAddress, NodeKind, NodeType } from './base.js'; +import type { BlockNodeAddress, NodeAddress, NodeKind, NodeType } from './base.js'; import type { NodeInfo } from './node.js'; import type { Range, TextAddress, SelectionTarget } from './address.js'; import type { DiscoveryOutput } from './discovery.js'; @@ -38,7 +38,7 @@ export type Selector = { nodeType: NodeType } | NodeSelector | TextSelector; export interface Query { /** Selector that determines which nodes to match. */ select: NodeSelector | TextSelector; - within?: NodeAddress; + within?: BlockNodeAddress; limit?: number; offset?: number; /** diff --git a/packages/document-api/src/types/sd-contract.ts b/packages/document-api/src/types/sd-contract.ts index c4413561f4..69619baed6 100644 --- a/packages/document-api/src/types/sd-contract.ts +++ b/packages/document-api/src/types/sd-contract.ts @@ -2,8 +2,9 @@ * SDM/1 contract types — mutation receipts, error model, and diagnostics. */ -import type { SelectionTarget } from './address.js'; -import type { SDAddress } from './sd-envelope.js'; +import type { BlockNodeAddress } from './base.js'; +import type { SelectionTarget, TextAddress } from './address.js'; +import type { TextMutationRange } from './receipt.js'; // --------------------------------------------------------------------------- // Error model (normative) @@ -30,7 +31,8 @@ export interface SDError { code: SDErrorCode; message: string; path?: Array; - address?: SDAddress; + /** The target that caused the error, when available. */ + target?: BlockNodeAddress | TextAddress | SelectionTarget; details?: Record; } @@ -38,13 +40,22 @@ export interface SDError { // Mutation receipt // --------------------------------------------------------------------------- +/** + * Discriminated target in a mutation resolution. + * + * - `TextAddress` (`kind: 'text'`) — text-level insert/replace with block-relative offsets. + * - `BlockNodeAddress` (`kind: 'block'`) — structural insert/replace targeting a whole block. + */ +export type MutationResolutionTarget = TextAddress | BlockNodeAddress; + export interface SDMutationReceipt { success: boolean; failure?: SDError; evaluatedRevision?: { before: string; after: string }; resolution?: { - requestedTarget?: SDAddress; - target: SDAddress; + target: MutationResolutionTarget; + /** Engine-resolved absolute document range for the effective target. */ + range: TextMutationRange; /** Full selection target for cross-block mutations. */ selectionTarget?: SelectionTarget; }; diff --git a/packages/document-api/src/types/sd-envelope.ts b/packages/document-api/src/types/sd-envelope.ts index 6632673d65..c4ed7caefb 100644 --- a/packages/document-api/src/types/sd-envelope.ts +++ b/packages/document-api/src/types/sd-envelope.ts @@ -1,14 +1,14 @@ /** - * SDM/1 envelope types — addressing, read options, query/find, and results. + * SDM/1 envelope types — read options, query/find, and results. * * These types wrap the core node model for API operations: - * SDAddress — universal node locator * SDNodeResult — single-node read/find result * SDFindResult — paginated find result set * SDReadOptions — projection options for reads */ -import type { NodeAddress } from './base.js'; +import type { BlockNodeAddress, NodeAddress } from './base.js'; +import type { TextSelector, NodeSelector } from './query.js'; import type { SDContentNode, SDInlineNode } from './sd-nodes.js'; // --------------------------------------------------------------------------- @@ -21,22 +21,6 @@ export interface SDPoint { offset: number; } -/** - * Legacy SDM/1 address type. - * - * @deprecated Prefer `NodeAddress` from `./base.js`. `find` results now return - * `NodeAddress` directly. This type is retained for backward-compatible inputs - * (`within`, `getNode`). - */ -export interface SDAddress { - kind: 'content' | 'inline' | 'annotation' | 'section'; - stability: 'stable' | 'ephemeral'; - nodeId?: string; - anchor?: { start: SDPoint; end: SDPoint }; - evaluatedRevision?: string; - path?: Array; -} - export interface SDNodeContext { ancestors?: Array<{ id: string; kind: string }>; sectionId?: string; @@ -65,33 +49,13 @@ export interface SDGetInput { options?: SDReadOptions; } -export interface SDGetNodeInput { - target: SDAddress; - options?: SDReadOptions; -} - // --------------------------------------------------------------------------- -// Selectors +// Find input // --------------------------------------------------------------------------- -export interface SDTextSelector { - type: 'text'; - pattern: string; - mode?: 'contains' | 'regex'; - caseSensitive?: boolean; -} - -export interface SDNodeSelector { - type: 'node'; - kind?: 'content' | 'inline'; - nodeKind?: string; -} - -export type SDSelector = SDTextSelector | SDNodeSelector; - export interface SDFindInput { - select: SDSelector; - within?: SDAddress | NodeAddress; + select: TextSelector | NodeSelector; + within?: BlockNodeAddress; limit?: number; offset?: number; options?: SDReadOptions; diff --git a/packages/document-api/src/types/structural-input.ts b/packages/document-api/src/types/structural-input.ts index 8fd4bdc991..c27e50714e 100644 --- a/packages/document-api/src/types/structural-input.ts +++ b/packages/document-api/src/types/structural-input.ts @@ -7,8 +7,8 @@ * Discrimination rule: presence of `content` (SDFragment) vs `value`/`text` (string). */ -import type { SDAddress } from './sd-envelope.js'; -import type { SelectionTarget, TextAddress } from './address.js'; +import type { BlockNodeAddress } from './base.js'; +import type { SelectionTarget } from './address.js'; import type { SDFragment } from './fragment.js'; import type { Placement, NestingPolicy } from './placement.js'; @@ -16,10 +16,10 @@ import type { Placement, NestingPolicy } from './placement.js'; // Structural insert input // --------------------------------------------------------------------------- -/** SDM/1 structural shape for the insert operation. */ +/** Structural shape for the insert operation. */ export interface SDInsertInput { /** Optional insertion target. When omitted, inserts at the end of the document. */ - target?: SDAddress | TextAddress; + target?: BlockNodeAddress; /** Structural content to insert. */ content: SDFragment; /** Where to place content relative to the target. Defaults to 'after'. */ @@ -32,10 +32,10 @@ export interface SDInsertInput { // Structural replace input // --------------------------------------------------------------------------- -/** SDM/1 structural shape for the replace operation. */ +/** Structural shape for the replace operation. */ export interface SDReplaceInput { - /** Target range to replace. Required unless `ref` is provided. */ - target?: SDAddress | TextAddress | SelectionTarget; + /** Target to replace. BlockNodeAddress replaces the entire block; SelectionTarget replaces a contiguous selection. */ + target?: BlockNodeAddress | SelectionTarget; /** Opaque ref string (alternative to `target`). */ ref?: string; /** Structural content to replace with. */ @@ -43,13 +43,3 @@ export interface SDReplaceInput { /** Nesting policy. Defaults to { tables: 'forbid' }. */ nestingPolicy?: NestingPolicy; } - -// --------------------------------------------------------------------------- -// Legacy aliases (temporary — removed in Phase 12) -// --------------------------------------------------------------------------- - -/** @deprecated Use SDInsertInput. Temporary alias for migration. */ -export type StructuralInsertInput = SDInsertInput; - -/** @deprecated Use SDReplaceInput. Temporary alias for migration. */ -export type StructuralReplaceInput = SDReplaceInput; diff --git a/packages/document-api/src/validation-primitives.ts b/packages/document-api/src/validation-primitives.ts index 5154a5743b..63c8d1e1e7 100644 --- a/packages/document-api/src/validation-primitives.ts +++ b/packages/document-api/src/validation-primitives.ts @@ -8,8 +8,8 @@ * Internal — not exported from the package root. */ -import type { TextAddress } from './types/index.js'; -import type { SDAddress } from './types/sd-envelope.js'; +import type { BlockNodeAddress, TextAddress } from './types/index.js'; +import { BLOCK_NODE_TYPES } from './types/base.js'; import { TABLE_NESTING_POLICY_VALUES } from './types/placement.js'; import { DocumentApiValidationError } from './errors.js'; @@ -32,22 +32,17 @@ export function isTextAddress(value: unknown): value is TextAddress { return range.start <= range.end; } -const SD_ADDRESS_KINDS: ReadonlySet = new Set(['content', 'inline', 'annotation', 'section']); -const SD_ADDRESS_STABILITIES: ReadonlySet = new Set(['stable', 'ephemeral']); +const BLOCK_NODE_TYPES_SET: ReadonlySet = new Set(BLOCK_NODE_TYPES); -/** Type guard for SDAddress. Checks shape, not semantic validity. */ -export function isSDAddress(value: unknown): value is SDAddress { +/** Type guard for BlockNodeAddress. Checks shape and nodeType membership. */ +export function isBlockNodeAddress(value: unknown): value is BlockNodeAddress { if (!isRecord(value)) return false; - if (typeof value.kind !== 'string' || !SD_ADDRESS_KINDS.has(value.kind)) return false; - if (typeof value.stability !== 'string' || !SD_ADDRESS_STABILITIES.has(value.stability)) return false; + if (value.kind !== 'block') return false; + if (typeof value.nodeType !== 'string' || !BLOCK_NODE_TYPES_SET.has(value.nodeType)) return false; + if (typeof value.nodeId !== 'string') return false; return true; } -/** Returns true when value is a valid target (either TextAddress or SDAddress). */ -export function isValidTarget(value: unknown): value is TextAddress | SDAddress { - return isTextAddress(value) || isSDAddress(value); -} - /** * Throws INVALID_TARGET if any key on the input object is not in the allowlist. */ diff --git a/packages/super-editor/src/core/Editor.lifecycle.test.ts b/packages/super-editor/src/core/Editor.lifecycle.test.ts index a3a464b87d..a69cdb4434 100644 --- a/packages/super-editor/src/core/Editor.lifecycle.test.ts +++ b/packages/super-editor/src/core/Editor.lifecycle.test.ts @@ -969,7 +969,7 @@ describe('Editor Lifecycle API', () => { expect(typeof docAfterReopen.find).toBe('function'); // find should execute without throwing - const result = docAfterReopen.find({ select: { type: 'node', nodeKind: 'paragraph' } }); + const result = docAfterReopen.find({ select: { type: 'node', nodeType: 'paragraph' } }); expect(result).toBeDefined(); }); }); diff --git a/packages/super-editor/src/document-api-adapters/citations-export.integration.test.ts b/packages/super-editor/src/document-api-adapters/citations-export.integration.test.ts index be1d005237..595c8ecfce 100644 --- a/packages/super-editor/src/document-api-adapters/citations-export.integration.test.ts +++ b/packages/super-editor/src/document-api-adapters/citations-export.integration.test.ts @@ -34,12 +34,7 @@ function resolveInsertedBlockId(receipt: unknown): string | null { const value = receipt as { target?: { blockId?: unknown }; resolution?: { - target?: { - nodeId?: unknown; - anchor?: { - start?: { blockId?: unknown }; - }; - }; + target?: { blockId?: unknown }; }; }; @@ -47,15 +42,8 @@ function resolveInsertedBlockId(receipt: unknown): string | null { return value.target.blockId; } - if (typeof value.resolution?.target?.nodeId === 'string' && value.resolution.target.nodeId.length > 0) { - return value.resolution.target.nodeId; - } - - if ( - typeof value.resolution?.target?.anchor?.start?.blockId === 'string' && - value.resolution.target.anchor.start.blockId.length > 0 - ) { - return value.resolution.target.anchor.start.blockId; + if (typeof value.resolution?.target?.blockId === 'string' && value.resolution.target.blockId.length > 0) { + return value.resolution.target.blockId; } return null; diff --git a/packages/super-editor/src/document-api-adapters/find-adapter.test.ts b/packages/super-editor/src/document-api-adapters/find-adapter.test.ts index d86fe1d5c4..0360dac611 100644 --- a/packages/super-editor/src/document-api-adapters/find-adapter.test.ts +++ b/packages/super-editor/src/document-api-adapters/find-adapter.test.ts @@ -272,22 +272,22 @@ describe('findLegacyAdapter — within scope', () => { expect(result.diagnostics![0].message).toContain('was not found'); }); - it('returns empty with diagnostic for inline within scope', () => { + it('returns empty with diagnostic for non-existent within scope', () => { const doc = buildDoc({ typeName: 'paragraph', attrs: { sdBlockId: 'p1' }, offset: 0 }); const editor = makeEditor(doc); const query: Query = { select: { type: 'node', nodeType: 'paragraph' }, within: { - kind: 'inline', - nodeType: 'run', - anchor: { start: { blockId: 'p1', offset: 0 }, end: { blockId: 'p1', offset: 5 } }, + kind: 'block', + nodeType: 'paragraph', + nodeId: 'nonexistent', }, }; const result = findLegacyAdapter(editor, query); expect(result.items).toEqual([]); - expect(result.diagnostics![0].message).toContain('Inline'); + expect(result.diagnostics![0].message).toContain('not found'); }); }); diff --git a/packages/super-editor/src/document-api-adapters/find-adapter.ts b/packages/super-editor/src/document-api-adapters/find-adapter.ts index 3e3624fea3..b14750ea0b 100644 --- a/packages/super-editor/src/document-api-adapters/find-adapter.ts +++ b/packages/super-editor/src/document-api-adapters/find-adapter.ts @@ -6,7 +6,6 @@ import type { SDFindResult, SDNodeResult, NodeAddress, - NodeType, UnknownNodeDiagnostic, } from '@superdoc/document-api'; import { buildResolvedHandle, buildDiscoveryItem, buildDiscoveryResult } from '@superdoc/document-api'; @@ -14,7 +13,7 @@ import { DocumentApiAdapterError } from './errors.js'; import { dedupeDiagnostics } from './helpers/adapter-utils.js'; import { getBlockIndex, getInlineIndex } from './helpers/index-cache.js'; import { findInlineByAnchor } from './helpers/inline-address-resolver.js'; -import { findBlockByNodeIdOnly } from './helpers/node-address-resolver.js'; +import { findBlockByIdStrict, findBlockByNodeIdOnly } from './helpers/node-address-resolver.js'; import { resolveIncludedNodes } from './helpers/node-info-resolver.js'; import { collectUnknownNodeDiagnostics, isInlineQuery, shouldQueryBothKinds } from './find/common.js'; import { executeBlockSelector } from './find/block-strategy.js'; @@ -148,32 +147,28 @@ function translateToInternalQuery(input: SDFindInput): Query { // Validate within address early (actual nodeType resolution happens in sdFindAdapter) if (within) validateWithinAddress(within); - if (select.type === 'text') { - return { - select: { - type: 'text', - pattern: select.pattern, - ...(select.mode != null && { mode: select.mode }), - ...(select.caseSensitive != null && { caseSensitive: select.caseSensitive }), - }, - limit, - offset, - // within is resolved in sdFindAdapter after block index is built - includeNodes: true, - }; + // Reject legacy selector vocabulary that would otherwise be silently ignored. + if (select.type === 'node') { + const raw = select as Record; + if ('nodeKind' in raw && raw.nodeKind != null) { + throw new DocumentApiAdapterError( + 'INVALID_INPUT', + `"nodeKind" is no longer supported on node selectors. Use "nodeType" instead: ` + + `{ type: 'node', nodeType: '${String(raw.nodeKind)}' }.`, + { field: 'select.nodeKind', value: raw.nodeKind }, + ); + } + if (raw.kind === 'content') { + throw new DocumentApiAdapterError( + 'INVALID_INPUT', + `kind: 'content' is no longer supported on node selectors. Use kind: 'block' instead.`, + { field: 'select.kind', value: raw.kind }, + ); + } } - // SDNodeSelector → internal NodeSelector - // Cast nodeKind (string) to NodeType — the internal engine handles unknown types gracefully. - const nodeSelect = { - type: 'node' as const, - ...(select.nodeKind != null && { nodeType: select.nodeKind as NodeType }), - ...(select.kind === 'content' && { kind: 'block' as const }), - ...(select.kind === 'inline' && { kind: 'inline' as const }), - }; - return { - select: nodeSelect, + select, limit, offset, // within is resolved in sdFindAdapter after block index is built @@ -182,44 +177,46 @@ function translateToInternalQuery(input: SDFindInput): Query { } /** - * Validates an address for use as a within scope. + * Validates a BlockNodeAddress for use as a within scope. * - * Accepts both NodeAddress (`kind: 'block'`) and legacy SDAddress (`kind: 'content'`). - * Only block/content-kind addresses with a `nodeId` are supported for scoping. - * The actual nodeType resolution is deferred to {@link resolveWithinNodeType} - * which requires the block index. + * Only block-kind addresses with a `nodeId` are supported for scoping. + * Returns the validated `nodeId` and optional `nodeType` for downstream + * verification against the live document in {@link resolveWithinAddress}. */ -function validateWithinAddress(address: SDFindInput['within'] & object): { nodeId: string } { - // Accept NodeAddress (kind: 'block') and legacy SDAddress (kind: 'content') - if ( - (address.kind === 'block' || address.kind === 'content') && - 'nodeId' in address && - typeof address.nodeId === 'string' - ) { - return { nodeId: address.nodeId }; +function validateWithinAddress(address: SDFindInput['within'] & object): { + nodeId: string; + nodeType?: import('@superdoc/document-api').BlockNodeType; +} { + if (address.kind === 'block' && 'nodeId' in address && typeof address.nodeId === 'string') { + return { nodeId: address.nodeId, nodeType: address.nodeType }; } - throw new DocumentApiAdapterError( - 'INVALID_TARGET', - `"within" scope requires a block address with a nodeId. Got kind="${address.kind}".`, - { field: 'within', value: address }, - ); + throw new DocumentApiAdapterError('INVALID_TARGET', '"within" scope requires a BlockNodeAddress with a nodeId.', { + field: 'within', + value: address, + }); } /** - * Resolves the actual nodeType for a within-scope nodeId using - * {@link findBlockByNodeIdOnly}, which handles alias IDs (e.g. sdBlockId) - * and throws a precise error for ambiguous or missing targets. + * Resolves a within-scope address against the live document index. + * + * When `expectedNodeType` is provided, uses the composite `nodeType:nodeId` + * key via {@link findBlockByIdStrict} — this disambiguates duplicate nodeIds + * that differ by type. Without a nodeType, falls back to + * {@link findBlockByNodeIdOnly} which handles alias IDs (e.g. sdBlockId). */ -function resolveWithinNodeType(index: ReturnType, nodeId: string): NodeAddress { - // findBlockByNodeIdOnly checks primary candidates, then alias entries, - // and throws AMBIGUOUS_TARGET / TARGET_NOT_FOUND as appropriate. +function resolveWithinAddress( + index: ReturnType, + nodeId: string, + expectedNodeType?: import('@superdoc/document-api').BlockNodeType, +): import('@superdoc/document-api').BlockNodeAddress { + if (expectedNodeType) { + const match = findBlockByIdStrict(index, { kind: 'block', nodeType: expectedNodeType, nodeId }); + return { kind: 'block', nodeType: match.nodeType, nodeId: match.nodeId }; + } + const match = findBlockByNodeIdOnly(index, nodeId); - return { - kind: 'block', - nodeType: match.nodeType, - nodeId: match.nodeId, - } as NodeAddress; + return { kind: 'block', nodeType: match.nodeType, nodeId: match.nodeId }; } /** @@ -227,7 +224,7 @@ function resolveWithinNodeType(index: ReturnType, nodeId: * in the block index (for blocks) or inline index (for inlines) and projecting * it to an SDM/1 node. * - * Returns NodeAddress directly — no SDAddress conversion. + * Returns NodeAddress directly. */ function projectMatchToSDNodeResult( editor: Editor, @@ -298,11 +295,11 @@ export function sdFindAdapter(editor: Editor, input: SDFindInput): SDFindResult const query = translateToInternalQuery(input); const index = getBlockIndex(editor); - // Resolve within scope after index is built (legacy SDAddress doesn't carry - // nodeType, so we need the index to look up the actual PM node type). + // Resolve within scope after index is built — validates the caller-supplied + // nodeType matches the actual node found in the document. if (input.within) { - const { nodeId } = validateWithinAddress(input.within); - query.within = resolveWithinNodeType(index, nodeId); + const { nodeId, nodeType } = validateWithinAddress(input.within); + query.within = resolveWithinAddress(index, nodeId, nodeType); } const diagnostics: UnknownNodeDiagnostic[] = []; diff --git a/packages/super-editor/src/document-api-adapters/get-node-adapter.ts b/packages/super-editor/src/document-api-adapters/get-node-adapter.ts index 9be6d56045..d7d1dbf025 100644 --- a/packages/super-editor/src/document-api-adapters/get-node-adapter.ts +++ b/packages/super-editor/src/document-api-adapters/get-node-adapter.ts @@ -16,18 +16,12 @@ function findBlocksByTypeAndId(blockIndex: BlockIndex, nodeType: BlockNodeType, return blockIndex.candidates.filter((candidate) => candidate.nodeType === nodeType && candidate.nodeId === nodeId); } -/** - * Returns the input block address as-is (it's already a NodeAddress). - * Previously converted to SDAddress; now passes through directly. - */ +/** Returns the input block address as-is (already a NodeAddress). */ function buildBlockAddress(address: NodeAddress & { kind: 'block' }): NodeAddress { return address; } -/** - * Returns the input inline address as-is (it's already a NodeAddress). - * Previously converted to SDAddress; now passes through directly. - */ +/** Returns the input inline address as-is (already a NodeAddress). */ function buildInlineAddress(address: NodeAddress & { kind: 'inline' }): NodeAddress { return address; } diff --git a/packages/super-editor/src/document-api-adapters/helpers/adapter-utils.ts b/packages/super-editor/src/document-api-adapters/helpers/adapter-utils.ts index 631b22d0c1..5f532f62f7 100644 --- a/packages/super-editor/src/document-api-adapters/helpers/adapter-utils.ts +++ b/packages/super-editor/src/document-api-adapters/helpers/adapter-utils.ts @@ -59,12 +59,6 @@ function assertUnambiguous(matches: BlockCandidate[], blockId: string): void { } } -function findInlineWithinTextBlock(index: BlockIndex, blockId: string): BlockCandidate | undefined { - const matches = findTextBlockCandidates(index, blockId); - assertUnambiguous(matches, blockId); - return matches[0]; -} - /** * Resolves a {@link TextAddress} to absolute ProseMirror positions. * @@ -386,42 +380,15 @@ export function resolveWithinScope( ): WithinResult { if (!query.within) return { ok: true, range: undefined }; - if (query.within.kind === 'block') { - const within = findBlockById(index, query.within); - if (!within) { - addDiagnostic( - diagnostics, - `Within block "${query.within.nodeType}" with id "${query.within.nodeId}" was not found in the document.`, - ); - return { ok: false }; - } - return { ok: true, range: { start: within.pos, end: within.end } }; - } - - if (query.within.anchor.start.blockId !== query.within.anchor.end.blockId) { - addDiagnostic(diagnostics, 'Inline within anchors that span multiple blocks are not supported.'); - return { ok: false }; - } - - const block = findInlineWithinTextBlock(index, query.within.anchor.start.blockId); - if (!block) { + const within = findBlockById(index, query.within); + if (!within) { addDiagnostic( diagnostics, - `Within inline anchor block "${query.within.anchor.start.blockId}" was not found in the document.`, + `Within block "${query.within.nodeType}" with id "${query.within.nodeId}" was not found in the document.`, ); return { ok: false }; } - - const resolved = resolveTextRangeInBlock(block.node, block.pos, { - start: query.within.anchor.start.offset, - end: query.within.anchor.end.offset, - }); - if (!resolved) { - addDiagnostic(diagnostics, 'Inline within anchor offsets could not be resolved in the target block.'); - return { ok: false }; - } - - return { ok: true, range: { start: resolved.from, end: resolved.to } }; + return { ok: true, range: { start: within.pos, end: within.end } }; } /** diff --git a/packages/super-editor/src/document-api-adapters/helpers/sd-projection.test.ts b/packages/super-editor/src/document-api-adapters/helpers/sd-projection.test.ts index 024d2e3c26..dcff7d65be 100644 --- a/packages/super-editor/src/document-api-adapters/helpers/sd-projection.test.ts +++ b/packages/super-editor/src/document-api-adapters/helpers/sd-projection.test.ts @@ -401,7 +401,7 @@ describe('sdFindAdapter — inline SDT node.kind', () => { }); const result = sdFindAdapter(editor, { - select: { type: 'node', nodeKind: 'sdt' }, + select: { type: 'node', nodeType: 'sdt' }, }); const inlineItem = result.items.find((item) => item.address.kind === 'inline'); diff --git a/packages/super-editor/src/document-api-adapters/plan-engine/compiler.ts b/packages/super-editor/src/document-api-adapters/plan-engine/compiler.ts index 8e64194483..9e40805ce3 100644 --- a/packages/super-editor/src/document-api-adapters/plan-engine/compiler.ts +++ b/packages/super-editor/src/document-api-adapters/plan-engine/compiler.ts @@ -503,14 +503,14 @@ function resolveTextSelector( editor: Editor, index: BlockIndex, selector: TextSelector | NodeSelector, - within: import('@superdoc/document-api').NodeAddress | undefined, + within: import('@superdoc/document-api').BlockNodeAddress | undefined, stepId: string, options?: { allBlockTypes?: boolean }, ): { addresses: ResolvedAddress[] } { if (selector.type === 'text') { const query = { select: selector, - within: within as import('@superdoc/document-api').NodeAddress | undefined, + within: within as import('@superdoc/document-api').BlockNodeAddress | undefined, includeNodes: false, }; const result = executeTextSelector(editor, index, query, []); @@ -546,7 +546,7 @@ function resolveTextSelector( // Node selector — resolve to block positions const query = { select: selector, - within: within as import('@superdoc/document-api').NodeAddress | undefined, + within: within as import('@superdoc/document-api').BlockNodeAddress | undefined, includeNodes: false, }; const result = executeBlockSelector(index, query, []); diff --git a/packages/super-editor/src/document-api-adapters/plan-engine/plan-wrappers.ts b/packages/super-editor/src/document-api-adapters/plan-engine/plan-wrappers.ts index 02fc42aeba..2ed3ba62bd 100644 --- a/packages/super-editor/src/document-api-adapters/plan-engine/plan-wrappers.ts +++ b/packages/super-editor/src/document-api-adapters/plan-engine/plan-wrappers.ts @@ -23,7 +23,7 @@ import type { SDInsertInput, SDReplaceInput, ReplaceInput, - SDAddress, + BlockNodeAddress, StepWhere, SelectionMutationRequest, SelectionTarget, @@ -36,6 +36,7 @@ import { isStructuralInsertInput, isStructuralReplaceInput, textReceiptToSDReceipt, + buildStructuralReceipt, INLINE_PROPERTY_BY_KEY, } from '@superdoc/document-api'; import type { Editor } from '../../core/Editor.js'; @@ -157,24 +158,22 @@ function ensureTableSeparators(jsonNodes: Record[]): void { } } -// --------------------------------------------------------------------------- -// SDAddress → TextAddress bridge (transitional — SDAddress resolution in Phase 6) -// --------------------------------------------------------------------------- +/** + * Extracts the block ID from a structural target, regardless of its kind. + */ +function targetBlockId(target: TextAddress | BlockNodeAddress): string { + return target.kind === 'block' ? target.nodeId : target.blockId; +} /** - * Narrows an `SDAddress | TextAddress` union to `TextAddress` for the current - * adapter layer, which only handles TextAddress-based resolution. + * Coerces a structural target to a TextAddress for internal resolution APIs + * that require it (e.g. text mutation resolution). * - * SDAddress inputs are bridged using `nodeId → blockId` and `anchor → range`. + * The zero range is a lookup sentinel — it does not affect behavior. */ -function narrowToTextAddress(target: SDAddress | TextAddress): TextAddress { +function toTextAddress(target: TextAddress | BlockNodeAddress): TextAddress { if (target.kind === 'text') return target; - const sd = target as SDAddress; - return { - kind: 'text', - blockId: sd.nodeId ?? '', - range: sd.anchor ? { start: sd.anchor.start.offset, end: sd.anchor.end.offset } : { start: 0, end: 0 }, - }; + return { kind: 'text', blockId: target.nodeId, range: { start: 0, end: 0 } }; } // --------------------------------------------------------------------------- @@ -829,6 +828,11 @@ export function insertStructuredWrapper( input: InsertInput, options?: MutationOptions, ): SDMutationReceipt { + // Structural (SDFragment) inserts with a BlockNodeAddress target produce + // a block-level receipt directly, avoiding the synthetic TextAddress bridge. + if (isStructuralInsertInput(input) && input.target) { + return executeStructuralInsertDirect(editor, input, options); + } return textReceiptToSDReceipt(insertStructuredInner(editor, input, options)); } @@ -1082,19 +1086,16 @@ function executeStructuralInsertWrapper( const { content, target, placement, nestingPolicy } = input; const mode = options?.changeMode ?? 'direct'; - // Narrow SDAddress | TextAddress → TextAddress for the current adapter layer. - const textTarget = target ? narrowToTextAddress(target) : undefined; - // Block-level resolution for metadata — uses the structural engine's resolver // so ALL block types (tables, images, etc.) are addressable, not just text blocks. let resolved; try { - resolved = resolveStructuralInsertTarget(editor, textTarget); + resolved = resolveStructuralInsertTarget(editor, target); } catch (err) { if (err instanceof DocumentApiAdapterError) throw err; throw new DocumentApiAdapterError( 'TARGET_NOT_FOUND', - `Cannot resolve insert target${textTarget ? ` for block "${textTarget.blockId}"` : ''}.`, + `Cannot resolve insert target${target ? ` for block "${target.nodeId}"` : ''}.`, ); } @@ -1116,7 +1117,6 @@ function executeStructuralInsertWrapper( const resolvedRange = { from: insertPos, to: insertPos }; const resolution = buildTextMutationResolution({ - requestedTarget: textTarget, target: effectiveTarget, range: resolvedRange, text: '', @@ -1127,7 +1127,7 @@ function executeStructuralInsertWrapper( // but skip dispatch. if (options?.dryRun) { executeStructuralInsertEngine(editor, { - target: textTarget, + target, content, placement, nestingPolicy, @@ -1141,7 +1141,7 @@ function executeStructuralInsertWrapper( editor, () => { const result = executeStructuralInsertEngine(editor, { - target: textTarget, + target, content, placement, nestingPolicy, @@ -1173,6 +1173,87 @@ function executeStructuralInsertWrapper( } } +/** + * Builds an SDMutationReceipt directly for structural inserts that target a + * BlockNodeAddress, preserving the original block address in the resolution + * instead of normalizing it to a synthetic TextAddress. + */ +function executeStructuralInsertDirect( + editor: Editor, + input: SDInsertInput, + options?: MutationOptions, +): SDMutationReceipt { + const { content, target, placement, nestingPolicy } = input; + const mode = options?.changeMode ?? 'direct'; + + // Resolve insert position directly from the BlockNodeAddress — no TextAddress conversion. + let resolved; + try { + resolved = resolveStructuralInsertTarget(editor, target); + } catch (err) { + if (err instanceof DocumentApiAdapterError) throw err; + throw new DocumentApiAdapterError( + 'TARGET_NOT_FOUND', + `Cannot resolve insert target for block "${target!.nodeId}".`, + ); + } + + let insertPos: number; + if (resolved.targetNode && resolved.targetNodePos !== undefined) { + insertPos = resolvePlacement(editor.state.doc, resolved.targetNodePos, resolved.targetNode, placement); + } else { + insertPos = resolved.insertPos; + } + + const range = { from: insertPos, to: insertPos }; + const receiptParams = { target: target!, range }; + + try { + if (options?.dryRun) { + executeStructuralInsertEngine(editor, { + target, + content, + placement, + nestingPolicy, + changeMode: mode, + dryRun: true, + }); + return buildStructuralReceipt(true, receiptParams); + } + + const receipt = executeDomainCommand( + editor, + () => { + const result = executeStructuralInsertEngine(editor, { + target, + content, + placement, + nestingPolicy, + changeMode: mode, + }); + return result.success; + }, + { expectedRevision: options?.expectedRevision, changeMode: mode }, + ); + + if (receipt.steps[0]?.effect !== 'changed') { + return buildStructuralReceipt(false, receiptParams, { + code: 'INVALID_TARGET', + message: 'Structural insert failed.', + }); + } + + return buildStructuralReceipt(true, receiptParams); + } catch (err) { + if (err instanceof DocumentApiAdapterError) throw err; + const message = err instanceof Error ? err.message : String(err); + return buildStructuralReceipt(false, receiptParams, { + code: 'INVALID_TARGET', + message: `Structural insert failed: ${message}`, + }); + } +} + // --------------------------------------------------------------------------- // Structural SDFragment replace wrapper // --------------------------------------------------------------------------- @@ -1194,17 +1275,32 @@ export function replaceStructuredWrapper( 'replaceStructured requires structural content input with a "content" field.', ); } - return textReceiptToSDReceipt(executeStructuralReplaceWrapper(editor, input, options)); + + // When the target is a BlockNodeAddress, re-wrap the receipt to preserve + // the block-level address instead of the synthetic TextAddress. + const blockTarget = + input.target && 'kind' in input.target && input.target.kind === 'block' + ? (input.target as BlockNodeAddress) + : undefined; + + const textReceipt = executeStructuralReplaceWrapper(editor, input, options); + if (!blockTarget) return textReceiptToSDReceipt(textReceipt); + + const sdReceipt = textReceiptToSDReceipt(textReceipt); + if (sdReceipt.resolution) { + sdReceipt.resolution.target = blockTarget; + } + return sdReceipt; } /** - * Resolved structural replace locator — contains the primary TextAddress + * Resolved structural replace locator — contains the primary target address * (for the engine's target parameter) and metadata about the actual * replacement scope for accurate receipt resolution. */ interface ResolvedStructuralLocator { - /** Primary block TextAddress — always points to the first targeted block. */ - textTarget: TextAddress; + /** Primary target — BlockNodeAddress for typed inputs, TextAddress for refs/selections. */ + textTarget: TextAddress | BlockNodeAddress; /** * Pre-resolved PM range spanning the full replacement area. * Present for SelectionTarget and multi-segment text ref locators. @@ -1229,7 +1325,7 @@ interface ResolvedStructuralLocator { * Resolves the target/ref locator from an SDReplaceInput into a * ResolvedStructuralLocator for the structural replace engine. * - * Single-block locators (SDAddress, TextAddress, raw nodeId ref) produce + * Single-block locators (BlockNodeAddress, raw nodeId ref) produce * only a `textTarget`. Multi-block locators (cross-block SelectionTarget, * multi-segment text refs) also produce a `resolvedRange` spanning the * full contiguous block range so the engine replaces all covered blocks. @@ -1262,8 +1358,8 @@ function resolveStructuralLocator(editor: Editor, input: SDReplaceInput): Resolv effectiveSelectionTarget: buildEffectiveSelectionTarget(expanded), }; } - // SDAddress | TextAddress — existing bridge (single block). - return { textTarget: narrowToTextAddress(target) }; + // BlockNodeAddress — pass through directly for typed block lookup. + return { textTarget: target }; } if (ref !== undefined) { @@ -1523,7 +1619,7 @@ function executeStructuralReplaceWrapper( if (err instanceof DocumentApiAdapterError) throw err; throw new DocumentApiAdapterError( 'TARGET_NOT_FOUND', - `Cannot resolve replace target for block "${textTarget.blockId}".`, + `Cannot resolve replace target for block "${targetBlockId(textTarget)}".`, ); } effectiveRange = { from: resolvedBlock.from, to: resolvedBlock.to }; @@ -1536,14 +1632,13 @@ function executeStructuralReplaceWrapper( // This covers both SelectionTarget inputs and multi-block ref inputs — both // produce an effectiveSelectionTarget describing the actual block-boundary scope. // For single-block inputs, fall back to the direct TextAddress resolution. + const textAddr = toTextAddress(textTarget); let resolution: TextMutationResolution; if (effectiveSelectionTarget) { resolution = selectionTargetToResolution(effectiveSelectionTarget, effectiveRange, coveredText); } else { resolution = buildTextMutationResolution({ - // Omit requestedTarget for ref-based calls — the textTarget is synthetic. - requestedTarget: isRefBased ? undefined : textTarget, - target: textTarget, + target: textAddr, range: effectiveRange, text: coveredText, }); diff --git a/packages/super-editor/src/document-api-adapters/plan-engine/query-match-adapter.ts b/packages/super-editor/src/document-api-adapters/plan-engine/query-match-adapter.ts index 86aeb612dd..ec5e6ead47 100644 --- a/packages/super-editor/src/document-api-adapters/plan-engine/query-match-adapter.ts +++ b/packages/super-editor/src/document-api-adapters/plan-engine/query-match-adapter.ts @@ -515,7 +515,8 @@ export function queryMatchAdapter(editor: Editor, input: QueryMatchInput): Query id, handle: buildResolvedHandle(ref, 'ephemeral', 'text'), matchKind: 'text', - address: raw.address, + // Text matches always resolve to a containing block address. + address: raw.address as import('@superdoc/document-api').BlockNodeAddress, target: buildSelectionTargetFromBlocks(blocks), snippet: snippetResult?.snippet ?? '', highlightRange: snippetResult?.highlightRange ?? { start: 0, end: 0 }, diff --git a/packages/super-editor/src/document-api-adapters/structural-write-engine/index.ts b/packages/super-editor/src/document-api-adapters/structural-write-engine/index.ts index e70c1ac5f4..f659088515 100644 --- a/packages/super-editor/src/document-api-adapters/structural-write-engine/index.ts +++ b/packages/super-editor/src/document-api-adapters/structural-write-engine/index.ts @@ -10,11 +10,11 @@ * TargetSelector → target-resolver → placement-resolver → insertion position */ -import type { SDFragment, SDContentNode, NestingPolicy, Placement, TextAddress } from '@superdoc/document-api'; +import type { SDFragment, SDContentNode, NestingPolicy, Placement } from '@superdoc/document-api'; import type { Node as ProseMirrorNode } from 'prosemirror-model'; import type { Editor } from '../../core/Editor.js'; import { materializeFragment, type SDWriteOp } from './node-materializer.js'; -import { resolveInsertTarget, resolveReplaceTarget } from './target-resolver.js'; +import { resolveInsertTarget, resolveReplaceTarget, type StructuralTarget } from './target-resolver.js'; import { resolvePlacement } from './placement-resolver.js'; import { enforceNestingPolicy } from './nesting-guard.js'; import { clearIndexCache } from '../helpers/index-cache.js'; @@ -28,7 +28,7 @@ import { DocumentApiAdapterError } from '../errors.js'; /** Options for structural insert. */ export interface StructuralInsertOptions { - target?: TextAddress; + target?: StructuralTarget; content: SDFragment; placement?: Placement; nestingPolicy?: NestingPolicy; @@ -40,7 +40,7 @@ export interface StructuralInsertOptions { /** Options for structural replace. */ export interface StructuralReplaceOptions { - target: TextAddress; + target: StructuralTarget; content: SDFragment; nestingPolicy?: NestingPolicy; /** Tracked or direct mode. When 'tracked', the transaction carries tracked-change metadata. */ diff --git a/packages/super-editor/src/document-api-adapters/structural-write-engine/structural-write-engine.test.ts b/packages/super-editor/src/document-api-adapters/structural-write-engine/structural-write-engine.test.ts index c447fbef16..eb53df195b 100644 --- a/packages/super-editor/src/document-api-adapters/structural-write-engine/structural-write-engine.test.ts +++ b/packages/super-editor/src/document-api-adapters/structural-write-engine/structural-write-engine.test.ts @@ -207,7 +207,7 @@ describe('replaceStructuredWrapper', () => { }); const blockId = seed.insertedBlockIds[0]!; - const target = { kind: 'text' as const, blockId, range: { start: 0, end: 8 } }; + const target = { kind: 'block' as const, nodeType: 'paragraph' as const, nodeId: blockId }; const result = replaceStructuredWrapper(editor, { target, content: { type: 'paragraph', content: [{ type: 'text', text: 'replaced' }] }, @@ -215,7 +215,9 @@ describe('replaceStructuredWrapper', () => { expect(result.success).toBe(true); expect(result.resolution).toBeDefined(); - expect(result.resolution!.target.nodeId).toBe(blockId); + // Block-targeted structural replace preserves BlockNodeAddress in the receipt. + expect(result.resolution!.target.kind).toBe('block'); + expect((result.resolution!.target as { nodeId: string }).nodeId).toBe(blockId); expect(editor.state.doc.textContent).toContain('replaced'); expect(editor.state.doc.textContent).not.toContain('old text'); }); @@ -226,17 +228,17 @@ describe('replaceStructuredWrapper', () => { }); const blockId = seed.insertedBlockIds[0]!; - const target = { kind: 'text' as const, blockId, range: { start: 0, end: 11 } }; + const target = { kind: 'block' as const, nodeType: 'paragraph' as const, nodeId: blockId }; const result = replaceStructuredWrapper(editor, { target, content: { type: 'paragraph', content: [{ type: 'text', text: 'new' }] }, }); expect(result.success).toBe(true); - // SDMutationReceipt resolution carries SDAddress (nodeId + anchor), not text snapshot. - // Verify the replace target was correctly resolved via the SDAddress. expect(result.resolution).toBeDefined(); - expect(result.resolution!.target.nodeId).toBe(blockId); + // Block-targeted structural replace preserves BlockNodeAddress in the receipt. + expect(result.resolution!.target.kind).toBe('block'); + expect((result.resolution!.target as { nodeId: string }).nodeId).toBe(blockId); }); it('replaces a table block via the wrapper', () => { @@ -255,7 +257,7 @@ describe('replaceStructuredWrapper', () => { }); const tableBlockId = seed.insertedBlockIds[0]!; - const target = { kind: 'text' as const, blockId: tableBlockId, range: { start: 0, end: 0 } }; + const target = { kind: 'block' as const, nodeType: 'table' as const, nodeId: tableBlockId }; const result = replaceStructuredWrapper(editor, { target, content: { type: 'paragraph', content: [{ type: 'text', text: 'table replaced' }] }, @@ -288,7 +290,7 @@ describe('replaceStructuredWrapper', () => { expect(() => validateDocumentFragment(parsed.fragment)).not.toThrow(); const result = replaceStructuredWrapper(editor, { - target: { kind: 'text', blockId: tableBlockId, range: { start: 0, end: 0 } }, + target: { kind: 'block', nodeType: 'table' as const, nodeId: tableBlockId }, content: parsed.fragment, }); @@ -315,7 +317,7 @@ describe('replaceStructuredWrapper', () => { const blockId = seed.insertedBlockIds[0]!; const textBefore = editor.state.doc.textContent; - const target = { kind: 'text' as const, blockId, range: { start: 0, end: 7 } }; + const target = { kind: 'block' as const, nodeType: 'paragraph' as const, nodeId: blockId }; const result = replaceStructuredWrapper( editor, { @@ -340,7 +342,7 @@ describe('replaceStructuredWrapper', () => { const result = replaceStructuredWrapper( editor, { - target: { kind: 'text', blockId, range: { start: 0, end: 11 } }, + target: { kind: 'block', nodeType: 'paragraph' as const, nodeId: blockId }, content: { type: 'paragraph', content: [{ type: 'text', text: 'tracked new' }] }, }, { changeMode: 'tracked' }, @@ -361,7 +363,7 @@ describe('replaceStructuredWrapper', () => { const paragraphInCellId = requireFirstParagraphInsideTableCellBlockId(editor); const input = { - target: { kind: 'text' as const, blockId: paragraphInCellId, range: { start: 0, end: 0 } }, + target: { kind: 'block' as const, nodeType: 'paragraph' as const, nodeId: paragraphInCellId }, content: tableFragment, }; @@ -389,7 +391,7 @@ describe('insertStructuredWrapper — placement receipt', () => { }); const blockId = seed.insertedBlockIds[0]!; - const target = { kind: 'text' as const, blockId, range: { start: 0, end: 6 } }; + const target = { kind: 'block' as const, nodeType: 'paragraph' as const, nodeId: blockId }; const result = insertStructuredWrapper(editor, { target, content: { type: 'paragraph', content: [{ type: 'text', text: 'before' }] }, @@ -397,7 +399,7 @@ describe('insertStructuredWrapper — placement receipt', () => { }); expect(result.success).toBe(true); - // "before" placement: receipt carries a valid SDAddress resolution. + // "before" placement: receipt carries a valid TextAddress resolution. expect(result.resolution).toBeDefined(); expect(result.resolution!.target).toBeDefined(); }); @@ -408,7 +410,7 @@ describe('insertStructuredWrapper — placement receipt', () => { }); const blockId = seed.insertedBlockIds[0]!; - const target = { kind: 'text' as const, blockId, range: { start: 0, end: 6 } }; + const target = { kind: 'block' as const, nodeType: 'paragraph' as const, nodeId: blockId }; const resultAfter = insertStructuredWrapper(editor, { target, content: { type: 'paragraph', content: [{ type: 'text', text: 'after' }] }, @@ -423,7 +425,7 @@ describe('insertStructuredWrapper — placement receipt', () => { expect(resultAfter.success).toBe(true); expect(resultBefore.success).toBe(true); - // Both inserts target the same block, so the SDAddress anchors reflect insertion points. + // Both inserts target the same block, so the TextAddress anchors reflect insertion points. // Verify both receipts carry valid resolution. expect(resultBefore.resolution).toBeDefined(); expect(resultAfter.resolution).toBeDefined(); @@ -456,7 +458,7 @@ describe('insertStructuredWrapper — placement receipt', () => { const cellBlockId = requireFirstTableCellBlockId(editor); const input = { - target: { kind: 'text' as const, blockId: cellBlockId, range: { start: 0, end: 0 } }, + target: { kind: 'block' as const, nodeType: 'tableCell' as const, nodeId: cellBlockId }, content: tableFragment, placement: 'insideStart' as const, }; @@ -1146,7 +1148,7 @@ describe('replaceStructuredWrapper — multi-block and locator forms', () => { expect(editor.state.doc.textContent).not.toContain('ref-target'); }); - it('omits requestedTarget for ref-based structural replace receipts', () => { + it('ref-based structural replace produces a valid resolution without extra fields', () => { const ids = seedParagraphs(['no-requested']); const result = replaceStructuredWrapper(editor, { @@ -1156,8 +1158,8 @@ describe('replaceStructuredWrapper — multi-block and locator forms', () => { expect(result.success).toBe(true); expect(result.resolution).toBeDefined(); - // Ref-based calls should NOT report a fabricated requestedTarget. - expect(result.resolution!.requestedTarget).toBeUndefined(); + expect(result.resolution!.target).toBeDefined(); + expect(result.resolution!.range).toBeDefined(); }); it('replaces a single block via single-block SelectionTarget (no selectionTarget in receipt)', () => { @@ -1248,7 +1250,7 @@ describe('replaceStructuredWrapper — multi-block and locator forms', () => { // Single-block: no selectionTarget needed. expect(result.resolution!.selectionTarget).toBeUndefined(); // The target should report full block (offset 0), not the partial offset. - expect(result.resolution!.target.nodeId).toBe(ids[0]); + expect(result.resolution!.target.blockId).toBe(ids[0]); }); it('multi-segment text: ref replaces all segments and includes selectionTarget', () => { @@ -1281,8 +1283,6 @@ describe('replaceStructuredWrapper — multi-block and locator forms', () => { // Multi-block ref: receipt should carry selectionTarget. expect(result.resolution!.selectionTarget).toBeDefined(); expect(result.resolution!.selectionTarget!.kind).toBe('selection'); - // Should NOT have a fabricated requestedTarget. - expect(result.resolution!.requestedTarget).toBeUndefined(); }); it('single-segment text: ref replaces one block without selectionTarget', () => { diff --git a/packages/super-editor/src/document-api-adapters/structural-write-engine/target-resolver.ts b/packages/super-editor/src/document-api-adapters/structural-write-engine/target-resolver.ts index e163f9c1e2..cf0a92c8da 100644 --- a/packages/super-editor/src/document-api-adapters/structural-write-engine/target-resolver.ts +++ b/packages/super-editor/src/document-api-adapters/structural-write-engine/target-resolver.ts @@ -12,14 +12,17 @@ * so tr.replaceWith replaces the entire block, not just its text content. */ -import type { TextAddress } from '@superdoc/document-api'; +import type { BlockNodeAddress, TextAddress } from '@superdoc/document-api'; import type { Node as ProseMirrorNode } from 'prosemirror-model'; import type { Editor } from '../../core/Editor.js'; import { resolveDefaultInsertTarget } from '../helpers/adapter-utils.js'; import { getBlockIndex } from '../helpers/index-cache.js'; -import { findBlockByNodeIdOnly } from '../helpers/node-address-resolver.js'; +import { findBlockByIdStrict, findBlockByNodeIdOnly } from '../helpers/node-address-resolver.js'; import { DocumentApiAdapterError } from '../errors.js'; +/** Target selector for structural operations — either a typed block address or a text address. */ +export type StructuralTarget = BlockNodeAddress | TextAddress; + /** Resolved insertion target with absolute ProseMirror position. */ export interface ResolvedInsertTarget { /** Absolute ProseMirror position for insertion. */ @@ -45,61 +48,69 @@ export interface ResolvedReplaceTarget { } /** - * Resolves an optional TextAddress target to an absolute ProseMirror insertion position. + * Resolves a block candidate from a structural target. + * + * When the target is a BlockNodeAddress, uses the composite `nodeType:nodeId` + * key via {@link findBlockByIdStrict} — this disambiguates duplicate nodeIds + * that differ by type. TextAddress targets fall back to + * {@link findBlockByNodeIdOnly} for alias-aware resolution. + */ +function findBlockByTarget(index: ReturnType, target: StructuralTarget, operationName: string) { + const nodeId = target.kind === 'block' ? target.nodeId : target.blockId; + try { + if (target.kind === 'block') { + return findBlockByIdStrict(index, target); + } + return findBlockByNodeIdOnly(index, nodeId); + } catch { + throw new DocumentApiAdapterError( + 'TARGET_NOT_FOUND', + `Cannot resolve ${operationName} target for block "${nodeId}".`, + ); + } +} + +/** + * Resolves an optional target to an absolute ProseMirror insertion position. * * Uses block-level lookup so ALL block types (paragraphs, tables, images, etc.) * are addressable — not just text blocks. * * When target is omitted, falls back to end-of-document insertion. */ -export function resolveInsertTarget(editor: Editor, target?: TextAddress): ResolvedInsertTarget { +export function resolveInsertTarget(editor: Editor, target?: StructuralTarget): ResolvedInsertTarget { if (!target) { return resolveDocumentEndTarget(editor); } - // Block-level resolution: find the block by ID, supporting all block types. const index = getBlockIndex(editor); - let candidate; - try { - candidate = findBlockByNodeIdOnly(index, target.blockId); - } catch { - throw new DocumentApiAdapterError( - 'TARGET_NOT_FOUND', - `Cannot resolve insert target for block "${target.blockId}".`, - ); - } + const candidate = findBlockByTarget(index, target, 'insert'); return { insertPos: candidate.end, structuralEnd: false, - effectiveTarget: target, + effectiveTarget: + target.kind === 'block' ? { kind: 'text', blockId: target.nodeId, range: { start: 0, end: 0 } } : target, targetNode: candidate.node, targetNodePos: candidate.pos, }; } /** - * Resolves a required TextAddress target for structural replace operations. + * Resolves a required target for structural replace operations. * * Resolves to the FULL block node range. This ensures tr.replaceWith * replaces the entire block — not just its text content. */ -export function resolveReplaceTarget(editor: Editor, target: TextAddress): ResolvedReplaceTarget { +export function resolveReplaceTarget(editor: Editor, target: StructuralTarget): ResolvedReplaceTarget { const index = getBlockIndex(editor); - let candidate; - try { - candidate = findBlockByNodeIdOnly(index, target.blockId); - } catch { - throw new DocumentApiAdapterError( - 'TARGET_NOT_FOUND', - `Cannot resolve replace target for block "${target.blockId}".`, - ); - } + const candidate = findBlockByTarget(index, target, 'replace'); return { from: candidate.pos, to: candidate.end, - effectiveTarget: target, + effectiveTarget: + target.kind === 'block' ? { kind: 'text', blockId: target.nodeId, range: { start: 0, end: 0 } } : target, }; } diff --git a/tests/behavior/fixtures/superdoc.ts b/tests/behavior/fixtures/superdoc.ts index 711f27f4dc..6f179e2795 100644 --- a/tests/behavior/fixtures/superdoc.ts +++ b/tests/behavior/fixtures/superdoc.ts @@ -221,9 +221,8 @@ function createFixture(page: Page, editor: Locator, modKey: string) { const toWithinAddress = (address: any): any => { if (!address || typeof address !== 'object') return null; - if (address.kind === 'content' || address.kind === 'inline') return address; if (address.kind === 'block' && typeof address.nodeId === 'string' && address.nodeId.length > 0) { - return { kind: 'content', stability: 'stable', nodeId: address.nodeId }; + return address; } return null; }; @@ -308,7 +307,7 @@ function createFixture(page: Page, editor: Locator, modKey: string) { .filter(Boolean); const hyperlinkResult = docApi.find({ - select: { type: 'node', nodeKind: 'hyperlink', kind: 'inline' }, + select: { type: 'node', nodeType: 'hyperlink', kind: 'inline' }, within: withinAddress, }); @@ -731,14 +730,14 @@ function createFixture(page: Page, editor: Locator, modKey: string) { return Array.isArray(result?.matches) ? result.matches : []; }; - const tableResult = docApi.find({ select: { type: 'node', nodeKind: 'table' }, limit: 1 }); + const tableResult = docApi.find({ select: { type: 'node', nodeType: 'table' }, limit: 1 }); const tableAddress = getAddresses(tableResult)[0]; if (!tableAddress) return 'no table found in document'; if (expectedRows !== undefined && expectedCols !== undefined) { const expectedCellCount = expectedRows * expectedCols; - const rowResult = docApi.find({ select: { type: 'node', nodeKind: 'tableRow' }, within: tableAddress }); + const rowResult = docApi.find({ select: { type: 'node', nodeType: 'tableRow' }, within: tableAddress }); const rowCount = getAddresses(rowResult).length; // Only validate row count when the adapter exposes row-level querying. @@ -747,13 +746,13 @@ function createFixture(page: Page, editor: Locator, modKey: string) { } const cellResult = docApi.find({ - select: { type: 'node', nodeKind: 'tableCell' }, + select: { type: 'node', nodeType: 'tableCell' }, within: tableAddress, }); let cellCount = getAddresses(cellResult).length; try { const headerResult = docApi.find({ - select: { type: 'node', nodeKind: 'tableHeader' }, + select: { type: 'node', nodeType: 'tableHeader' }, within: tableAddress, }); cellCount += getAddresses(headerResult).length; @@ -764,7 +763,7 @@ function createFixture(page: Page, editor: Locator, modKey: string) { // Fallback: count paragraphs when cell-level querying isn't available. if (cellCount === 0) { const paragraphResult = docApi.find({ - select: { type: 'node', nodeKind: 'paragraph' }, + select: { type: 'node', nodeType: 'paragraph' }, within: tableAddress, }); cellCount = getAddresses(paragraphResult).length; diff --git a/tests/behavior/helpers/table.ts b/tests/behavior/helpers/table.ts index be6184d0d6..394e53132f 100644 --- a/tests/behavior/helpers/table.ts +++ b/tests/behavior/helpers/table.ts @@ -21,15 +21,15 @@ export async function countTableCells(page: Page): Promise { return Array.isArray(result?.matches) ? result.matches : []; }; - const tableResult = docApi.find({ select: { type: 'node', nodeKind: 'table' }, limit: 1 }); + const tableResult = docApi.find({ select: { type: 'node', nodeType: 'table' }, limit: 1 }); const tableAddress = getAddresses(tableResult)[0]; if (!tableAddress) return 0; - const cellResult = docApi.find({ select: { type: 'node', nodeKind: 'tableCell' }, within: tableAddress }); + const cellResult = docApi.find({ select: { type: 'node', nodeType: 'tableCell' }, within: tableAddress }); let cellCount = getAddresses(cellResult).length; try { - const headerResult = docApi.find({ select: { type: 'node', nodeKind: 'tableHeader' }, within: tableAddress }); + const headerResult = docApi.find({ select: { type: 'node', nodeType: 'tableHeader' }, within: tableAddress }); cellCount += getAddresses(headerResult).length; } catch { /* tableHeader may not be queryable */ @@ -38,7 +38,7 @@ export async function countTableCells(page: Page): Promise { if (cellCount > 0) return cellCount; // Fallback: count paragraphs when cell-level querying isn't available. - const paragraphResult = docApi.find({ select: { type: 'node', nodeKind: 'paragraph' }, within: tableAddress }); + const paragraphResult = docApi.find({ select: { type: 'node', nodeType: 'paragraph' }, within: tableAddress }); return getAddresses(paragraphResult).length; }); } From 2a3696517e4d31261ff0b3e9e5efa572773f7dd6 Mon Sep 17 00:00:00 2001 From: Nick Bernal Date: Mon, 16 Mar 2026 14:46:21 -0700 Subject: [PATCH 3/5] fix(document-api): return canonical nodeId in getNodeById address --- .../document-api-adapters/get-node-adapter.ts | 5 ++- .../structural-write-engine.test.ts | 35 +++++++++++++++++++ .../target-resolver.ts | 19 ++++++---- 3 files changed, 52 insertions(+), 7 deletions(-) diff --git a/packages/super-editor/src/document-api-adapters/get-node-adapter.ts b/packages/super-editor/src/document-api-adapters/get-node-adapter.ts index d7d1dbf025..22c2fd429b 100644 --- a/packages/super-editor/src/document-api-adapters/get-node-adapter.ts +++ b/packages/super-editor/src/document-api-adapters/get-node-adapter.ts @@ -131,6 +131,9 @@ export function getNodeByIdAdapter(editor: Editor, input: GetNodeByIdInput): SDN const { candidate, resolvedType } = resolveBlockById(editor, nodeId, nodeType); return { node: projectContentNode(candidate.node), - address: { kind: 'block', nodeType: resolvedType, nodeId } as NodeAddress, + // Use candidate.nodeId (the canonical ID) rather than the caller's input, + // which may be an alias (e.g. sdBlockId). This ensures the emitted address + // is resolvable by getNode(), which looks up by primary nodeId. + address: { kind: 'block', nodeType: resolvedType, nodeId: candidate.nodeId } as NodeAddress, }; } diff --git a/packages/super-editor/src/document-api-adapters/structural-write-engine/structural-write-engine.test.ts b/packages/super-editor/src/document-api-adapters/structural-write-engine/structural-write-engine.test.ts index eb53df195b..3521a56821 100644 --- a/packages/super-editor/src/document-api-adapters/structural-write-engine/structural-write-engine.test.ts +++ b/packages/super-editor/src/document-api-adapters/structural-write-engine/structural-write-engine.test.ts @@ -241,6 +241,41 @@ describe('replaceStructuredWrapper', () => { expect((result.resolution!.target as { nodeId: string }).nodeId).toBe(blockId); }); + it('resolves a block-targeted replace after the paragraph subtype changes', () => { + // Seed a plain paragraph and capture its address as nodeType: 'paragraph'. + const seed = executeStructuralInsert(editor, { + content: { type: 'paragraph', content: [{ type: 'text', text: 'will restyle' }] }, + }); + const blockId = seed.insertedBlockIds[0]!; + const staleAddress = { kind: 'block' as const, nodeType: 'paragraph' as const, nodeId: blockId }; + + // Restyle the paragraph to a heading by setting styleId — this changes + // mapBlockNodeType() from 'paragraph' to 'heading', making the saved + // nodeType stale. + const { doc, tr } = editor.state; + doc.descendants((node, pos) => { + if (node.type.name === 'paragraph' && node.attrs.sdBlockId === blockId) { + tr.setNodeMarkup(pos, undefined, { + ...node.attrs, + paragraphProperties: { ...node.attrs.paragraphProperties, styleId: 'Heading1' }, + }); + return false; + } + }); + editor.dispatch(tr); + + // The stale address (nodeType: 'paragraph') should still resolve because + // the structural target resolver falls back to nodeId-only lookup. + const result = replaceStructuredWrapper(editor, { + target: staleAddress, + content: { type: 'paragraph', content: [{ type: 'text', text: 'after restyle' }] }, + }); + + expect(result.success).toBe(true); + expect(editor.state.doc.textContent).toContain('after restyle'); + expect(editor.state.doc.textContent).not.toContain('will restyle'); + }); + it('replaces a table block via the wrapper', () => { const seed = executeStructuralInsert(editor, { content: { diff --git a/packages/super-editor/src/document-api-adapters/structural-write-engine/target-resolver.ts b/packages/super-editor/src/document-api-adapters/structural-write-engine/target-resolver.ts index cf0a92c8da..1dacdc4779 100644 --- a/packages/super-editor/src/document-api-adapters/structural-write-engine/target-resolver.ts +++ b/packages/super-editor/src/document-api-adapters/structural-write-engine/target-resolver.ts @@ -17,7 +17,7 @@ import type { Node as ProseMirrorNode } from 'prosemirror-model'; import type { Editor } from '../../core/Editor.js'; import { resolveDefaultInsertTarget } from '../helpers/adapter-utils.js'; import { getBlockIndex } from '../helpers/index-cache.js'; -import { findBlockByIdStrict, findBlockByNodeIdOnly } from '../helpers/node-address-resolver.js'; +import { findBlockById, findBlockByNodeIdOnly } from '../helpers/node-address-resolver.js'; import { DocumentApiAdapterError } from '../errors.js'; /** Target selector for structural operations — either a typed block address or a text address. */ @@ -50,16 +50,23 @@ export interface ResolvedReplaceTarget { /** * Resolves a block candidate from a structural target. * - * When the target is a BlockNodeAddress, uses the composite `nodeType:nodeId` - * key via {@link findBlockByIdStrict} — this disambiguates duplicate nodeIds - * that differ by type. TextAddress targets fall back to - * {@link findBlockByNodeIdOnly} for alias-aware resolution. + * For BlockNodeAddress targets, tries the composite `nodeType:nodeId` key first + * to disambiguate duplicate IDs, then falls back to nodeId-only lookup. The + * fallback is necessary because paragraph-backed blocks can change subtype + * (paragraph/heading/listItem) via mutable attrs — a saved address from + * find() or getNodeById() should still resolve after a restyle. + * + * TextAddress targets always use nodeId-only (alias-aware) resolution. */ function findBlockByTarget(index: ReturnType, target: StructuralTarget, operationName: string) { const nodeId = target.kind === 'block' ? target.nodeId : target.blockId; try { if (target.kind === 'block') { - return findBlockByIdStrict(index, target); + // Typed lookup first — handles duplicate IDs across different block types. + const typed = findBlockById(index, target); + if (typed) return typed; + // Fallback to nodeId-only — handles stale subtypes after restyle. + return findBlockByNodeIdOnly(index, nodeId); } return findBlockByNodeIdOnly(index, nodeId); } catch { From cfd4705bd3b31d351b7b424f3697462bae858f72 Mon Sep 17 00:00:00 2001 From: Nick Bernal Date: Mon, 16 Mar 2026 15:01:56 -0700 Subject: [PATCH 4/5] chore: update docs --- .../reference/_generated-manifest.json | 2 +- .../reference/authorities/configure.mdx | 2 +- .../reference/authorities/entries-insert.mdx | 2 +- .../reference/authorities/entries-remove.mdx | 2 +- .../reference/authorities/entries-update.mdx | 2 +- .../reference/authorities/insert.mdx | 2 +- .../reference/authorities/rebuild.mdx | 2 +- .../reference/authorities/remove.mdx | 2 +- .../reference/bookmarks/insert.mdx | 2 +- .../reference/bookmarks/remove.mdx | 2 +- .../reference/bookmarks/rename.mdx | 2 +- .../reference/capabilities/get.mdx | 2041 ++++------------- .../reference/captions/insert.mdx | 2 +- .../reference/captions/remove.mdx | 2 +- .../reference/captions/update.mdx | 2 +- .../citations/bibliography-configure.mdx | 2 +- .../citations/bibliography-insert.mdx | 2 +- .../citations/bibliography-rebuild.mdx | 2 +- .../citations/bibliography-remove.mdx | 2 +- .../reference/citations/insert.mdx | 2 +- .../reference/citations/remove.mdx | 2 +- .../reference/citations/sources-insert.mdx | 2 +- .../reference/citations/sources-remove.mdx | 2 +- .../reference/citations/sources-update.mdx | 2 +- .../reference/citations/update.mdx | 2 +- .../document-api/reference/create/heading.mdx | 2 +- .../reference/create/paragraph.mdx | 2 +- .../reference/create/section-break.mdx | 2 +- .../reference/create/table-of-contents.mdx | 2 +- .../document-api/reference/create/table.mdx | 2 +- .../reference/cross-refs/insert.mdx | 2 +- .../reference/cross-refs/rebuild.mdx | 2 +- .../reference/cross-refs/remove.mdx | 2 +- apps/docs/document-api/reference/delete.mdx | 4 +- .../document-api/reference/fields/insert.mdx | 2 +- .../document-api/reference/fields/rebuild.mdx | 2 +- .../document-api/reference/fields/remove.mdx | 2 +- .../reference/footnotes/insert.mdx | 2 +- .../reference/footnotes/remove.mdx | 2 +- .../reference/footnotes/update.mdx | 2 +- .../document-api/reference/format/apply.mdx | 4 +- .../document-api/reference/format/b-cs.mdx | 4 +- .../document-api/reference/format/bold.mdx | 4 +- .../document-api/reference/format/border.mdx | 4 +- .../document-api/reference/format/caps.mdx | 4 +- .../reference/format/char-scale.mdx | 4 +- .../document-api/reference/format/color.mdx | 4 +- .../format/contextual-alternates.mdx | 4 +- .../docs/document-api/reference/format/cs.mdx | 4 +- .../document-api/reference/format/dstrike.mdx | 4 +- .../reference/format/east-asian-layout.mdx | 4 +- .../docs/document-api/reference/format/em.mdx | 4 +- .../document-api/reference/format/emboss.mdx | 4 +- .../reference/format/fit-text.mdx | 4 +- .../reference/format/font-family.mdx | 4 +- .../reference/format/font-size-cs.mdx | 4 +- .../reference/format/font-size.mdx | 4 +- .../reference/format/highlight.mdx | 4 +- .../document-api/reference/format/i-cs.mdx | 4 +- .../document-api/reference/format/imprint.mdx | 4 +- .../document-api/reference/format/italic.mdx | 4 +- .../document-api/reference/format/kerning.mdx | 4 +- .../document-api/reference/format/lang.mdx | 4 +- .../reference/format/letter-spacing.mdx | 4 +- .../reference/format/ligatures.mdx | 4 +- .../reference/format/num-form.mdx | 4 +- .../reference/format/num-spacing.mdx | 4 +- .../document-api/reference/format/o-math.mdx | 4 +- .../document-api/reference/format/outline.mdx | 4 +- .../reference/format/position.mdx | 4 +- .../document-api/reference/format/r-fonts.mdx | 4 +- .../document-api/reference/format/r-style.mdx | 4 +- .../document-api/reference/format/rtl.mdx | 4 +- .../document-api/reference/format/shading.mdx | 4 +- .../document-api/reference/format/shadow.mdx | 4 +- .../reference/format/small-caps.mdx | 4 +- .../reference/format/snap-to-grid.mdx | 4 +- .../reference/format/spec-vanish.mdx | 4 +- .../document-api/reference/format/strike.mdx | 4 +- .../reference/format/stylistic-sets.mdx | 4 +- .../reference/format/underline.mdx | 4 +- .../document-api/reference/format/vanish.mdx | 4 +- .../reference/format/vert-align.mdx | 4 +- .../reference/format/web-hidden.mdx | 4 +- .../reference/header-footers/refs/clear.mdx | 2 +- .../refs/set-linked-to-previous.mdx | 2 +- .../reference/header-footers/refs/set.mdx | 2 +- .../reference/hyperlinks/insert.mdx | 2 +- .../reference/hyperlinks/patch.mdx | 2 +- .../reference/hyperlinks/remove.mdx | 2 +- .../reference/hyperlinks/wrap.mdx | 2 +- .../reference/index/configure.mdx | 2 +- .../reference/index/entries-insert.mdx | 2 +- .../reference/index/entries-remove.mdx | 2 +- .../reference/index/entries-update.mdx | 2 +- .../document-api/reference/index/insert.mdx | 2 +- .../document-api/reference/index/rebuild.mdx | 2 +- .../document-api/reference/index/remove.mdx | 2 +- apps/docs/document-api/reference/insert.mdx | 149 +- .../reference/lists/apply-preset.mdx | 2 +- .../reference/lists/apply-template.mdx | 2 +- .../document-api/reference/lists/attach.mdx | 2 +- .../reference/lists/clear-level-overrides.mdx | 2 +- .../reference/lists/continue-previous.mdx | 2 +- .../reference/lists/convert-to-text.mdx | 2 +- .../document-api/reference/lists/create.mdx | 2 +- .../document-api/reference/lists/detach.mdx | 2 +- .../document-api/reference/lists/indent.mdx | 2 +- .../document-api/reference/lists/insert.mdx | 2 +- .../document-api/reference/lists/outdent.mdx | 2 +- .../reference/lists/set-level-alignment.mdx | 2 +- .../reference/lists/set-level-bullet.mdx | 2 +- .../reference/lists/set-level-indents.mdx | 2 +- .../reference/lists/set-level-marker-font.mdx | 2 +- .../reference/lists/set-level-numbering.mdx | 2 +- .../lists/set-level-picture-bullet.mdx | 2 +- .../reference/lists/set-level-restart.mdx | 2 +- .../lists/set-level-trailing-character.mdx | 2 +- .../reference/lists/set-level.mdx | 2 +- .../document-api/reference/lists/set-type.mdx | 2 +- .../reference/lists/set-value.mdx | 2 +- apps/docs/document-api/reference/replace.mdx | 80 +- .../sections/clear-header-footer-ref.mdx | 2 +- .../reference/sections/clear-page-borders.mdx | 2 +- .../reference/sections/set-break-type.mdx | 2 +- .../reference/sections/set-columns.mdx | 2 +- .../sections/set-header-footer-margins.mdx | 2 +- .../sections/set-header-footer-ref.mdx | 2 +- .../reference/sections/set-line-numbering.mdx | 2 +- .../sections/set-link-to-previous.mdx | 2 +- .../reference/sections/set-page-borders.mdx | 2 +- .../reference/sections/set-page-margins.mdx | 2 +- .../reference/sections/set-page-numbering.mdx | 2 +- .../reference/sections/set-page-setup.mdx | 2 +- .../sections/set-section-direction.mdx | 2 +- .../reference/sections/set-title-page.mdx | 2 +- .../reference/sections/set-vertical-align.mdx | 2 +- .../reference/tables/apply-border-preset.mdx | 2 +- .../reference/tables/clear-border.mdx | 2 +- .../reference/tables/clear-cell-spacing.mdx | 2 +- .../reference/tables/clear-contents.mdx | 2 +- .../reference/tables/clear-shading.mdx | 2 +- .../reference/tables/clear-style.mdx | 2 +- .../reference/tables/convert-from-text.mdx | 2 +- .../reference/tables/convert-to-text.mdx | 2 +- .../reference/tables/delete-cell.mdx | 2 +- .../reference/tables/delete-column.mdx | 2 +- .../reference/tables/delete-row.mdx | 2 +- .../document-api/reference/tables/delete.mdx | 2 +- .../reference/tables/distribute-columns.mdx | 2 +- .../reference/tables/distribute-rows.mdx | 2 +- .../reference/tables/insert-cell.mdx | 2 +- .../reference/tables/insert-column.mdx | 2 +- .../reference/tables/insert-row.mdx | 2 +- .../reference/tables/merge-cells.mdx | 2 +- .../document-api/reference/tables/move.mdx | 2 +- .../reference/tables/set-alt-text.mdx | 2 +- .../reference/tables/set-border.mdx | 2 +- .../reference/tables/set-cell-padding.mdx | 2 +- .../reference/tables/set-cell-properties.mdx | 2 +- .../reference/tables/set-cell-spacing.mdx | 2 +- .../reference/tables/set-column-width.mdx | 2 +- .../reference/tables/set-layout.mdx | 2 +- .../reference/tables/set-row-height.mdx | 2 +- .../reference/tables/set-row-options.mdx | 2 +- .../reference/tables/set-shading.mdx | 2 +- .../reference/tables/set-style-option.mdx | 2 +- .../reference/tables/set-style.mdx | 2 +- .../reference/tables/set-table-padding.mdx | 2 +- .../document-api/reference/tables/sort.mdx | 2 +- .../reference/tables/split-cell.mdx | 2 +- .../document-api/reference/tables/split.mdx | 2 +- .../reference/tables/unmerge-cells.mdx | 2 +- .../document-api/reference/toc/configure.mdx | 2 +- .../document-api/reference/toc/edit-entry.mdx | 2 +- .../document-api/reference/toc/mark-entry.mdx | 2 +- .../document-api/reference/toc/remove.mdx | 2 +- .../reference/toc/unmark-entry.mdx | 2 +- .../document-api/reference/toc/update.mdx | 2 +- .../scripts/lib/reference-docs-artifacts.ts | 176 +- packages/document-api/src/README.md | 40 +- .../src/contract/contract.test.ts | 53 +- .../src/contract/operation-definitions.ts | 2 +- packages/document-api/src/contract/schemas.ts | 39 +- .../src/overview-examples.test.ts | 40 +- 185 files changed, 1135 insertions(+), 1927 deletions(-) diff --git a/apps/docs/document-api/reference/_generated-manifest.json b/apps/docs/document-api/reference/_generated-manifest.json index 31200dc8d9..6a6fc54c34 100644 --- a/apps/docs/document-api/reference/_generated-manifest.json +++ b/apps/docs/document-api/reference/_generated-manifest.json @@ -951,5 +951,5 @@ } ], "marker": "{/* GENERATED FILE: DO NOT EDIT. Regenerate via `pnpm run docapi:sync`. */}", - "sourceHash": "414b3ae9575b723c5618dbcaa69abb048c3378bd00f7157d74cd780804058d43" + "sourceHash": "b52520ee9b80ed98b8bb191aeec45df6488bdd1ee406009553247cfec58cfea1" } diff --git a/apps/docs/document-api/reference/authorities/configure.mdx b/apps/docs/document-api/reference/authorities/configure.mdx index 65c0e25c62..08e5730515 100644 --- a/apps/docs/document-api/reference/authorities/configure.mdx +++ b/apps/docs/document-api/reference/authorities/configure.mdx @@ -58,7 +58,7 @@ Returns an AuthoritiesMutationResult indicating success or a failure. ## Output fields -### Variant 1 (authorities.kind="block") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/authorities/entries-insert.mdx b/apps/docs/document-api/reference/authorities/entries-insert.mdx index 65b1ab94db..2fc5a4f767 100644 --- a/apps/docs/document-api/reference/authorities/entries-insert.mdx +++ b/apps/docs/document-api/reference/authorities/entries-insert.mdx @@ -65,7 +65,7 @@ Returns an AuthorityEntryMutationResult indicating success with the entry addres ## Output fields -### Variant 1 (entry.kind="inline") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/authorities/entries-remove.mdx b/apps/docs/document-api/reference/authorities/entries-remove.mdx index 58697865ab..07562ac8a3 100644 --- a/apps/docs/document-api/reference/authorities/entries-remove.mdx +++ b/apps/docs/document-api/reference/authorities/entries-remove.mdx @@ -62,7 +62,7 @@ Returns an AuthorityEntryMutationResult indicating success or a failure. ## Output fields -### Variant 1 (entry.kind="inline") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/authorities/entries-update.mdx b/apps/docs/document-api/reference/authorities/entries-update.mdx index f2d28eaace..676ce3134d 100644 --- a/apps/docs/document-api/reference/authorities/entries-update.mdx +++ b/apps/docs/document-api/reference/authorities/entries-update.mdx @@ -72,7 +72,7 @@ Returns an AuthorityEntryMutationResult indicating success or a failure. ## Output fields -### Variant 1 (entry.kind="inline") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/authorities/insert.mdx b/apps/docs/document-api/reference/authorities/insert.mdx index e4d1a794a0..83986909a6 100644 --- a/apps/docs/document-api/reference/authorities/insert.mdx +++ b/apps/docs/document-api/reference/authorities/insert.mdx @@ -53,7 +53,7 @@ Returns an AuthoritiesMutationResult indicating success with the TOA address or ## Output fields -### Variant 1 (authorities.kind="block") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/authorities/rebuild.mdx b/apps/docs/document-api/reference/authorities/rebuild.mdx index d61e1eeee5..02d07b1566 100644 --- a/apps/docs/document-api/reference/authorities/rebuild.mdx +++ b/apps/docs/document-api/reference/authorities/rebuild.mdx @@ -47,7 +47,7 @@ Returns an AuthoritiesMutationResult indicating success or a failure. ## Output fields -### Variant 1 (authorities.kind="block") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/authorities/remove.mdx b/apps/docs/document-api/reference/authorities/remove.mdx index 35fd9c1dfd..392b2e1a2b 100644 --- a/apps/docs/document-api/reference/authorities/remove.mdx +++ b/apps/docs/document-api/reference/authorities/remove.mdx @@ -47,7 +47,7 @@ Returns an AuthoritiesMutationResult indicating success or a failure. ## Output fields -### Variant 1 (authorities.kind="block") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/bookmarks/insert.mdx b/apps/docs/document-api/reference/bookmarks/insert.mdx index 0aacef73c0..a025780413 100644 --- a/apps/docs/document-api/reference/bookmarks/insert.mdx +++ b/apps/docs/document-api/reference/bookmarks/insert.mdx @@ -62,7 +62,7 @@ Returns a BookmarkMutationResult indicating success with the bookmark address or ## Output fields -### Variant 1 (bookmark.kind="entity") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/bookmarks/remove.mdx b/apps/docs/document-api/reference/bookmarks/remove.mdx index 1c85b6d8ad..7142f8b338 100644 --- a/apps/docs/document-api/reference/bookmarks/remove.mdx +++ b/apps/docs/document-api/reference/bookmarks/remove.mdx @@ -47,7 +47,7 @@ Returns a BookmarkMutationResult indicating success or a failure. ## Output fields -### Variant 1 (bookmark.kind="entity") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/bookmarks/rename.mdx b/apps/docs/document-api/reference/bookmarks/rename.mdx index 44a0629cd5..d1fe9309a7 100644 --- a/apps/docs/document-api/reference/bookmarks/rename.mdx +++ b/apps/docs/document-api/reference/bookmarks/rename.mdx @@ -49,7 +49,7 @@ Returns a BookmarkMutationResult indicating success with the updated bookmark ad ## Output fields -### Variant 1 (bookmark.kind="entity") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/capabilities/get.mdx b/apps/docs/document-api/reference/capabilities/get.mdx index 7540879a86..beef164146 100644 --- a/apps/docs/document-api/reference/capabilities/get.mdx +++ b/apps/docs/document-api/reference/capabilities/get.mdx @@ -2357,2932 +2357,1831 @@ _No fields._ }, "global": { "comments": { - "enabled": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ] + "enabled": true }, "dryRun": { - "enabled": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ] + "enabled": true }, "history": { - "enabled": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ] + "enabled": true }, "lists": { - "enabled": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ] + "enabled": true }, "trackChanges": { - "enabled": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ] + "enabled": true } }, "operations": { "authorities.configure": { "available": true, - "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "dryRun": false, + "tracked": false }, "authorities.entries.get": { "available": true, - "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "dryRun": false, + "tracked": false }, "authorities.entries.insert": { "available": true, - "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "dryRun": false, + "tracked": false }, "authorities.entries.list": { "available": true, - "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "dryRun": false, + "tracked": false }, "authorities.entries.remove": { "available": true, - "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "dryRun": false, + "tracked": false }, "authorities.entries.update": { "available": true, - "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "dryRun": false, + "tracked": false }, "authorities.get": { "available": true, - "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "dryRun": false, + "tracked": false }, "authorities.insert": { "available": true, - "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "dryRun": false, + "tracked": false }, "authorities.list": { "available": true, - "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "dryRun": false, + "tracked": false }, "authorities.rebuild": { "available": true, - "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "dryRun": false, + "tracked": false }, "authorities.remove": { "available": true, - "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "dryRun": false, + "tracked": false }, "blocks.delete": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "blocks.deleteRange": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "blocks.list": { "available": true, - "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "dryRun": false, + "tracked": false }, "bookmarks.get": { "available": true, - "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "dryRun": false, + "tracked": false }, "bookmarks.insert": { "available": true, - "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "dryRun": false, + "tracked": false }, "bookmarks.list": { "available": true, - "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "dryRun": false, + "tracked": false }, "bookmarks.remove": { "available": true, - "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "dryRun": false, + "tracked": false }, "bookmarks.rename": { "available": true, - "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "dryRun": false, + "tracked": false }, "capabilities.get": { "available": true, - "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "dryRun": false, + "tracked": false }, "captions.configure": { "available": true, - "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "dryRun": false, + "tracked": false }, "captions.get": { "available": true, - "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "dryRun": false, + "tracked": false }, "captions.insert": { "available": true, - "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "dryRun": false, + "tracked": false }, "captions.list": { "available": true, - "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "dryRun": false, + "tracked": false }, "captions.remove": { "available": true, - "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "dryRun": false, + "tracked": false }, "captions.update": { "available": true, - "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "dryRun": false, + "tracked": false }, "citations.bibliography.configure": { "available": true, - "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "dryRun": false, + "tracked": false }, "citations.bibliography.get": { "available": true, - "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "dryRun": false, + "tracked": false }, "citations.bibliography.insert": { "available": true, - "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "dryRun": false, + "tracked": false }, "citations.bibliography.rebuild": { "available": true, - "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "dryRun": false, + "tracked": false }, "citations.bibliography.remove": { "available": true, - "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "dryRun": false, + "tracked": false }, "citations.get": { "available": true, - "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "dryRun": false, + "tracked": false }, "citations.insert": { "available": true, - "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "dryRun": false, + "tracked": false }, "citations.list": { "available": true, - "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "dryRun": false, + "tracked": false }, "citations.remove": { "available": true, - "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "dryRun": false, + "tracked": false }, "citations.sources.get": { "available": true, - "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "dryRun": false, + "tracked": false }, "citations.sources.insert": { "available": true, - "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "dryRun": false, + "tracked": false }, "citations.sources.list": { "available": true, - "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "dryRun": false, + "tracked": false }, "citations.sources.remove": { "available": true, - "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "dryRun": false, + "tracked": false }, "citations.sources.update": { "available": true, - "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "dryRun": false, + "tracked": false }, "citations.update": { "available": true, - "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "dryRun": false, + "tracked": false }, "clearContent": { "available": true, - "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "dryRun": false, + "tracked": false }, "comments.create": { "available": true, - "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "dryRun": false, + "tracked": false }, "comments.delete": { "available": true, - "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "dryRun": false, + "tracked": false }, "comments.get": { "available": true, - "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "dryRun": false, + "tracked": false }, "comments.list": { "available": true, - "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "dryRun": false, + "tracked": false }, "comments.patch": { "available": true, - "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "dryRun": false, + "tracked": false }, "contentControls.appendContent": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "contentControls.checkbox.getState": { "available": true, - "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "dryRun": false, + "tracked": false }, "contentControls.checkbox.setState": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "contentControls.checkbox.setSymbolPair": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "contentControls.checkbox.toggle": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "contentControls.choiceList.getItems": { "available": true, - "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "dryRun": false, + "tracked": false }, "contentControls.choiceList.setItems": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "contentControls.choiceList.setSelected": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "contentControls.clearBinding": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "contentControls.clearContent": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "contentControls.copy": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "contentControls.date.clearValue": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "contentControls.date.setCalendar": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "contentControls.date.setDisplayFormat": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "contentControls.date.setDisplayLocale": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "contentControls.date.setStorageFormat": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "contentControls.date.setValue": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "contentControls.delete": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "contentControls.get": { "available": true, - "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "dryRun": false, + "tracked": false }, "contentControls.getBinding": { "available": true, - "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "dryRun": false, + "tracked": false }, "contentControls.getContent": { "available": true, - "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "dryRun": false, + "tracked": false }, "contentControls.getParent": { "available": true, - "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "dryRun": false, + "tracked": false }, "contentControls.getRawProperties": { "available": true, - "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "dryRun": false, + "tracked": false }, "contentControls.group.ungroup": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "contentControls.group.wrap": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "contentControls.insertAfter": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "contentControls.insertBefore": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "contentControls.list": { "available": true, - "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "dryRun": false, + "tracked": false }, "contentControls.listChildren": { "available": true, - "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "dryRun": false, + "tracked": false }, "contentControls.listInRange": { "available": true, - "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "dryRun": false, + "tracked": false }, "contentControls.move": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "contentControls.normalizeTagPayload": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "contentControls.normalizeWordCompatibility": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "contentControls.patch": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "contentControls.patchRawProperties": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "contentControls.prependContent": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "contentControls.repeatingSection.cloneItem": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "contentControls.repeatingSection.deleteItem": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "contentControls.repeatingSection.insertItemAfter": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "contentControls.repeatingSection.insertItemBefore": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "contentControls.repeatingSection.listItems": { "available": true, - "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "dryRun": false, + "tracked": false }, "contentControls.repeatingSection.setAllowInsertDelete": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "contentControls.replaceContent": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "contentControls.selectByTag": { "available": true, - "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "dryRun": false, + "tracked": false }, "contentControls.selectByTitle": { "available": true, - "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "dryRun": false, + "tracked": false }, "contentControls.setBinding": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "contentControls.setLockMode": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "contentControls.setType": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "contentControls.text.clearValue": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "contentControls.text.setMultiline": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "contentControls.text.setValue": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "contentControls.unwrap": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "contentControls.validateWordCompatibility": { "available": true, - "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "dryRun": false, + "tracked": false }, "contentControls.wrap": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "create.contentControl": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "create.heading": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], "tracked": true }, "create.image": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "create.paragraph": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], "tracked": true }, "create.sectionBreak": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "create.table": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], "tracked": true }, "create.tableOfContents": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "crossRefs.get": { "available": true, - "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "dryRun": false, + "tracked": false }, "crossRefs.insert": { "available": true, - "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "dryRun": false, + "tracked": false }, "crossRefs.list": { "available": true, - "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "dryRun": false, + "tracked": false }, "crossRefs.rebuild": { "available": true, - "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "dryRun": false, + "tracked": false }, "crossRefs.remove": { "available": true, - "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "dryRun": false, + "tracked": false }, "delete": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], "tracked": true }, "fields.get": { "available": true, - "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "dryRun": false, + "tracked": false }, "fields.insert": { "available": true, - "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "dryRun": false, + "tracked": false }, "fields.list": { "available": true, - "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "dryRun": false, + "tracked": false }, "fields.rebuild": { "available": true, - "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "dryRun": false, + "tracked": false }, "fields.remove": { "available": true, - "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "dryRun": false, + "tracked": false }, "find": { "available": true, - "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "dryRun": false, + "tracked": false }, "footnotes.configure": { "available": true, - "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "dryRun": false, + "tracked": false }, "footnotes.get": { "available": true, - "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "dryRun": false, + "tracked": false }, "footnotes.insert": { - "available": true, - "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "available": true, + "dryRun": false, + "tracked": false }, "footnotes.list": { "available": true, - "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "dryRun": false, + "tracked": false }, "footnotes.remove": { "available": true, - "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "dryRun": false, + "tracked": false }, "footnotes.update": { "available": true, - "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "dryRun": false, + "tracked": false }, "format.apply": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], "tracked": true }, "format.bCs": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "format.bold": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], "tracked": true }, "format.border": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "format.caps": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], "tracked": true }, "format.charScale": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "format.color": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], "tracked": true }, "format.contextualAlternates": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "format.cs": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "format.dstrike": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "format.eastAsianLayout": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "format.em": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "format.emboss": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "format.fitText": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "format.fontFamily": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], "tracked": true }, "format.fontSize": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], "tracked": true }, "format.fontSizeCs": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "format.highlight": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], "tracked": true }, "format.iCs": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "format.imprint": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "format.italic": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], "tracked": true }, "format.kerning": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "format.lang": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "format.letterSpacing": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], "tracked": true }, "format.ligatures": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "format.numForm": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "format.numSpacing": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "format.oMath": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "format.outline": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "format.paragraph.clearAlignment": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "format.paragraph.clearAllTabStops": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "format.paragraph.clearBorder": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "format.paragraph.clearIndentation": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "format.paragraph.clearShading": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "format.paragraph.clearSpacing": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "format.paragraph.clearTabStop": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "format.paragraph.resetDirectFormatting": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "format.paragraph.setAlignment": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "format.paragraph.setBorder": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "format.paragraph.setFlowOptions": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "format.paragraph.setIndentation": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "format.paragraph.setKeepOptions": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "format.paragraph.setOutlineLevel": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "format.paragraph.setShading": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "format.paragraph.setSpacing": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "format.paragraph.setTabStop": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "format.position": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], "tracked": true }, "format.rFonts": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "format.rStyle": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "format.rtl": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "format.shading": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "format.shadow": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "format.smallCaps": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "format.snapToGrid": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "format.specVanish": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "format.strike": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], "tracked": true }, "format.stylisticSets": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "format.underline": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], "tracked": true }, "format.vanish": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "format.vertAlign": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], "tracked": true }, "format.webHidden": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "get": { "available": true, - "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "dryRun": false, + "tracked": false }, "getHtml": { "available": true, - "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "dryRun": false, + "tracked": false }, "getMarkdown": { "available": true, - "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "dryRun": false, + "tracked": false }, "getNode": { "available": true, - "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "dryRun": false, + "tracked": false }, "getNodeById": { "available": true, - "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "dryRun": false, + "tracked": false }, "getText": { "available": true, - "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "dryRun": false, + "tracked": false }, "headerFooters.get": { "available": true, - "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "dryRun": false, + "tracked": false }, "headerFooters.list": { "available": true, - "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "dryRun": false, + "tracked": false }, "headerFooters.parts.create": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "headerFooters.parts.delete": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "headerFooters.parts.list": { "available": true, - "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "dryRun": false, + "tracked": false }, "headerFooters.refs.clear": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "headerFooters.refs.set": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "headerFooters.refs.setLinkedToPrevious": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "headerFooters.resolve": { "available": true, - "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "dryRun": false, + "tracked": false }, "history.get": { "available": true, - "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "dryRun": false, + "tracked": false }, "history.redo": { "available": true, - "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "dryRun": false, + "tracked": false }, "history.undo": { "available": true, - "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "dryRun": false, + "tracked": false }, "hyperlinks.get": { "available": true, - "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "dryRun": false, + "tracked": false }, "hyperlinks.insert": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "hyperlinks.list": { "available": true, - "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "dryRun": false, + "tracked": false }, "hyperlinks.patch": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "hyperlinks.remove": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "hyperlinks.wrap": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "images.convertToFloating": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "images.convertToInline": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "images.crop": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "images.delete": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "images.flip": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "images.get": { "available": true, - "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "dryRun": false, + "tracked": false }, "images.insertCaption": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "images.list": { "available": true, - "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "dryRun": false, + "tracked": false }, "images.move": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "images.removeCaption": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "images.replaceSource": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "images.resetCrop": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "images.rotate": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "images.scale": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "images.setAltText": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "images.setAnchorOptions": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "images.setDecorative": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "images.setHyperlink": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "images.setLockAspectRatio": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "images.setName": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "images.setPosition": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "images.setSize": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "images.setWrapDistances": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "images.setWrapSide": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "images.setWrapType": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "images.setZOrder": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "images.updateCaption": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "index.configure": { "available": true, - "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "dryRun": false, + "tracked": false }, "index.entries.get": { "available": true, - "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "dryRun": false, + "tracked": false }, "index.entries.insert": { "available": true, - "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "dryRun": false, + "tracked": false }, "index.entries.list": { "available": true, - "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "dryRun": false, + "tracked": false }, "index.entries.remove": { "available": true, - "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "dryRun": false, + "tracked": false }, "index.entries.update": { "available": true, - "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "dryRun": false, + "tracked": false }, "index.get": { "available": true, - "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "dryRun": false, + "tracked": false }, "index.insert": { "available": true, - "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "dryRun": false, + "tracked": false }, "index.list": { "available": true, - "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "dryRun": false, + "tracked": false }, "index.rebuild": { "available": true, - "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "dryRun": false, + "tracked": false }, "index.remove": { "available": true, - "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "dryRun": false, + "tracked": false }, "info": { "available": true, - "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "dryRun": false, + "tracked": false }, "insert": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], "tracked": true }, "lists.applyPreset": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "lists.applyTemplate": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "lists.attach": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "lists.canContinuePrevious": { "available": true, - "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "dryRun": false, + "tracked": false }, "lists.canJoin": { "available": true, - "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "dryRun": false, + "tracked": false }, "lists.captureTemplate": { "available": true, - "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "dryRun": false, + "tracked": false }, "lists.clearLevelOverrides": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "lists.continuePrevious": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "lists.convertToText": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "lists.create": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "lists.detach": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "lists.get": { "available": true, - "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "dryRun": false, + "tracked": false }, "lists.indent": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "lists.insert": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], "tracked": true }, "lists.join": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "lists.list": { "available": true, - "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "dryRun": false, + "tracked": false }, "lists.outdent": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "lists.separate": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "lists.setLevel": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "lists.setLevelAlignment": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "lists.setLevelBullet": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "lists.setLevelIndents": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "lists.setLevelMarkerFont": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "lists.setLevelNumbering": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "lists.setLevelPictureBullet": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "lists.setLevelRestart": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "lists.setLevelTrailingCharacter": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "lists.setType": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "lists.setValue": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "markdownToFragment": { "available": true, - "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "dryRun": false, + "tracked": false }, "mutations.apply": { "available": true, - "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], + "dryRun": false, "tracked": true }, "mutations.preview": { "available": true, - "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "dryRun": false, + "tracked": false }, "query.match": { "available": true, - "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "dryRun": false, + "tracked": false }, "ranges.resolve": { "available": true, - "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "dryRun": false, + "tracked": false }, "replace": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], "tracked": true }, "sections.clearHeaderFooterRef": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "sections.clearPageBorders": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "sections.get": { "available": true, - "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "dryRun": false, + "tracked": false }, "sections.list": { "available": true, - "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "dryRun": false, + "tracked": false }, "sections.setBreakType": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "sections.setColumns": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "sections.setHeaderFooterMargins": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "sections.setHeaderFooterRef": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "sections.setLineNumbering": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "sections.setLinkToPrevious": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "sections.setOddEvenHeadersFooters": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "sections.setPageBorders": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "sections.setPageMargins": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "sections.setPageNumbering": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "sections.setPageSetup": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "sections.setSectionDirection": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "sections.setTitlePage": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "sections.setVerticalAlign": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "styles.apply": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "styles.paragraph.clearStyle": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "styles.paragraph.setStyle": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "tables.applyBorderPreset": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "tables.clearBorder": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "tables.clearCellSpacing": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "tables.clearContents": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "tables.clearDefaultStyle": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "tables.clearShading": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "tables.clearStyle": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "tables.convertFromText": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "tables.convertToText": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "tables.delete": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], "tracked": true }, "tables.deleteCell": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "tables.deleteColumn": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], "tracked": true }, "tables.deleteRow": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], "tracked": true }, "tables.distributeColumns": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "tables.distributeRows": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "tables.get": { "available": true, - "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "dryRun": false, + "tracked": false }, "tables.getCells": { "available": true, - "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "dryRun": false, + "tracked": false }, "tables.getProperties": { "available": true, - "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "dryRun": false, + "tracked": false }, "tables.getStyles": { "available": true, - "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "dryRun": false, + "tracked": false }, "tables.insertCell": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "tables.insertColumn": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], "tracked": true }, "tables.insertRow": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], "tracked": true }, "tables.mergeCells": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "tables.move": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "tables.setAltText": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "tables.setBorder": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "tables.setCellPadding": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "tables.setCellProperties": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "tables.setCellSpacing": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "tables.setColumnWidth": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "tables.setDefaultStyle": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "tables.setLayout": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "tables.setRowHeight": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "tables.setRowOptions": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "tables.setShading": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "tables.setStyle": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "tables.setStyleOption": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "tables.setTablePadding": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "tables.sort": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "tables.split": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "tables.splitCell": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "tables.unmergeCells": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "toc.configure": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "toc.editEntry": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "toc.get": { "available": true, - "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "dryRun": false, + "tracked": false }, "toc.getEntry": { "available": true, - "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "dryRun": false, + "tracked": false }, "toc.list": { "available": true, - "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "dryRun": false, + "tracked": false }, "toc.listEntries": { "available": true, - "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "dryRun": false, + "tracked": false }, "toc.markEntry": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "toc.remove": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "toc.unmarkEntry": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "toc.update": { "available": true, "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "tracked": false }, "trackChanges.decide": { "available": true, - "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "dryRun": false, + "tracked": false }, "trackChanges.get": { "available": true, - "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "dryRun": false, + "tracked": false }, "trackChanges.list": { "available": true, - "dryRun": true, - "reasons": [ - "COMMAND_UNAVAILABLE" - ], - "tracked": true + "dryRun": false, + "tracked": false } }, "planEngine": { diff --git a/apps/docs/document-api/reference/captions/insert.mdx b/apps/docs/document-api/reference/captions/insert.mdx index d299ead28f..71435d43cf 100644 --- a/apps/docs/document-api/reference/captions/insert.mdx +++ b/apps/docs/document-api/reference/captions/insert.mdx @@ -53,7 +53,7 @@ Returns a CaptionMutationResult indicating success with the caption address or a ## Output fields -### Variant 1 (caption.kind="block") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/captions/remove.mdx b/apps/docs/document-api/reference/captions/remove.mdx index bd43a1b9c2..fbb1a1b145 100644 --- a/apps/docs/document-api/reference/captions/remove.mdx +++ b/apps/docs/document-api/reference/captions/remove.mdx @@ -47,7 +47,7 @@ Returns a CaptionMutationResult indicating success or a failure. ## Output fields -### Variant 1 (caption.kind="block") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/captions/update.mdx b/apps/docs/document-api/reference/captions/update.mdx index 8c98fe2890..ac78e64d2e 100644 --- a/apps/docs/document-api/reference/captions/update.mdx +++ b/apps/docs/document-api/reference/captions/update.mdx @@ -52,7 +52,7 @@ Returns a CaptionMutationResult indicating success or a failure. ## Output fields -### Variant 1 (caption.kind="block") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/citations/bibliography-configure.mdx b/apps/docs/document-api/reference/citations/bibliography-configure.mdx index d16e819f5b..0bd53ed640 100644 --- a/apps/docs/document-api/reference/citations/bibliography-configure.mdx +++ b/apps/docs/document-api/reference/citations/bibliography-configure.mdx @@ -40,7 +40,7 @@ Returns a BibliographyMutationResult indicating success or a failure. ## Output fields -### Variant 1 (bibliography.kind="block") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/citations/bibliography-insert.mdx b/apps/docs/document-api/reference/citations/bibliography-insert.mdx index f170b34452..c0e20f9046 100644 --- a/apps/docs/document-api/reference/citations/bibliography-insert.mdx +++ b/apps/docs/document-api/reference/citations/bibliography-insert.mdx @@ -44,7 +44,7 @@ Returns a BibliographyMutationResult indicating success with the bibliography ad ## Output fields -### Variant 1 (bibliography.kind="block") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/citations/bibliography-rebuild.mdx b/apps/docs/document-api/reference/citations/bibliography-rebuild.mdx index c70dab3083..dd3fa5f85b 100644 --- a/apps/docs/document-api/reference/citations/bibliography-rebuild.mdx +++ b/apps/docs/document-api/reference/citations/bibliography-rebuild.mdx @@ -47,7 +47,7 @@ Returns a BibliographyMutationResult indicating success or a failure. ## Output fields -### Variant 1 (bibliography.kind="block") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/citations/bibliography-remove.mdx b/apps/docs/document-api/reference/citations/bibliography-remove.mdx index b9c24617f3..820f5b52f9 100644 --- a/apps/docs/document-api/reference/citations/bibliography-remove.mdx +++ b/apps/docs/document-api/reference/citations/bibliography-remove.mdx @@ -47,7 +47,7 @@ Returns a BibliographyMutationResult indicating success or a failure. ## Output fields -### Variant 1 (bibliography.kind="block") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/citations/insert.mdx b/apps/docs/document-api/reference/citations/insert.mdx index 9088be0c84..c552cc49e6 100644 --- a/apps/docs/document-api/reference/citations/insert.mdx +++ b/apps/docs/document-api/reference/citations/insert.mdx @@ -57,7 +57,7 @@ Returns a CitationMutationResult indicating success with the citation address or ## Output fields -### Variant 1 (citation.kind="inline") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/citations/remove.mdx b/apps/docs/document-api/reference/citations/remove.mdx index 511c1a18ae..679df432f2 100644 --- a/apps/docs/document-api/reference/citations/remove.mdx +++ b/apps/docs/document-api/reference/citations/remove.mdx @@ -62,7 +62,7 @@ Returns a CitationMutationResult indicating success or a failure. ## Output fields -### Variant 1 (citation.kind="inline") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/citations/sources-insert.mdx b/apps/docs/document-api/reference/citations/sources-insert.mdx index 9d196a7281..7b6449ec42 100644 --- a/apps/docs/document-api/reference/citations/sources-insert.mdx +++ b/apps/docs/document-api/reference/citations/sources-insert.mdx @@ -68,7 +68,7 @@ Returns a CitationSourceMutationResult indicating success with the source addres ## Output fields -### Variant 1 (source.kind="entity") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/citations/sources-remove.mdx b/apps/docs/document-api/reference/citations/sources-remove.mdx index 4d1c2e77a8..8ba1233940 100644 --- a/apps/docs/document-api/reference/citations/sources-remove.mdx +++ b/apps/docs/document-api/reference/citations/sources-remove.mdx @@ -47,7 +47,7 @@ Returns a CitationSourceMutationResult indicating success or a failure. ## Output fields -### Variant 1 (source.kind="entity") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/citations/sources-update.mdx b/apps/docs/document-api/reference/citations/sources-update.mdx index 456ba332f6..f7c9eaa984 100644 --- a/apps/docs/document-api/reference/citations/sources-update.mdx +++ b/apps/docs/document-api/reference/citations/sources-update.mdx @@ -75,7 +75,7 @@ Returns a CitationSourceMutationResult indicating success or a failure. ## Output fields -### Variant 1 (source.kind="entity") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/citations/update.mdx b/apps/docs/document-api/reference/citations/update.mdx index 6643569f3d..3536fa4a34 100644 --- a/apps/docs/document-api/reference/citations/update.mdx +++ b/apps/docs/document-api/reference/citations/update.mdx @@ -69,7 +69,7 @@ Returns a CitationMutationResult indicating success or a failure. ## Output fields -### Variant 1 (citation.kind="inline") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/create/heading.mdx b/apps/docs/document-api/reference/create/heading.mdx index 58fb255929..f6c6b5a21b 100644 --- a/apps/docs/document-api/reference/create/heading.mdx +++ b/apps/docs/document-api/reference/create/heading.mdx @@ -46,7 +46,7 @@ Returns a CreateHeadingResult with the new heading block ID and address. ## Output fields -### Variant 1 (heading.kind="block") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/create/paragraph.mdx b/apps/docs/document-api/reference/create/paragraph.mdx index 7179f49c7c..011cbcfdf0 100644 --- a/apps/docs/document-api/reference/create/paragraph.mdx +++ b/apps/docs/document-api/reference/create/paragraph.mdx @@ -44,7 +44,7 @@ Returns a CreateParagraphResult with the new paragraph block ID and address. ## Output fields -### Variant 1 (paragraph.kind="block") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/create/section-break.mdx b/apps/docs/document-api/reference/create/section-break.mdx index 66ad58709e..680d94d644 100644 --- a/apps/docs/document-api/reference/create/section-break.mdx +++ b/apps/docs/document-api/reference/create/section-break.mdx @@ -53,7 +53,7 @@ Returns a CreateSectionBreakResult with the new section break position and secti ## Output fields -### Variant 1 (section.kind="section") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/create/table-of-contents.mdx b/apps/docs/document-api/reference/create/table-of-contents.mdx index aafa47ac49..7d0f73308d 100644 --- a/apps/docs/document-api/reference/create/table-of-contents.mdx +++ b/apps/docs/document-api/reference/create/table-of-contents.mdx @@ -67,7 +67,7 @@ Returns a CreateTableOfContentsResult with the new TOC block address. ## Output fields -### Variant 1 (toc.kind="block") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/create/table.mdx b/apps/docs/document-api/reference/create/table.mdx index b216e078fe..91f3833b55 100644 --- a/apps/docs/document-api/reference/create/table.mdx +++ b/apps/docs/document-api/reference/create/table.mdx @@ -46,7 +46,7 @@ Returns a CreateTableResult with the new table block ID and address. ## Output fields -### Variant 1 (table.kind="block") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/cross-refs/insert.mdx b/apps/docs/document-api/reference/cross-refs/insert.mdx index ee024ccd18..005e6afaba 100644 --- a/apps/docs/document-api/reference/cross-refs/insert.mdx +++ b/apps/docs/document-api/reference/cross-refs/insert.mdx @@ -60,7 +60,7 @@ Returns a CrossRefMutationResult indicating success with the cross-reference add ## Output fields -### Variant 1 (crossRef.kind="inline") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/cross-refs/rebuild.mdx b/apps/docs/document-api/reference/cross-refs/rebuild.mdx index 94083eed38..eee82fa86d 100644 --- a/apps/docs/document-api/reference/cross-refs/rebuild.mdx +++ b/apps/docs/document-api/reference/cross-refs/rebuild.mdx @@ -62,7 +62,7 @@ Returns a CrossRefMutationResult indicating success or a failure. ## Output fields -### Variant 1 (crossRef.kind="inline") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/cross-refs/remove.mdx b/apps/docs/document-api/reference/cross-refs/remove.mdx index faa3325bda..fc796d6dfc 100644 --- a/apps/docs/document-api/reference/cross-refs/remove.mdx +++ b/apps/docs/document-api/reference/cross-refs/remove.mdx @@ -62,7 +62,7 @@ Returns a CrossRefMutationResult indicating success or a failure. ## Output fields -### Variant 1 (crossRef.kind="inline") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/delete.mdx b/apps/docs/document-api/reference/delete.mdx index de113bfd05..53269b85ff 100644 --- a/apps/docs/document-api/reference/delete.mdx +++ b/apps/docs/document-api/reference/delete.mdx @@ -66,7 +66,7 @@ Returns a TextMutationReceipt with applied status; receipt reports NO_OP if the ## Output fields -### Variant 1 (resolution.requestedTarget.kind="text") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | @@ -96,7 +96,7 @@ Returns a TextMutationReceipt with applied status; receipt reports NO_OP if the | `success` | `true` | yes | Constant: `true` | | `updated` | EntityAddress[] | no | | -### Variant 2 (resolution.requestedTarget.kind="text") +### Variant 2 (success=false) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/fields/insert.mdx b/apps/docs/document-api/reference/fields/insert.mdx index aea93bcc61..ff6492c7f6 100644 --- a/apps/docs/document-api/reference/fields/insert.mdx +++ b/apps/docs/document-api/reference/fields/insert.mdx @@ -57,7 +57,7 @@ Returns a FieldMutationResult indicating success with the field address or a fai ## Output fields -### Variant 1 (field.kind="field") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/fields/rebuild.mdx b/apps/docs/document-api/reference/fields/rebuild.mdx index c820c694f4..c86a2d27ca 100644 --- a/apps/docs/document-api/reference/fields/rebuild.mdx +++ b/apps/docs/document-api/reference/fields/rebuild.mdx @@ -49,7 +49,7 @@ Returns a FieldMutationResult indicating success or a failure. ## Output fields -### Variant 1 (field.kind="field") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/fields/remove.mdx b/apps/docs/document-api/reference/fields/remove.mdx index a627c9ab1a..b2d7239919 100644 --- a/apps/docs/document-api/reference/fields/remove.mdx +++ b/apps/docs/document-api/reference/fields/remove.mdx @@ -51,7 +51,7 @@ Returns a FieldMutationResult indicating success or a failure. ## Output fields -### Variant 1 (field.kind="field") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/footnotes/insert.mdx b/apps/docs/document-api/reference/footnotes/insert.mdx index 6a3761f615..bd1d454af0 100644 --- a/apps/docs/document-api/reference/footnotes/insert.mdx +++ b/apps/docs/document-api/reference/footnotes/insert.mdx @@ -57,7 +57,7 @@ Returns a FootnoteMutationResult indicating success with the footnote address or ## Output fields -### Variant 1 (footnote.kind="entity") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/footnotes/remove.mdx b/apps/docs/document-api/reference/footnotes/remove.mdx index 23c663ce06..577e95a969 100644 --- a/apps/docs/document-api/reference/footnotes/remove.mdx +++ b/apps/docs/document-api/reference/footnotes/remove.mdx @@ -47,7 +47,7 @@ Returns a FootnoteMutationResult indicating success or a failure. ## Output fields -### Variant 1 (footnote.kind="entity") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/footnotes/update.mdx b/apps/docs/document-api/reference/footnotes/update.mdx index 7cdd95b89e..985ccf94f7 100644 --- a/apps/docs/document-api/reference/footnotes/update.mdx +++ b/apps/docs/document-api/reference/footnotes/update.mdx @@ -52,7 +52,7 @@ Returns a FootnoteMutationResult indicating success with the updated footnote ad ## Output fields -### Variant 1 (footnote.kind="entity") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/format/apply.mdx b/apps/docs/document-api/reference/format/apply.mdx index 0194e44916..d52dad8263 100644 --- a/apps/docs/document-api/reference/format/apply.mdx +++ b/apps/docs/document-api/reference/format/apply.mdx @@ -155,7 +155,7 @@ Returns a TextMutationReceipt confirming inline styles were applied to the targe ## Output fields -### Variant 1 (resolution.requestedTarget.kind="text") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | @@ -185,7 +185,7 @@ Returns a TextMutationReceipt confirming inline styles were applied to the targe | `success` | `true` | yes | Constant: `true` | | `updated` | EntityAddress[] | no | | -### Variant 2 (resolution.requestedTarget.kind="text") +### Variant 2 (success=false) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/format/b-cs.mdx b/apps/docs/document-api/reference/format/b-cs.mdx index 15d538aeef..dfe82162fc 100644 --- a/apps/docs/document-api/reference/format/b-cs.mdx +++ b/apps/docs/document-api/reference/format/b-cs.mdx @@ -66,7 +66,7 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli ## Output fields -### Variant 1 (resolution.requestedTarget.kind="text") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | @@ -96,7 +96,7 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli | `success` | `true` | yes | Constant: `true` | | `updated` | EntityAddress[] | no | | -### Variant 2 (resolution.requestedTarget.kind="text") +### Variant 2 (success=false) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/format/bold.mdx b/apps/docs/document-api/reference/format/bold.mdx index 351982085e..72b2bf42da 100644 --- a/apps/docs/document-api/reference/format/bold.mdx +++ b/apps/docs/document-api/reference/format/bold.mdx @@ -66,7 +66,7 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli ## Output fields -### Variant 1 (resolution.requestedTarget.kind="text") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | @@ -96,7 +96,7 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli | `success` | `true` | yes | Constant: `true` | | `updated` | EntityAddress[] | no | | -### Variant 2 (resolution.requestedTarget.kind="text") +### Variant 2 (success=false) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/format/border.mdx b/apps/docs/document-api/reference/format/border.mdx index 64a0aa4e9b..ddeaf14597 100644 --- a/apps/docs/document-api/reference/format/border.mdx +++ b/apps/docs/document-api/reference/format/border.mdx @@ -69,7 +69,7 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli ## Output fields -### Variant 1 (resolution.requestedTarget.kind="text") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | @@ -99,7 +99,7 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli | `success` | `true` | yes | Constant: `true` | | `updated` | EntityAddress[] | no | | -### Variant 2 (resolution.requestedTarget.kind="text") +### Variant 2 (success=false) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/format/caps.mdx b/apps/docs/document-api/reference/format/caps.mdx index 2dd902137d..60295f05d9 100644 --- a/apps/docs/document-api/reference/format/caps.mdx +++ b/apps/docs/document-api/reference/format/caps.mdx @@ -66,7 +66,7 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli ## Output fields -### Variant 1 (resolution.requestedTarget.kind="text") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | @@ -96,7 +96,7 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli | `success` | `true` | yes | Constant: `true` | | `updated` | EntityAddress[] | no | | -### Variant 2 (resolution.requestedTarget.kind="text") +### Variant 2 (success=false) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/format/char-scale.mdx b/apps/docs/document-api/reference/format/char-scale.mdx index 257b48446c..1780c38081 100644 --- a/apps/docs/document-api/reference/format/char-scale.mdx +++ b/apps/docs/document-api/reference/format/char-scale.mdx @@ -66,7 +66,7 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli ## Output fields -### Variant 1 (resolution.requestedTarget.kind="text") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | @@ -96,7 +96,7 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli | `success` | `true` | yes | Constant: `true` | | `updated` | EntityAddress[] | no | | -### Variant 2 (resolution.requestedTarget.kind="text") +### Variant 2 (success=false) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/format/color.mdx b/apps/docs/document-api/reference/format/color.mdx index bbe4ab703e..a904fe8d06 100644 --- a/apps/docs/document-api/reference/format/color.mdx +++ b/apps/docs/document-api/reference/format/color.mdx @@ -66,7 +66,7 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli ## Output fields -### Variant 1 (resolution.requestedTarget.kind="text") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | @@ -96,7 +96,7 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli | `success` | `true` | yes | Constant: `true` | | `updated` | EntityAddress[] | no | | -### Variant 2 (resolution.requestedTarget.kind="text") +### Variant 2 (success=false) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/format/contextual-alternates.mdx b/apps/docs/document-api/reference/format/contextual-alternates.mdx index 5858ea01ad..1a7d4a9cd2 100644 --- a/apps/docs/document-api/reference/format/contextual-alternates.mdx +++ b/apps/docs/document-api/reference/format/contextual-alternates.mdx @@ -66,7 +66,7 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli ## Output fields -### Variant 1 (resolution.requestedTarget.kind="text") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | @@ -96,7 +96,7 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli | `success` | `true` | yes | Constant: `true` | | `updated` | EntityAddress[] | no | | -### Variant 2 (resolution.requestedTarget.kind="text") +### Variant 2 (success=false) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/format/cs.mdx b/apps/docs/document-api/reference/format/cs.mdx index 5fb6e48b60..a3a801fdd7 100644 --- a/apps/docs/document-api/reference/format/cs.mdx +++ b/apps/docs/document-api/reference/format/cs.mdx @@ -66,7 +66,7 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli ## Output fields -### Variant 1 (resolution.requestedTarget.kind="text") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | @@ -96,7 +96,7 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli | `success` | `true` | yes | Constant: `true` | | `updated` | EntityAddress[] | no | | -### Variant 2 (resolution.requestedTarget.kind="text") +### Variant 2 (success=false) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/format/dstrike.mdx b/apps/docs/document-api/reference/format/dstrike.mdx index fd412503bc..a16a3483fa 100644 --- a/apps/docs/document-api/reference/format/dstrike.mdx +++ b/apps/docs/document-api/reference/format/dstrike.mdx @@ -66,7 +66,7 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli ## Output fields -### Variant 1 (resolution.requestedTarget.kind="text") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | @@ -96,7 +96,7 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli | `success` | `true` | yes | Constant: `true` | | `updated` | EntityAddress[] | no | | -### Variant 2 (resolution.requestedTarget.kind="text") +### Variant 2 (success=false) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/format/east-asian-layout.mdx b/apps/docs/document-api/reference/format/east-asian-layout.mdx index ace6aac506..ac9afbbf37 100644 --- a/apps/docs/document-api/reference/format/east-asian-layout.mdx +++ b/apps/docs/document-api/reference/format/east-asian-layout.mdx @@ -69,7 +69,7 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli ## Output fields -### Variant 1 (resolution.requestedTarget.kind="text") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | @@ -99,7 +99,7 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli | `success` | `true` | yes | Constant: `true` | | `updated` | EntityAddress[] | no | | -### Variant 2 (resolution.requestedTarget.kind="text") +### Variant 2 (success=false) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/format/em.mdx b/apps/docs/document-api/reference/format/em.mdx index 404315ca86..4c6de23d3c 100644 --- a/apps/docs/document-api/reference/format/em.mdx +++ b/apps/docs/document-api/reference/format/em.mdx @@ -66,7 +66,7 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli ## Output fields -### Variant 1 (resolution.requestedTarget.kind="text") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | @@ -96,7 +96,7 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli | `success` | `true` | yes | Constant: `true` | | `updated` | EntityAddress[] | no | | -### Variant 2 (resolution.requestedTarget.kind="text") +### Variant 2 (success=false) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/format/emboss.mdx b/apps/docs/document-api/reference/format/emboss.mdx index 0870f50abd..7dda6af6a7 100644 --- a/apps/docs/document-api/reference/format/emboss.mdx +++ b/apps/docs/document-api/reference/format/emboss.mdx @@ -66,7 +66,7 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli ## Output fields -### Variant 1 (resolution.requestedTarget.kind="text") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | @@ -96,7 +96,7 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli | `success` | `true` | yes | Constant: `true` | | `updated` | EntityAddress[] | no | | -### Variant 2 (resolution.requestedTarget.kind="text") +### Variant 2 (success=false) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/format/fit-text.mdx b/apps/docs/document-api/reference/format/fit-text.mdx index b0bc6fb38e..ee7b7df742 100644 --- a/apps/docs/document-api/reference/format/fit-text.mdx +++ b/apps/docs/document-api/reference/format/fit-text.mdx @@ -69,7 +69,7 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli ## Output fields -### Variant 1 (resolution.requestedTarget.kind="text") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | @@ -99,7 +99,7 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli | `success` | `true` | yes | Constant: `true` | | `updated` | EntityAddress[] | no | | -### Variant 2 (resolution.requestedTarget.kind="text") +### Variant 2 (success=false) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/format/font-family.mdx b/apps/docs/document-api/reference/format/font-family.mdx index e5e95275e3..1dc5721cad 100644 --- a/apps/docs/document-api/reference/format/font-family.mdx +++ b/apps/docs/document-api/reference/format/font-family.mdx @@ -66,7 +66,7 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli ## Output fields -### Variant 1 (resolution.requestedTarget.kind="text") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | @@ -96,7 +96,7 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli | `success` | `true` | yes | Constant: `true` | | `updated` | EntityAddress[] | no | | -### Variant 2 (resolution.requestedTarget.kind="text") +### Variant 2 (success=false) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/format/font-size-cs.mdx b/apps/docs/document-api/reference/format/font-size-cs.mdx index 567b086871..5a2ab544a5 100644 --- a/apps/docs/document-api/reference/format/font-size-cs.mdx +++ b/apps/docs/document-api/reference/format/font-size-cs.mdx @@ -66,7 +66,7 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli ## Output fields -### Variant 1 (resolution.requestedTarget.kind="text") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | @@ -96,7 +96,7 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli | `success` | `true` | yes | Constant: `true` | | `updated` | EntityAddress[] | no | | -### Variant 2 (resolution.requestedTarget.kind="text") +### Variant 2 (success=false) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/format/font-size.mdx b/apps/docs/document-api/reference/format/font-size.mdx index 7ffcb1c22c..3b111c5590 100644 --- a/apps/docs/document-api/reference/format/font-size.mdx +++ b/apps/docs/document-api/reference/format/font-size.mdx @@ -66,7 +66,7 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli ## Output fields -### Variant 1 (resolution.requestedTarget.kind="text") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | @@ -96,7 +96,7 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli | `success` | `true` | yes | Constant: `true` | | `updated` | EntityAddress[] | no | | -### Variant 2 (resolution.requestedTarget.kind="text") +### Variant 2 (success=false) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/format/highlight.mdx b/apps/docs/document-api/reference/format/highlight.mdx index 949a1e1846..c65e986f6f 100644 --- a/apps/docs/document-api/reference/format/highlight.mdx +++ b/apps/docs/document-api/reference/format/highlight.mdx @@ -66,7 +66,7 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli ## Output fields -### Variant 1 (resolution.requestedTarget.kind="text") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | @@ -96,7 +96,7 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli | `success` | `true` | yes | Constant: `true` | | `updated` | EntityAddress[] | no | | -### Variant 2 (resolution.requestedTarget.kind="text") +### Variant 2 (success=false) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/format/i-cs.mdx b/apps/docs/document-api/reference/format/i-cs.mdx index ae728fe82d..db716e29bd 100644 --- a/apps/docs/document-api/reference/format/i-cs.mdx +++ b/apps/docs/document-api/reference/format/i-cs.mdx @@ -66,7 +66,7 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli ## Output fields -### Variant 1 (resolution.requestedTarget.kind="text") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | @@ -96,7 +96,7 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli | `success` | `true` | yes | Constant: `true` | | `updated` | EntityAddress[] | no | | -### Variant 2 (resolution.requestedTarget.kind="text") +### Variant 2 (success=false) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/format/imprint.mdx b/apps/docs/document-api/reference/format/imprint.mdx index 745aceee78..7c0a2ab65e 100644 --- a/apps/docs/document-api/reference/format/imprint.mdx +++ b/apps/docs/document-api/reference/format/imprint.mdx @@ -66,7 +66,7 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli ## Output fields -### Variant 1 (resolution.requestedTarget.kind="text") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | @@ -96,7 +96,7 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli | `success` | `true` | yes | Constant: `true` | | `updated` | EntityAddress[] | no | | -### Variant 2 (resolution.requestedTarget.kind="text") +### Variant 2 (success=false) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/format/italic.mdx b/apps/docs/document-api/reference/format/italic.mdx index f152ea0e36..c6602c33b3 100644 --- a/apps/docs/document-api/reference/format/italic.mdx +++ b/apps/docs/document-api/reference/format/italic.mdx @@ -66,7 +66,7 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli ## Output fields -### Variant 1 (resolution.requestedTarget.kind="text") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | @@ -96,7 +96,7 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli | `success` | `true` | yes | Constant: `true` | | `updated` | EntityAddress[] | no | | -### Variant 2 (resolution.requestedTarget.kind="text") +### Variant 2 (success=false) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/format/kerning.mdx b/apps/docs/document-api/reference/format/kerning.mdx index a35bc80262..2b2e9edefc 100644 --- a/apps/docs/document-api/reference/format/kerning.mdx +++ b/apps/docs/document-api/reference/format/kerning.mdx @@ -66,7 +66,7 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli ## Output fields -### Variant 1 (resolution.requestedTarget.kind="text") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | @@ -96,7 +96,7 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli | `success` | `true` | yes | Constant: `true` | | `updated` | EntityAddress[] | no | | -### Variant 2 (resolution.requestedTarget.kind="text") +### Variant 2 (success=false) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/format/lang.mdx b/apps/docs/document-api/reference/format/lang.mdx index 496ec8acf6..e2d41b7e51 100644 --- a/apps/docs/document-api/reference/format/lang.mdx +++ b/apps/docs/document-api/reference/format/lang.mdx @@ -69,7 +69,7 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli ## Output fields -### Variant 1 (resolution.requestedTarget.kind="text") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | @@ -99,7 +99,7 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli | `success` | `true` | yes | Constant: `true` | | `updated` | EntityAddress[] | no | | -### Variant 2 (resolution.requestedTarget.kind="text") +### Variant 2 (success=false) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/format/letter-spacing.mdx b/apps/docs/document-api/reference/format/letter-spacing.mdx index b626bc2948..5365471aa8 100644 --- a/apps/docs/document-api/reference/format/letter-spacing.mdx +++ b/apps/docs/document-api/reference/format/letter-spacing.mdx @@ -66,7 +66,7 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli ## Output fields -### Variant 1 (resolution.requestedTarget.kind="text") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | @@ -96,7 +96,7 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli | `success` | `true` | yes | Constant: `true` | | `updated` | EntityAddress[] | no | | -### Variant 2 (resolution.requestedTarget.kind="text") +### Variant 2 (success=false) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/format/ligatures.mdx b/apps/docs/document-api/reference/format/ligatures.mdx index 86070465fd..86d44f9c24 100644 --- a/apps/docs/document-api/reference/format/ligatures.mdx +++ b/apps/docs/document-api/reference/format/ligatures.mdx @@ -66,7 +66,7 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli ## Output fields -### Variant 1 (resolution.requestedTarget.kind="text") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | @@ -96,7 +96,7 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli | `success` | `true` | yes | Constant: `true` | | `updated` | EntityAddress[] | no | | -### Variant 2 (resolution.requestedTarget.kind="text") +### Variant 2 (success=false) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/format/num-form.mdx b/apps/docs/document-api/reference/format/num-form.mdx index c967c5ede3..443f023e22 100644 --- a/apps/docs/document-api/reference/format/num-form.mdx +++ b/apps/docs/document-api/reference/format/num-form.mdx @@ -66,7 +66,7 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli ## Output fields -### Variant 1 (resolution.requestedTarget.kind="text") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | @@ -96,7 +96,7 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli | `success` | `true` | yes | Constant: `true` | | `updated` | EntityAddress[] | no | | -### Variant 2 (resolution.requestedTarget.kind="text") +### Variant 2 (success=false) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/format/num-spacing.mdx b/apps/docs/document-api/reference/format/num-spacing.mdx index 92362b23f9..a2e04e57af 100644 --- a/apps/docs/document-api/reference/format/num-spacing.mdx +++ b/apps/docs/document-api/reference/format/num-spacing.mdx @@ -66,7 +66,7 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli ## Output fields -### Variant 1 (resolution.requestedTarget.kind="text") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | @@ -96,7 +96,7 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli | `success` | `true` | yes | Constant: `true` | | `updated` | EntityAddress[] | no | | -### Variant 2 (resolution.requestedTarget.kind="text") +### Variant 2 (success=false) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/format/o-math.mdx b/apps/docs/document-api/reference/format/o-math.mdx index 87b9e7d5af..3a51052086 100644 --- a/apps/docs/document-api/reference/format/o-math.mdx +++ b/apps/docs/document-api/reference/format/o-math.mdx @@ -66,7 +66,7 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli ## Output fields -### Variant 1 (resolution.requestedTarget.kind="text") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | @@ -96,7 +96,7 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli | `success` | `true` | yes | Constant: `true` | | `updated` | EntityAddress[] | no | | -### Variant 2 (resolution.requestedTarget.kind="text") +### Variant 2 (success=false) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/format/outline.mdx b/apps/docs/document-api/reference/format/outline.mdx index 99b9ff949d..88951aa891 100644 --- a/apps/docs/document-api/reference/format/outline.mdx +++ b/apps/docs/document-api/reference/format/outline.mdx @@ -66,7 +66,7 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli ## Output fields -### Variant 1 (resolution.requestedTarget.kind="text") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | @@ -96,7 +96,7 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli | `success` | `true` | yes | Constant: `true` | | `updated` | EntityAddress[] | no | | -### Variant 2 (resolution.requestedTarget.kind="text") +### Variant 2 (success=false) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/format/position.mdx b/apps/docs/document-api/reference/format/position.mdx index a927fc0f9e..c4c5692bfa 100644 --- a/apps/docs/document-api/reference/format/position.mdx +++ b/apps/docs/document-api/reference/format/position.mdx @@ -66,7 +66,7 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli ## Output fields -### Variant 1 (resolution.requestedTarget.kind="text") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | @@ -96,7 +96,7 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli | `success` | `true` | yes | Constant: `true` | | `updated` | EntityAddress[] | no | | -### Variant 2 (resolution.requestedTarget.kind="text") +### Variant 2 (success=false) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/format/r-fonts.mdx b/apps/docs/document-api/reference/format/r-fonts.mdx index c13e4294d5..2ed8c76f4e 100644 --- a/apps/docs/document-api/reference/format/r-fonts.mdx +++ b/apps/docs/document-api/reference/format/r-fonts.mdx @@ -69,7 +69,7 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli ## Output fields -### Variant 1 (resolution.requestedTarget.kind="text") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | @@ -99,7 +99,7 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli | `success` | `true` | yes | Constant: `true` | | `updated` | EntityAddress[] | no | | -### Variant 2 (resolution.requestedTarget.kind="text") +### Variant 2 (success=false) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/format/r-style.mdx b/apps/docs/document-api/reference/format/r-style.mdx index 9c0d232d85..0b5142d978 100644 --- a/apps/docs/document-api/reference/format/r-style.mdx +++ b/apps/docs/document-api/reference/format/r-style.mdx @@ -66,7 +66,7 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli ## Output fields -### Variant 1 (resolution.requestedTarget.kind="text") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | @@ -96,7 +96,7 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli | `success` | `true` | yes | Constant: `true` | | `updated` | EntityAddress[] | no | | -### Variant 2 (resolution.requestedTarget.kind="text") +### Variant 2 (success=false) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/format/rtl.mdx b/apps/docs/document-api/reference/format/rtl.mdx index 7492a60d5c..d99d5a239e 100644 --- a/apps/docs/document-api/reference/format/rtl.mdx +++ b/apps/docs/document-api/reference/format/rtl.mdx @@ -66,7 +66,7 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli ## Output fields -### Variant 1 (resolution.requestedTarget.kind="text") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | @@ -96,7 +96,7 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli | `success` | `true` | yes | Constant: `true` | | `updated` | EntityAddress[] | no | | -### Variant 2 (resolution.requestedTarget.kind="text") +### Variant 2 (success=false) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/format/shading.mdx b/apps/docs/document-api/reference/format/shading.mdx index de11933981..8d74a625bf 100644 --- a/apps/docs/document-api/reference/format/shading.mdx +++ b/apps/docs/document-api/reference/format/shading.mdx @@ -69,7 +69,7 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli ## Output fields -### Variant 1 (resolution.requestedTarget.kind="text") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | @@ -99,7 +99,7 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli | `success` | `true` | yes | Constant: `true` | | `updated` | EntityAddress[] | no | | -### Variant 2 (resolution.requestedTarget.kind="text") +### Variant 2 (success=false) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/format/shadow.mdx b/apps/docs/document-api/reference/format/shadow.mdx index 7cd7a9a9f2..c1db6da66a 100644 --- a/apps/docs/document-api/reference/format/shadow.mdx +++ b/apps/docs/document-api/reference/format/shadow.mdx @@ -66,7 +66,7 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli ## Output fields -### Variant 1 (resolution.requestedTarget.kind="text") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | @@ -96,7 +96,7 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli | `success` | `true` | yes | Constant: `true` | | `updated` | EntityAddress[] | no | | -### Variant 2 (resolution.requestedTarget.kind="text") +### Variant 2 (success=false) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/format/small-caps.mdx b/apps/docs/document-api/reference/format/small-caps.mdx index 85ef01c8d5..91c81a122b 100644 --- a/apps/docs/document-api/reference/format/small-caps.mdx +++ b/apps/docs/document-api/reference/format/small-caps.mdx @@ -66,7 +66,7 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli ## Output fields -### Variant 1 (resolution.requestedTarget.kind="text") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | @@ -96,7 +96,7 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli | `success` | `true` | yes | Constant: `true` | | `updated` | EntityAddress[] | no | | -### Variant 2 (resolution.requestedTarget.kind="text") +### Variant 2 (success=false) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/format/snap-to-grid.mdx b/apps/docs/document-api/reference/format/snap-to-grid.mdx index 6381068677..7da10eda54 100644 --- a/apps/docs/document-api/reference/format/snap-to-grid.mdx +++ b/apps/docs/document-api/reference/format/snap-to-grid.mdx @@ -66,7 +66,7 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli ## Output fields -### Variant 1 (resolution.requestedTarget.kind="text") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | @@ -96,7 +96,7 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli | `success` | `true` | yes | Constant: `true` | | `updated` | EntityAddress[] | no | | -### Variant 2 (resolution.requestedTarget.kind="text") +### Variant 2 (success=false) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/format/spec-vanish.mdx b/apps/docs/document-api/reference/format/spec-vanish.mdx index 363f38907a..358699f1c3 100644 --- a/apps/docs/document-api/reference/format/spec-vanish.mdx +++ b/apps/docs/document-api/reference/format/spec-vanish.mdx @@ -66,7 +66,7 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli ## Output fields -### Variant 1 (resolution.requestedTarget.kind="text") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | @@ -96,7 +96,7 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli | `success` | `true` | yes | Constant: `true` | | `updated` | EntityAddress[] | no | | -### Variant 2 (resolution.requestedTarget.kind="text") +### Variant 2 (success=false) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/format/strike.mdx b/apps/docs/document-api/reference/format/strike.mdx index 893936d966..d27479b7de 100644 --- a/apps/docs/document-api/reference/format/strike.mdx +++ b/apps/docs/document-api/reference/format/strike.mdx @@ -66,7 +66,7 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli ## Output fields -### Variant 1 (resolution.requestedTarget.kind="text") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | @@ -96,7 +96,7 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli | `success` | `true` | yes | Constant: `true` | | `updated` | EntityAddress[] | no | | -### Variant 2 (resolution.requestedTarget.kind="text") +### Variant 2 (success=false) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/format/stylistic-sets.mdx b/apps/docs/document-api/reference/format/stylistic-sets.mdx index c8bf9dc322..e9046d3311 100644 --- a/apps/docs/document-api/reference/format/stylistic-sets.mdx +++ b/apps/docs/document-api/reference/format/stylistic-sets.mdx @@ -71,7 +71,7 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli ## Output fields -### Variant 1 (resolution.requestedTarget.kind="text") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | @@ -101,7 +101,7 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli | `success` | `true` | yes | Constant: `true` | | `updated` | EntityAddress[] | no | | -### Variant 2 (resolution.requestedTarget.kind="text") +### Variant 2 (success=false) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/format/underline.mdx b/apps/docs/document-api/reference/format/underline.mdx index a0327df84b..abeb32b7da 100644 --- a/apps/docs/document-api/reference/format/underline.mdx +++ b/apps/docs/document-api/reference/format/underline.mdx @@ -66,7 +66,7 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli ## Output fields -### Variant 1 (resolution.requestedTarget.kind="text") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | @@ -96,7 +96,7 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli | `success` | `true` | yes | Constant: `true` | | `updated` | EntityAddress[] | no | | -### Variant 2 (resolution.requestedTarget.kind="text") +### Variant 2 (success=false) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/format/vanish.mdx b/apps/docs/document-api/reference/format/vanish.mdx index 5259ee2184..4a35c2523f 100644 --- a/apps/docs/document-api/reference/format/vanish.mdx +++ b/apps/docs/document-api/reference/format/vanish.mdx @@ -66,7 +66,7 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli ## Output fields -### Variant 1 (resolution.requestedTarget.kind="text") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | @@ -96,7 +96,7 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli | `success` | `true` | yes | Constant: `true` | | `updated` | EntityAddress[] | no | | -### Variant 2 (resolution.requestedTarget.kind="text") +### Variant 2 (success=false) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/format/vert-align.mdx b/apps/docs/document-api/reference/format/vert-align.mdx index 4f15b65e94..8356c07382 100644 --- a/apps/docs/document-api/reference/format/vert-align.mdx +++ b/apps/docs/document-api/reference/format/vert-align.mdx @@ -66,7 +66,7 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli ## Output fields -### Variant 1 (resolution.requestedTarget.kind="text") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | @@ -96,7 +96,7 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli | `success` | `true` | yes | Constant: `true` | | `updated` | EntityAddress[] | no | | -### Variant 2 (resolution.requestedTarget.kind="text") +### Variant 2 (success=false) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/format/web-hidden.mdx b/apps/docs/document-api/reference/format/web-hidden.mdx index 7f02108c2c..854ea6f43b 100644 --- a/apps/docs/document-api/reference/format/web-hidden.mdx +++ b/apps/docs/document-api/reference/format/web-hidden.mdx @@ -66,7 +66,7 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli ## Output fields -### Variant 1 (resolution.requestedTarget.kind="text") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | @@ -96,7 +96,7 @@ Returns a TextMutationReceipt confirming the inline run property patch was appli | `success` | `true` | yes | Constant: `true` | | `updated` | EntityAddress[] | no | | -### Variant 2 (resolution.requestedTarget.kind="text") +### Variant 2 (success=false) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/header-footers/refs/clear.mdx b/apps/docs/document-api/reference/header-footers/refs/clear.mdx index 07c0bf641a..008e96f002 100644 --- a/apps/docs/document-api/reference/header-footers/refs/clear.mdx +++ b/apps/docs/document-api/reference/header-footers/refs/clear.mdx @@ -54,7 +54,7 @@ Returns a SectionMutationResult receipt; reports NO_OP if no explicit reference ## Output fields -### Variant 1 (section.kind="section") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/header-footers/refs/set-linked-to-previous.mdx b/apps/docs/document-api/reference/header-footers/refs/set-linked-to-previous.mdx index 123298891c..a55a1c3a20 100644 --- a/apps/docs/document-api/reference/header-footers/refs/set-linked-to-previous.mdx +++ b/apps/docs/document-api/reference/header-footers/refs/set-linked-to-previous.mdx @@ -56,7 +56,7 @@ Returns a SectionMutationResult receipt; reports NO_OP if the link state already ## Output fields -### Variant 1 (section.kind="section") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/header-footers/refs/set.mdx b/apps/docs/document-api/reference/header-footers/refs/set.mdx index 087b03e9bd..8988d05035 100644 --- a/apps/docs/document-api/reference/header-footers/refs/set.mdx +++ b/apps/docs/document-api/reference/header-footers/refs/set.mdx @@ -56,7 +56,7 @@ Returns a SectionMutationResult receipt; reports NO_OP if the reference already ## Output fields -### Variant 1 (section.kind="section") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/hyperlinks/insert.mdx b/apps/docs/document-api/reference/hyperlinks/insert.mdx index 852f621bbc..db11c3e858 100644 --- a/apps/docs/document-api/reference/hyperlinks/insert.mdx +++ b/apps/docs/document-api/reference/hyperlinks/insert.mdx @@ -70,7 +70,7 @@ Returns a HyperlinkMutationResult with the created hyperlink address on success, ## Output fields -### Variant 1 (hyperlink.kind="inline") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/hyperlinks/patch.mdx b/apps/docs/document-api/reference/hyperlinks/patch.mdx index fdf77fa413..d0971bbe8f 100644 --- a/apps/docs/document-api/reference/hyperlinks/patch.mdx +++ b/apps/docs/document-api/reference/hyperlinks/patch.mdx @@ -73,7 +73,7 @@ Returns a HyperlinkMutationResult with the updated hyperlink address on success, ## Output fields -### Variant 1 (hyperlink.kind="inline") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/hyperlinks/remove.mdx b/apps/docs/document-api/reference/hyperlinks/remove.mdx index 22ef399f4d..7e0900376a 100644 --- a/apps/docs/document-api/reference/hyperlinks/remove.mdx +++ b/apps/docs/document-api/reference/hyperlinks/remove.mdx @@ -64,7 +64,7 @@ Returns a HyperlinkMutationResult with the removed hyperlink address on success, ## Output fields -### Variant 1 (hyperlink.kind="inline") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/hyperlinks/wrap.mdx b/apps/docs/document-api/reference/hyperlinks/wrap.mdx index 050de1d159..a99c861c3f 100644 --- a/apps/docs/document-api/reference/hyperlinks/wrap.mdx +++ b/apps/docs/document-api/reference/hyperlinks/wrap.mdx @@ -68,7 +68,7 @@ Returns a HyperlinkMutationResult with the created hyperlink address on success, ## Output fields -### Variant 1 (hyperlink.kind="inline") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/index/configure.mdx b/apps/docs/document-api/reference/index/configure.mdx index fec12730b9..bbba79c0c2 100644 --- a/apps/docs/document-api/reference/index/configure.mdx +++ b/apps/docs/document-api/reference/index/configure.mdx @@ -64,7 +64,7 @@ Returns an IndexMutationResult indicating success or a failure. ## Output fields -### Variant 1 (index.kind="block") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/index/entries-insert.mdx b/apps/docs/document-api/reference/index/entries-insert.mdx index 2492a81310..c68a99f427 100644 --- a/apps/docs/document-api/reference/index/entries-insert.mdx +++ b/apps/docs/document-api/reference/index/entries-insert.mdx @@ -67,7 +67,7 @@ Returns an IndexEntryMutationResult indicating success with the entry address or ## Output fields -### Variant 1 (entry.kind="inline") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/index/entries-remove.mdx b/apps/docs/document-api/reference/index/entries-remove.mdx index f4056121ee..d00f34c3e3 100644 --- a/apps/docs/document-api/reference/index/entries-remove.mdx +++ b/apps/docs/document-api/reference/index/entries-remove.mdx @@ -62,7 +62,7 @@ Returns an IndexEntryMutationResult indicating success or a failure. ## Output fields -### Variant 1 (entry.kind="inline") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/index/entries-update.mdx b/apps/docs/document-api/reference/index/entries-update.mdx index 4291ec0731..c4eb2961d7 100644 --- a/apps/docs/document-api/reference/index/entries-update.mdx +++ b/apps/docs/document-api/reference/index/entries-update.mdx @@ -75,7 +75,7 @@ Returns an IndexEntryMutationResult indicating success or a failure. ## Output fields -### Variant 1 (entry.kind="inline") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/index/insert.mdx b/apps/docs/document-api/reference/index/insert.mdx index e3f1fb948c..ff7fa91e99 100644 --- a/apps/docs/document-api/reference/index/insert.mdx +++ b/apps/docs/document-api/reference/index/insert.mdx @@ -59,7 +59,7 @@ Returns an IndexMutationResult indicating success with the index address or a fa ## Output fields -### Variant 1 (index.kind="block") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/index/rebuild.mdx b/apps/docs/document-api/reference/index/rebuild.mdx index 4bd0264c20..3fb0243f8e 100644 --- a/apps/docs/document-api/reference/index/rebuild.mdx +++ b/apps/docs/document-api/reference/index/rebuild.mdx @@ -47,7 +47,7 @@ Returns an IndexMutationResult indicating success or a failure. ## Output fields -### Variant 1 (index.kind="block") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/index/remove.mdx b/apps/docs/document-api/reference/index/remove.mdx index b83fba7775..74b7466d88 100644 --- a/apps/docs/document-api/reference/index/remove.mdx +++ b/apps/docs/document-api/reference/index/remove.mdx @@ -47,7 +47,7 @@ Returns an IndexMutationResult indicating success or a failure. ## Output fields -### Variant 1 (index.kind="block") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/insert.mdx b/apps/docs/document-api/reference/insert.mdx index 3253612f16..0a3f788219 100644 --- a/apps/docs/document-api/reference/insert.mdx +++ b/apps/docs/document-api/reference/insert.mdx @@ -22,10 +22,12 @@ Insert content into the document. Two input shapes: legacy string-based (value + ## Expected result -Returns a TextMutationReceipt with applied status; receipt reports NO_OP if the insertion point is invalid or content is empty. +Returns an SDMutationReceipt with applied status; resolution reports a TextAddress for legacy text insertion or a BlockNodeAddress for structural insertion. Receipt reports NO_OP if the insertion point is invalid or content is empty. ## Input fields +### Variant 1 (target.kind="text") + | Field | Type | Required | Description | | --- | --- | --- | --- | | `target` | TextAddress | no | TextAddress | @@ -37,26 +39,44 @@ Returns a TextMutationReceipt with applied status; receipt reports NO_OP if the | `type` | enum | no | `"text"`, `"markdown"`, `"html"` | | `value` | string | yes | | +### Variant 2 (target.kind="block") + +| Field | Type | Required | Description | +| --- | --- | --- | --- | +| `content` | object | yes | | +| `nestingPolicy` | object | no | | +| `nestingPolicy.tables` | enum | no | `"forbid"`, `"allow"` | +| `placement` | enum | no | `"before"`, `"after"`, `"insideStart"`, `"insideEnd"` | +| `target` | BlockNodeAddress | no | BlockNodeAddress | +| `target.kind` | `"block"` | no | Constant: `"block"` | +| `target.nodeId` | string | no | | +| `target.nodeType` | enum | no | `"paragraph"`, `"heading"`, `"listItem"`, `"table"`, `"tableRow"`, `"tableCell"`, `"tableOfContents"`, `"image"`, `"sdt"` | + ### Example request ```json { - "target": { - "blockId": "block-abc123", - "kind": "text", - "range": { - "end": 10, - "start": 0 - } + "content": { + "content": [ + { + "text": "example", + "type": "text" + } + ], + "type": "paragraph" }, - "type": "text", - "value": "example" + "placement": "after", + "target": { + "kind": "block", + "nodeId": "node-def456", + "nodeType": "paragraph" + } } ``` ## Output fields -### Variant 1 (resolution.selectionTarget.kind="selection") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | @@ -74,7 +94,7 @@ Returns a TextMutationReceipt with applied status; receipt reports NO_OP if the | `resolution.target` | TextAddress \\| BlockNodeAddress | no | One of: TextAddress, BlockNodeAddress | | `success` | `true` | yes | Constant: `true` | -### Variant 2 (resolution.selectionTarget.kind="selection") +### Variant 2 (success=false) | Field | Type | Required | Description | | --- | --- | --- | --- | @@ -101,34 +121,18 @@ Returns a TextMutationReceipt with applied status; receipt reports NO_OP if the ```json { "evaluatedRevision": { - "after": "example", - "before": "example" + "after": "rev-002", + "before": "rev-001" }, "resolution": { "range": { - "from": 0, - "to": 10 - }, - "selectionTarget": { - "end": { - "blockId": "block-abc123", - "kind": "text", - "offset": 0 - }, - "kind": "selection", - "start": { - "blockId": "block-abc123", - "kind": "text", - "offset": 0 - } + "from": 42, + "to": 42 }, "target": { - "blockId": "block-abc123", - "kind": "text", - "range": { - "end": 10, - "start": 0 - } + "kind": "block", + "nodeId": "node-def456", + "nodeType": "paragraph" } }, "success": true @@ -169,27 +173,66 @@ Returns a TextMutationReceipt with applied status; receipt reports NO_OP if the ```json { - "additionalProperties": false, - "properties": { - "target": { - "$ref": "#/$defs/TextAddress" - }, - "type": { - "enum": [ - "text", - "markdown", - "html" + "oneOf": [ + { + "additionalProperties": false, + "properties": { + "target": { + "$ref": "#/$defs/TextAddress" + }, + "type": { + "enum": [ + "text", + "markdown", + "html" + ], + "type": "string" + }, + "value": { + "type": "string" + } + }, + "required": [ + "value" ], - "type": "string" + "type": "object" }, - "value": { - "type": "string" + { + "additionalProperties": false, + "properties": { + "content": { + "type": "object" + }, + "nestingPolicy": { + "additionalProperties": false, + "properties": { + "tables": { + "enum": [ + "forbid", + "allow" + ] + } + }, + "type": "object" + }, + "placement": { + "enum": [ + "before", + "after", + "insideStart", + "insideEnd" + ] + }, + "target": { + "$ref": "#/$defs/BlockNodeAddress" + } + }, + "required": [ + "content" + ], + "type": "object" } - }, - "required": [ - "value" - ], - "type": "object" + ] } ``` diff --git a/apps/docs/document-api/reference/lists/apply-preset.mdx b/apps/docs/document-api/reference/lists/apply-preset.mdx index fda45fb278..ab2ff51772 100644 --- a/apps/docs/document-api/reference/lists/apply-preset.mdx +++ b/apps/docs/document-api/reference/lists/apply-preset.mdx @@ -53,7 +53,7 @@ Returns a ListsMutateItemResult receipt; reports NO_OP if all levels already mat ## Output fields -### Variant 1 (item.kind="block") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/lists/apply-template.mdx b/apps/docs/document-api/reference/lists/apply-template.mdx index 8a91993f0b..c34187c1ab 100644 --- a/apps/docs/document-api/reference/lists/apply-template.mdx +++ b/apps/docs/document-api/reference/lists/apply-template.mdx @@ -64,7 +64,7 @@ Returns a ListsMutateItemResult receipt; reports NO_OP if all levels already mat ## Output fields -### Variant 1 (item.kind="block") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/lists/attach.mdx b/apps/docs/document-api/reference/lists/attach.mdx index f19db21702..3d41db9af6 100644 --- a/apps/docs/document-api/reference/lists/attach.mdx +++ b/apps/docs/document-api/reference/lists/attach.mdx @@ -55,7 +55,7 @@ Returns a ListsMutateItemResult confirming attachment. ## Output fields -### Variant 1 (item.kind="block") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/lists/clear-level-overrides.mdx b/apps/docs/document-api/reference/lists/clear-level-overrides.mdx index 6d13eb2a0a..d96be8b0f3 100644 --- a/apps/docs/document-api/reference/lists/clear-level-overrides.mdx +++ b/apps/docs/document-api/reference/lists/clear-level-overrides.mdx @@ -49,7 +49,7 @@ Returns a ListsMutateItemResult receipt; reports NO_OP if no override exists. ## Output fields -### Variant 1 (item.kind="block") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/lists/continue-previous.mdx b/apps/docs/document-api/reference/lists/continue-previous.mdx index 34eec4b625..beaf22455f 100644 --- a/apps/docs/document-api/reference/lists/continue-previous.mdx +++ b/apps/docs/document-api/reference/lists/continue-previous.mdx @@ -47,7 +47,7 @@ Returns a ListsMutateItemResult receipt. ## Output fields -### Variant 1 (item.kind="block") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/lists/convert-to-text.mdx b/apps/docs/document-api/reference/lists/convert-to-text.mdx index 636742d36a..ad68555cad 100644 --- a/apps/docs/document-api/reference/lists/convert-to-text.mdx +++ b/apps/docs/document-api/reference/lists/convert-to-text.mdx @@ -49,7 +49,7 @@ Returns a ListsConvertToTextResult confirming the conversion. ## Output fields -### Variant 1 (paragraph.kind="block") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/lists/create.mdx b/apps/docs/document-api/reference/lists/create.mdx index 09d07e012b..ed7b2d7d5a 100644 --- a/apps/docs/document-api/reference/lists/create.mdx +++ b/apps/docs/document-api/reference/lists/create.mdx @@ -58,7 +58,7 @@ Returns a ListsCreateResult with the new listId and the first item address. ## Output fields -### Variant 1 (item.kind="block") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/lists/detach.mdx b/apps/docs/document-api/reference/lists/detach.mdx index d3d7d89fb1..a67c5c3bfa 100644 --- a/apps/docs/document-api/reference/lists/detach.mdx +++ b/apps/docs/document-api/reference/lists/detach.mdx @@ -47,7 +47,7 @@ Returns a ListsDetachResult confirming the item was converted to a plain paragra ## Output fields -### Variant 1 (paragraph.kind="block") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/lists/indent.mdx b/apps/docs/document-api/reference/lists/indent.mdx index 76ce8058de..8e4502d901 100644 --- a/apps/docs/document-api/reference/lists/indent.mdx +++ b/apps/docs/document-api/reference/lists/indent.mdx @@ -47,7 +47,7 @@ Returns a ListsMutateItemResult receipt; reports NO_OP if the item is already at ## Output fields -### Variant 1 (item.kind="block") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/lists/insert.mdx b/apps/docs/document-api/reference/lists/insert.mdx index d7d8720ef4..1312b3ea44 100644 --- a/apps/docs/document-api/reference/lists/insert.mdx +++ b/apps/docs/document-api/reference/lists/insert.mdx @@ -51,7 +51,7 @@ Returns a ListsInsertResult with the new list item address and block ID. ## Output fields -### Variant 1 (item.kind="block") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/lists/outdent.mdx b/apps/docs/document-api/reference/lists/outdent.mdx index 027bd8767d..b0ddd81a4f 100644 --- a/apps/docs/document-api/reference/lists/outdent.mdx +++ b/apps/docs/document-api/reference/lists/outdent.mdx @@ -47,7 +47,7 @@ Returns a ListsMutateItemResult receipt; reports NO_OP if the item is already at ## Output fields -### Variant 1 (item.kind="block") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/lists/set-level-alignment.mdx b/apps/docs/document-api/reference/lists/set-level-alignment.mdx index cba39d499f..1fd5a99e20 100644 --- a/apps/docs/document-api/reference/lists/set-level-alignment.mdx +++ b/apps/docs/document-api/reference/lists/set-level-alignment.mdx @@ -51,7 +51,7 @@ Returns a ListsMutateItemResult receipt; reports NO_OP if the alignment already ## Output fields -### Variant 1 (item.kind="block") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/lists/set-level-bullet.mdx b/apps/docs/document-api/reference/lists/set-level-bullet.mdx index b3ac100d0e..728b613170 100644 --- a/apps/docs/document-api/reference/lists/set-level-bullet.mdx +++ b/apps/docs/document-api/reference/lists/set-level-bullet.mdx @@ -51,7 +51,7 @@ Returns a ListsMutateItemResult receipt; reports NO_OP if the marker already mat ## Output fields -### Variant 1 (item.kind="block") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/lists/set-level-indents.mdx b/apps/docs/document-api/reference/lists/set-level-indents.mdx index 7650a4ce2a..4a6abe277d 100644 --- a/apps/docs/document-api/reference/lists/set-level-indents.mdx +++ b/apps/docs/document-api/reference/lists/set-level-indents.mdx @@ -56,7 +56,7 @@ _No fields._ ## Output fields -### Variant 1 (item.kind="block") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/lists/set-level-marker-font.mdx b/apps/docs/document-api/reference/lists/set-level-marker-font.mdx index 838ef02bc5..2bd9363b49 100644 --- a/apps/docs/document-api/reference/lists/set-level-marker-font.mdx +++ b/apps/docs/document-api/reference/lists/set-level-marker-font.mdx @@ -51,7 +51,7 @@ Returns a ListsMutateItemResult receipt; reports NO_OP if the font already match ## Output fields -### Variant 1 (item.kind="block") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/lists/set-level-numbering.mdx b/apps/docs/document-api/reference/lists/set-level-numbering.mdx index 0ae4c6a77f..16c6acebe2 100644 --- a/apps/docs/document-api/reference/lists/set-level-numbering.mdx +++ b/apps/docs/document-api/reference/lists/set-level-numbering.mdx @@ -55,7 +55,7 @@ Returns a ListsMutateItemResult receipt; reports NO_OP if the level already matc ## Output fields -### Variant 1 (item.kind="block") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/lists/set-level-picture-bullet.mdx b/apps/docs/document-api/reference/lists/set-level-picture-bullet.mdx index 23bf4b24ac..54747c58a3 100644 --- a/apps/docs/document-api/reference/lists/set-level-picture-bullet.mdx +++ b/apps/docs/document-api/reference/lists/set-level-picture-bullet.mdx @@ -51,7 +51,7 @@ Returns a ListsMutateItemResult receipt; reports NO_OP if the picture bullet alr ## Output fields -### Variant 1 (item.kind="block") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/lists/set-level-restart.mdx b/apps/docs/document-api/reference/lists/set-level-restart.mdx index 24c291665b..8d8c69bc0e 100644 --- a/apps/docs/document-api/reference/lists/set-level-restart.mdx +++ b/apps/docs/document-api/reference/lists/set-level-restart.mdx @@ -53,7 +53,7 @@ Returns a ListsMutateItemResult receipt. ## Output fields -### Variant 1 (item.kind="block") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/lists/set-level-trailing-character.mdx b/apps/docs/document-api/reference/lists/set-level-trailing-character.mdx index 1c1aa1c7e4..01f6385172 100644 --- a/apps/docs/document-api/reference/lists/set-level-trailing-character.mdx +++ b/apps/docs/document-api/reference/lists/set-level-trailing-character.mdx @@ -51,7 +51,7 @@ Returns a ListsMutateItemResult receipt; reports NO_OP if the trailing character ## Output fields -### Variant 1 (item.kind="block") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/lists/set-level.mdx b/apps/docs/document-api/reference/lists/set-level.mdx index 8df0c15a2a..479ebda77d 100644 --- a/apps/docs/document-api/reference/lists/set-level.mdx +++ b/apps/docs/document-api/reference/lists/set-level.mdx @@ -49,7 +49,7 @@ Returns a ListsMutateItemResult receipt; reports NO_OP if already at the target ## Output fields -### Variant 1 (item.kind="block") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/lists/set-type.mdx b/apps/docs/document-api/reference/lists/set-type.mdx index f1798b4848..ffae4c53c3 100644 --- a/apps/docs/document-api/reference/lists/set-type.mdx +++ b/apps/docs/document-api/reference/lists/set-type.mdx @@ -51,7 +51,7 @@ Returns a ListsMutateItemResult receipt; reports NO_OP if the list is already th ## Output fields -### Variant 1 (item.kind="block") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/lists/set-value.mdx b/apps/docs/document-api/reference/lists/set-value.mdx index 8550ffcdaf..708f89ae66 100644 --- a/apps/docs/document-api/reference/lists/set-value.mdx +++ b/apps/docs/document-api/reference/lists/set-value.mdx @@ -49,7 +49,7 @@ Returns a ListsMutateItemResult receipt. ## Output fields -### Variant 1 (item.kind="block") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/replace.mdx b/apps/docs/document-api/reference/replace.mdx index f5654cab7f..a3bb0ec88f 100644 --- a/apps/docs/document-api/reference/replace.mdx +++ b/apps/docs/document-api/reference/replace.mdx @@ -26,13 +26,40 @@ Returns an SDMutationReceipt with applied status; receipt reports NO_OP if the t ## Input fields -### Variant 1 +### Variant 1.1 (target.kind="selection") -_No fields._ +| Field | Type | Required | Description | +| --- | --- | --- | --- | +| `target` | SelectionTarget | yes | SelectionTarget | +| `target.end` | SelectionPoint | yes | SelectionPoint | +| `target.kind` | `"selection"` | yes | Constant: `"selection"` | +| `target.start` | SelectionPoint | yes | SelectionPoint | +| `text` | string | yes | | + +### Variant 1.2 + +| Field | Type | Required | Description | +| --- | --- | --- | --- | +| `ref` | string | yes | | +| `text` | string | yes | | + +### Variant 2.1 + +| Field | Type | Required | Description | +| --- | --- | --- | --- | +| `content` | object | yes | | +| `nestingPolicy` | object | no | | +| `nestingPolicy.tables` | enum | no | `"forbid"`, `"allow"` | +| `target` | BlockNodeAddress \\| SelectionTarget | yes | One of: BlockNodeAddress, SelectionTarget | -### Variant 2 +### Variant 2.2 -_No fields._ +| Field | Type | Required | Description | +| --- | --- | --- | --- | +| `content` | object | yes | | +| `nestingPolicy` | object | no | | +| `nestingPolicy.tables` | enum | no | `"forbid"`, `"allow"` | +| `ref` | string | yes | | ### Example request @@ -42,7 +69,7 @@ _No fields._ "end": { "blockId": "block-abc123", "kind": "text", - "offset": 0 + "offset": 12 }, "kind": "selection", "start": { @@ -57,7 +84,7 @@ _No fields._ ## Output fields -### Variant 1 (resolution.selectionTarget.kind="selection") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | @@ -75,7 +102,7 @@ _No fields._ | `resolution.target` | TextAddress \\| BlockNodeAddress | no | One of: TextAddress, BlockNodeAddress | | `success` | `true` | yes | Constant: `true` | -### Variant 2 (resolution.selectionTarget.kind="selection") +### Variant 2 (success=false) | Field | Type | Required | Description | | --- | --- | --- | --- | @@ -102,32 +129,19 @@ _No fields._ ```json { "evaluatedRevision": { - "after": "example", - "before": "example" + "after": "rev-002", + "before": "rev-001" }, "resolution": { "range": { "from": 0, - "to": 10 - }, - "selectionTarget": { - "end": { - "blockId": "block-abc123", - "kind": "text", - "offset": 0 - }, - "kind": "selection", - "start": { - "blockId": "block-abc123", - "kind": "text", - "offset": 0 - } + "to": 12 }, "target": { "blockId": "block-abc123", "kind": "text", "range": { - "end": 10, + "end": 12, "start": 0 } } @@ -214,6 +228,15 @@ _No fields._ "type": "object" }, "nestingPolicy": { + "additionalProperties": false, + "properties": { + "tables": { + "enum": [ + "forbid", + "allow" + ] + } + }, "type": "object" }, "target": { @@ -240,6 +263,15 @@ _No fields._ "type": "object" }, "nestingPolicy": { + "additionalProperties": false, + "properties": { + "tables": { + "enum": [ + "forbid", + "allow" + ] + } + }, "type": "object" }, "ref": { diff --git a/apps/docs/document-api/reference/sections/clear-header-footer-ref.mdx b/apps/docs/document-api/reference/sections/clear-header-footer-ref.mdx index 94d10531c6..a6d4b25cf6 100644 --- a/apps/docs/document-api/reference/sections/clear-header-footer-ref.mdx +++ b/apps/docs/document-api/reference/sections/clear-header-footer-ref.mdx @@ -49,7 +49,7 @@ Returns a SectionMutationResult receipt; reports NO_OP if no reference exists fo ## Output fields -### Variant 1 (section.kind="section") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/sections/clear-page-borders.mdx b/apps/docs/document-api/reference/sections/clear-page-borders.mdx index 9466b7e6a3..336aaf9ff0 100644 --- a/apps/docs/document-api/reference/sections/clear-page-borders.mdx +++ b/apps/docs/document-api/reference/sections/clear-page-borders.mdx @@ -45,7 +45,7 @@ Returns a SectionMutationResult receipt; reports NO_OP if no page borders are co ## Output fields -### Variant 1 (section.kind="section") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/sections/set-break-type.mdx b/apps/docs/document-api/reference/sections/set-break-type.mdx index 8faab66ed6..e5c9af8b30 100644 --- a/apps/docs/document-api/reference/sections/set-break-type.mdx +++ b/apps/docs/document-api/reference/sections/set-break-type.mdx @@ -47,7 +47,7 @@ Returns a SectionMutationResult receipt; reports NO_OP if the section already ha ## Output fields -### Variant 1 (section.kind="section") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/sections/set-columns.mdx b/apps/docs/document-api/reference/sections/set-columns.mdx index d4c072c382..4922dcc7ad 100644 --- a/apps/docs/document-api/reference/sections/set-columns.mdx +++ b/apps/docs/document-api/reference/sections/set-columns.mdx @@ -54,7 +54,7 @@ _No fields._ ## Output fields -### Variant 1 (section.kind="section") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/sections/set-header-footer-margins.mdx b/apps/docs/document-api/reference/sections/set-header-footer-margins.mdx index 76248e9ec5..a927c4f479 100644 --- a/apps/docs/document-api/reference/sections/set-header-footer-margins.mdx +++ b/apps/docs/document-api/reference/sections/set-header-footer-margins.mdx @@ -49,7 +49,7 @@ _No fields._ ## Output fields -### Variant 1 (section.kind="section") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/sections/set-header-footer-ref.mdx b/apps/docs/document-api/reference/sections/set-header-footer-ref.mdx index 0bf8174ecd..6b0c6731fd 100644 --- a/apps/docs/document-api/reference/sections/set-header-footer-ref.mdx +++ b/apps/docs/document-api/reference/sections/set-header-footer-ref.mdx @@ -51,7 +51,7 @@ Returns a SectionMutationResult receipt; reports NO_OP if the header/footer refe ## Output fields -### Variant 1 (section.kind="section") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/sections/set-line-numbering.mdx b/apps/docs/document-api/reference/sections/set-line-numbering.mdx index 04c4989d9a..f72c331d91 100644 --- a/apps/docs/document-api/reference/sections/set-line-numbering.mdx +++ b/apps/docs/document-api/reference/sections/set-line-numbering.mdx @@ -53,7 +53,7 @@ Returns a SectionMutationResult receipt; reports NO_OP if line numbering setting ## Output fields -### Variant 1 (section.kind="section") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/sections/set-link-to-previous.mdx b/apps/docs/document-api/reference/sections/set-link-to-previous.mdx index ad52fb62a7..84f6ec79e4 100644 --- a/apps/docs/document-api/reference/sections/set-link-to-previous.mdx +++ b/apps/docs/document-api/reference/sections/set-link-to-previous.mdx @@ -51,7 +51,7 @@ Returns a SectionMutationResult receipt; reports NO_OP if link-to-previous alrea ## Output fields -### Variant 1 (section.kind="section") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/sections/set-page-borders.mdx b/apps/docs/document-api/reference/sections/set-page-borders.mdx index e9dc0d87b8..6893ab4db1 100644 --- a/apps/docs/document-api/reference/sections/set-page-borders.mdx +++ b/apps/docs/document-api/reference/sections/set-page-borders.mdx @@ -82,7 +82,7 @@ Returns a SectionMutationResult receipt; reports NO_OP if page border configurat ## Output fields -### Variant 1 (section.kind="section") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/sections/set-page-margins.mdx b/apps/docs/document-api/reference/sections/set-page-margins.mdx index b306e34ef1..1c24d4cb44 100644 --- a/apps/docs/document-api/reference/sections/set-page-margins.mdx +++ b/apps/docs/document-api/reference/sections/set-page-margins.mdx @@ -62,7 +62,7 @@ _No fields._ ## Output fields -### Variant 1 (section.kind="section") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/sections/set-page-numbering.mdx b/apps/docs/document-api/reference/sections/set-page-numbering.mdx index 3fd618f0f8..a680a84813 100644 --- a/apps/docs/document-api/reference/sections/set-page-numbering.mdx +++ b/apps/docs/document-api/reference/sections/set-page-numbering.mdx @@ -49,7 +49,7 @@ _No fields._ ## Output fields -### Variant 1 (section.kind="section") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/sections/set-page-setup.mdx b/apps/docs/document-api/reference/sections/set-page-setup.mdx index eb70806ce5..710ed3b948 100644 --- a/apps/docs/document-api/reference/sections/set-page-setup.mdx +++ b/apps/docs/document-api/reference/sections/set-page-setup.mdx @@ -58,7 +58,7 @@ _No fields._ ## Output fields -### Variant 1 (section.kind="section") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/sections/set-section-direction.mdx b/apps/docs/document-api/reference/sections/set-section-direction.mdx index 3d49c2ddb8..4d396650de 100644 --- a/apps/docs/document-api/reference/sections/set-section-direction.mdx +++ b/apps/docs/document-api/reference/sections/set-section-direction.mdx @@ -47,7 +47,7 @@ Returns a SectionMutationResult receipt; reports NO_OP if text direction already ## Output fields -### Variant 1 (section.kind="section") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/sections/set-title-page.mdx b/apps/docs/document-api/reference/sections/set-title-page.mdx index de53ad3bdf..e60fd979a5 100644 --- a/apps/docs/document-api/reference/sections/set-title-page.mdx +++ b/apps/docs/document-api/reference/sections/set-title-page.mdx @@ -47,7 +47,7 @@ Returns a SectionMutationResult receipt; reports NO_OP if the title-page setting ## Output fields -### Variant 1 (section.kind="section") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/sections/set-vertical-align.mdx b/apps/docs/document-api/reference/sections/set-vertical-align.mdx index 7d415e506c..44be53d96d 100644 --- a/apps/docs/document-api/reference/sections/set-vertical-align.mdx +++ b/apps/docs/document-api/reference/sections/set-vertical-align.mdx @@ -47,7 +47,7 @@ Returns a SectionMutationResult receipt; reports NO_OP if vertical alignment alr ## Output fields -### Variant 1 (section.kind="section") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/tables/apply-border-preset.mdx b/apps/docs/document-api/reference/tables/apply-border-preset.mdx index 2e1ee173a3..fa7093598c 100644 --- a/apps/docs/document-api/reference/tables/apply-border-preset.mdx +++ b/apps/docs/document-api/reference/tables/apply-border-preset.mdx @@ -50,7 +50,7 @@ _No fields._ ## Output fields -### Variant 1 (table.kind="block") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/tables/clear-border.mdx b/apps/docs/document-api/reference/tables/clear-border.mdx index f99240f1aa..a8d6afb6ba 100644 --- a/apps/docs/document-api/reference/tables/clear-border.mdx +++ b/apps/docs/document-api/reference/tables/clear-border.mdx @@ -50,7 +50,7 @@ _No fields._ ## Output fields -### Variant 1 (table.kind="block") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/tables/clear-cell-spacing.mdx b/apps/docs/document-api/reference/tables/clear-cell-spacing.mdx index c6d8c4c783..0179ad49c1 100644 --- a/apps/docs/document-api/reference/tables/clear-cell-spacing.mdx +++ b/apps/docs/document-api/reference/tables/clear-cell-spacing.mdx @@ -49,7 +49,7 @@ _No fields._ ## Output fields -### Variant 1 (table.kind="block") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/tables/clear-contents.mdx b/apps/docs/document-api/reference/tables/clear-contents.mdx index 55430d21ab..919cc3343c 100644 --- a/apps/docs/document-api/reference/tables/clear-contents.mdx +++ b/apps/docs/document-api/reference/tables/clear-contents.mdx @@ -49,7 +49,7 @@ _No fields._ ## Output fields -### Variant 1 (table.kind="block") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/tables/clear-shading.mdx b/apps/docs/document-api/reference/tables/clear-shading.mdx index cfebf13cdd..90aac8e32f 100644 --- a/apps/docs/document-api/reference/tables/clear-shading.mdx +++ b/apps/docs/document-api/reference/tables/clear-shading.mdx @@ -49,7 +49,7 @@ _No fields._ ## Output fields -### Variant 1 (table.kind="block") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/tables/clear-style.mdx b/apps/docs/document-api/reference/tables/clear-style.mdx index 00710610df..a1e923643d 100644 --- a/apps/docs/document-api/reference/tables/clear-style.mdx +++ b/apps/docs/document-api/reference/tables/clear-style.mdx @@ -49,7 +49,7 @@ _No fields._ ## Output fields -### Variant 1 (table.kind="block") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/tables/convert-from-text.mdx b/apps/docs/document-api/reference/tables/convert-from-text.mdx index e9fdeb4acb..9fd6756a1f 100644 --- a/apps/docs/document-api/reference/tables/convert-from-text.mdx +++ b/apps/docs/document-api/reference/tables/convert-from-text.mdx @@ -50,7 +50,7 @@ _No fields._ ## Output fields -### Variant 1 (table.kind="block") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/tables/convert-to-text.mdx b/apps/docs/document-api/reference/tables/convert-to-text.mdx index db704bb89a..e658aa58ea 100644 --- a/apps/docs/document-api/reference/tables/convert-to-text.mdx +++ b/apps/docs/document-api/reference/tables/convert-to-text.mdx @@ -50,7 +50,7 @@ _No fields._ ## Output fields -### Variant 1 (table.kind="block") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/tables/delete-cell.mdx b/apps/docs/document-api/reference/tables/delete-cell.mdx index 942a79c5cc..760f679525 100644 --- a/apps/docs/document-api/reference/tables/delete-cell.mdx +++ b/apps/docs/document-api/reference/tables/delete-cell.mdx @@ -50,7 +50,7 @@ _No fields._ ## Output fields -### Variant 1 (table.kind="block") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/tables/delete-column.mdx b/apps/docs/document-api/reference/tables/delete-column.mdx index 44067e6427..1cff7f06a8 100644 --- a/apps/docs/document-api/reference/tables/delete-column.mdx +++ b/apps/docs/document-api/reference/tables/delete-column.mdx @@ -50,7 +50,7 @@ _No fields._ ## Output fields -### Variant 1 (table.kind="block") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/tables/delete-row.mdx b/apps/docs/document-api/reference/tables/delete-row.mdx index dcdfc97cb7..795449da50 100644 --- a/apps/docs/document-api/reference/tables/delete-row.mdx +++ b/apps/docs/document-api/reference/tables/delete-row.mdx @@ -62,7 +62,7 @@ _No fields._ ## Output fields -### Variant 1 (table.kind="block") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/tables/delete.mdx b/apps/docs/document-api/reference/tables/delete.mdx index bdd439643f..b8429d2e6b 100644 --- a/apps/docs/document-api/reference/tables/delete.mdx +++ b/apps/docs/document-api/reference/tables/delete.mdx @@ -49,7 +49,7 @@ _No fields._ ## Output fields -### Variant 1 (table.kind="block") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/tables/distribute-columns.mdx b/apps/docs/document-api/reference/tables/distribute-columns.mdx index 323336a4d2..4a77999425 100644 --- a/apps/docs/document-api/reference/tables/distribute-columns.mdx +++ b/apps/docs/document-api/reference/tables/distribute-columns.mdx @@ -53,7 +53,7 @@ _No fields._ ## Output fields -### Variant 1 (table.kind="block") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/tables/distribute-rows.mdx b/apps/docs/document-api/reference/tables/distribute-rows.mdx index 91e74d546c..b5bca6f90e 100644 --- a/apps/docs/document-api/reference/tables/distribute-rows.mdx +++ b/apps/docs/document-api/reference/tables/distribute-rows.mdx @@ -49,7 +49,7 @@ _No fields._ ## Output fields -### Variant 1 (table.kind="block") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/tables/insert-cell.mdx b/apps/docs/document-api/reference/tables/insert-cell.mdx index 089286b09c..8bf9ecedbb 100644 --- a/apps/docs/document-api/reference/tables/insert-cell.mdx +++ b/apps/docs/document-api/reference/tables/insert-cell.mdx @@ -50,7 +50,7 @@ _No fields._ ## Output fields -### Variant 1 (table.kind="block") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/tables/insert-column.mdx b/apps/docs/document-api/reference/tables/insert-column.mdx index e98df8f8be..45db92077f 100644 --- a/apps/docs/document-api/reference/tables/insert-column.mdx +++ b/apps/docs/document-api/reference/tables/insert-column.mdx @@ -52,7 +52,7 @@ _No fields._ ## Output fields -### Variant 1 (table.kind="block") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/tables/insert-row.mdx b/apps/docs/document-api/reference/tables/insert-row.mdx index da13647c79..52f76a3525 100644 --- a/apps/docs/document-api/reference/tables/insert-row.mdx +++ b/apps/docs/document-api/reference/tables/insert-row.mdx @@ -63,7 +63,7 @@ _No fields._ ## Output fields -### Variant 1 (table.kind="block") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/tables/merge-cells.mdx b/apps/docs/document-api/reference/tables/merge-cells.mdx index a6900ec6b6..93ef2217e3 100644 --- a/apps/docs/document-api/reference/tables/merge-cells.mdx +++ b/apps/docs/document-api/reference/tables/merge-cells.mdx @@ -57,7 +57,7 @@ _No fields._ ## Output fields -### Variant 1 (table.kind="block") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/tables/move.mdx b/apps/docs/document-api/reference/tables/move.mdx index cc373dc1ee..4722dee631 100644 --- a/apps/docs/document-api/reference/tables/move.mdx +++ b/apps/docs/document-api/reference/tables/move.mdx @@ -52,7 +52,7 @@ _No fields._ ## Output fields -### Variant 1 (table.kind="block") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/tables/set-alt-text.mdx b/apps/docs/document-api/reference/tables/set-alt-text.mdx index 45dd68e588..f9ba336ba1 100644 --- a/apps/docs/document-api/reference/tables/set-alt-text.mdx +++ b/apps/docs/document-api/reference/tables/set-alt-text.mdx @@ -50,7 +50,7 @@ _No fields._ ## Output fields -### Variant 1 (table.kind="block") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/tables/set-border.mdx b/apps/docs/document-api/reference/tables/set-border.mdx index 92f97638c8..495d108249 100644 --- a/apps/docs/document-api/reference/tables/set-border.mdx +++ b/apps/docs/document-api/reference/tables/set-border.mdx @@ -53,7 +53,7 @@ _No fields._ ## Output fields -### Variant 1 (table.kind="block") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/tables/set-cell-padding.mdx b/apps/docs/document-api/reference/tables/set-cell-padding.mdx index 83e79d23cd..a12a164336 100644 --- a/apps/docs/document-api/reference/tables/set-cell-padding.mdx +++ b/apps/docs/document-api/reference/tables/set-cell-padding.mdx @@ -53,7 +53,7 @@ _No fields._ ## Output fields -### Variant 1 (table.kind="block") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/tables/set-cell-properties.mdx b/apps/docs/document-api/reference/tables/set-cell-properties.mdx index c474ce86d3..cc98204b3e 100644 --- a/apps/docs/document-api/reference/tables/set-cell-properties.mdx +++ b/apps/docs/document-api/reference/tables/set-cell-properties.mdx @@ -50,7 +50,7 @@ _No fields._ ## Output fields -### Variant 1 (table.kind="block") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/tables/set-cell-spacing.mdx b/apps/docs/document-api/reference/tables/set-cell-spacing.mdx index 601430da38..1fc3bd30ca 100644 --- a/apps/docs/document-api/reference/tables/set-cell-spacing.mdx +++ b/apps/docs/document-api/reference/tables/set-cell-spacing.mdx @@ -50,7 +50,7 @@ _No fields._ ## Output fields -### Variant 1 (table.kind="block") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/tables/set-column-width.mdx b/apps/docs/document-api/reference/tables/set-column-width.mdx index 2fe76b59ef..17af31c505 100644 --- a/apps/docs/document-api/reference/tables/set-column-width.mdx +++ b/apps/docs/document-api/reference/tables/set-column-width.mdx @@ -51,7 +51,7 @@ _No fields._ ## Output fields -### Variant 1 (table.kind="block") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/tables/set-layout.mdx b/apps/docs/document-api/reference/tables/set-layout.mdx index a6b95ef9c9..5ec464c5ea 100644 --- a/apps/docs/document-api/reference/tables/set-layout.mdx +++ b/apps/docs/document-api/reference/tables/set-layout.mdx @@ -50,7 +50,7 @@ _No fields._ ## Output fields -### Variant 1 (table.kind="block") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/tables/set-row-height.mdx b/apps/docs/document-api/reference/tables/set-row-height.mdx index 01b35add81..8bbe9e537c 100644 --- a/apps/docs/document-api/reference/tables/set-row-height.mdx +++ b/apps/docs/document-api/reference/tables/set-row-height.mdx @@ -64,7 +64,7 @@ _No fields._ ## Output fields -### Variant 1 (table.kind="block") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/tables/set-row-options.mdx b/apps/docs/document-api/reference/tables/set-row-options.mdx index bf08661829..a41a7084c4 100644 --- a/apps/docs/document-api/reference/tables/set-row-options.mdx +++ b/apps/docs/document-api/reference/tables/set-row-options.mdx @@ -62,7 +62,7 @@ _No fields._ ## Output fields -### Variant 1 (table.kind="block") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/tables/set-shading.mdx b/apps/docs/document-api/reference/tables/set-shading.mdx index 5947a39337..56870e039b 100644 --- a/apps/docs/document-api/reference/tables/set-shading.mdx +++ b/apps/docs/document-api/reference/tables/set-shading.mdx @@ -50,7 +50,7 @@ _No fields._ ## Output fields -### Variant 1 (table.kind="block") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/tables/set-style-option.mdx b/apps/docs/document-api/reference/tables/set-style-option.mdx index 2ef87b0e5b..abcaa196eb 100644 --- a/apps/docs/document-api/reference/tables/set-style-option.mdx +++ b/apps/docs/document-api/reference/tables/set-style-option.mdx @@ -51,7 +51,7 @@ _No fields._ ## Output fields -### Variant 1 (table.kind="block") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/tables/set-style.mdx b/apps/docs/document-api/reference/tables/set-style.mdx index f68d776960..dfb83c1fb7 100644 --- a/apps/docs/document-api/reference/tables/set-style.mdx +++ b/apps/docs/document-api/reference/tables/set-style.mdx @@ -50,7 +50,7 @@ _No fields._ ## Output fields -### Variant 1 (table.kind="block") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/tables/set-table-padding.mdx b/apps/docs/document-api/reference/tables/set-table-padding.mdx index 64eb6feb20..b5f0e3ce3a 100644 --- a/apps/docs/document-api/reference/tables/set-table-padding.mdx +++ b/apps/docs/document-api/reference/tables/set-table-padding.mdx @@ -53,7 +53,7 @@ _No fields._ ## Output fields -### Variant 1 (table.kind="block") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/tables/sort.mdx b/apps/docs/document-api/reference/tables/sort.mdx index 825e5cb454..b44c57e435 100644 --- a/apps/docs/document-api/reference/tables/sort.mdx +++ b/apps/docs/document-api/reference/tables/sort.mdx @@ -56,7 +56,7 @@ _No fields._ ## Output fields -### Variant 1 (table.kind="block") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/tables/split-cell.mdx b/apps/docs/document-api/reference/tables/split-cell.mdx index 99cdc07628..8a94d4ee7a 100644 --- a/apps/docs/document-api/reference/tables/split-cell.mdx +++ b/apps/docs/document-api/reference/tables/split-cell.mdx @@ -51,7 +51,7 @@ _No fields._ ## Output fields -### Variant 1 (table.kind="block") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/tables/split.mdx b/apps/docs/document-api/reference/tables/split.mdx index 4abec33ecb..d5a4f527dc 100644 --- a/apps/docs/document-api/reference/tables/split.mdx +++ b/apps/docs/document-api/reference/tables/split.mdx @@ -50,7 +50,7 @@ _No fields._ ## Output fields -### Variant 1 (table.kind="block") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/tables/unmerge-cells.mdx b/apps/docs/document-api/reference/tables/unmerge-cells.mdx index b6520b260d..d451f388ea 100644 --- a/apps/docs/document-api/reference/tables/unmerge-cells.mdx +++ b/apps/docs/document-api/reference/tables/unmerge-cells.mdx @@ -49,7 +49,7 @@ _No fields._ ## Output fields -### Variant 1 (table.kind="block") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/toc/configure.mdx b/apps/docs/document-api/reference/toc/configure.mdx index 1a2a015454..a21a7da384 100644 --- a/apps/docs/document-api/reference/toc/configure.mdx +++ b/apps/docs/document-api/reference/toc/configure.mdx @@ -72,7 +72,7 @@ Returns a TocMutationResult with the updated TOC address on success, or a failur ## Output fields -### Variant 1 (toc.kind="block") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/toc/edit-entry.mdx b/apps/docs/document-api/reference/toc/edit-entry.mdx index a970d7c62d..2ab1ecd624 100644 --- a/apps/docs/document-api/reference/toc/edit-entry.mdx +++ b/apps/docs/document-api/reference/toc/edit-entry.mdx @@ -56,7 +56,7 @@ Returns a TocEntryMutationResult with the updated entry address on success, or N ## Output fields -### Variant 1 (entry.kind="inline") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/toc/mark-entry.mdx b/apps/docs/document-api/reference/toc/mark-entry.mdx index 1ee1d3bc05..a2f73141ab 100644 --- a/apps/docs/document-api/reference/toc/mark-entry.mdx +++ b/apps/docs/document-api/reference/toc/mark-entry.mdx @@ -59,7 +59,7 @@ Returns a TocEntryMutationResult with the created entry address on success. ## Output fields -### Variant 1 (entry.kind="inline") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/toc/remove.mdx b/apps/docs/document-api/reference/toc/remove.mdx index 2f26bfa4c4..ca5ca3a882 100644 --- a/apps/docs/document-api/reference/toc/remove.mdx +++ b/apps/docs/document-api/reference/toc/remove.mdx @@ -47,7 +47,7 @@ Returns a TocMutationResult with the removed TOC address on success, or a failur ## Output fields -### Variant 1 (toc.kind="block") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/toc/unmark-entry.mdx b/apps/docs/document-api/reference/toc/unmark-entry.mdx index db95cfcd5c..6878bd71a5 100644 --- a/apps/docs/document-api/reference/toc/unmark-entry.mdx +++ b/apps/docs/document-api/reference/toc/unmark-entry.mdx @@ -47,7 +47,7 @@ Returns a TocEntryMutationResult with the removed entry address on success. ## Output fields -### Variant 1 (entry.kind="inline") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/apps/docs/document-api/reference/toc/update.mdx b/apps/docs/document-api/reference/toc/update.mdx index b538948e69..dbfe5a25e7 100644 --- a/apps/docs/document-api/reference/toc/update.mdx +++ b/apps/docs/document-api/reference/toc/update.mdx @@ -49,7 +49,7 @@ Returns a TocMutationResult with the TOC address on success, or a failure code i ## Output fields -### Variant 1 (toc.kind="block") +### Variant 1 (success=true) | Field | Type | Required | Description | | --- | --- | --- | --- | diff --git a/packages/document-api/scripts/lib/reference-docs-artifacts.ts b/packages/document-api/scripts/lib/reference-docs-artifacts.ts index 54b79e8480..02ed12894d 100644 --- a/packages/document-api/scripts/lib/reference-docs-artifacts.ts +++ b/packages/document-api/scripts/lib/reference-docs-artifacts.ts @@ -319,6 +319,38 @@ function collectConstDiscriminators( return discriminators; } +function hasTopLevelUnion(schema: JsonSchema): boolean { + return ( + (Array.isArray(schema.oneOf) && schema.oneOf.length > 0) || (Array.isArray(schema.anyOf) && schema.anyOf.length > 0) + ); +} + +function preferredDiscriminator( + discriminators: Array<{ path: string; value: unknown }>, +): { path: string; value: unknown } | undefined { + if (discriminators.length === 0) return undefined; + + const priorities = [/^success$/u, /(^|\.)(type|kind|mode|channel)$/u]; + for (const pattern of priorities) { + const match = discriminators.find((entry) => pattern.test(entry.path)); + if (match) return match; + } + + return discriminators[0]; +} + +function combineVariantTitles(parentTitle: string, childTitle?: string): string { + if (!childTitle) return parentTitle; + + const parentMatch = /^Variant (\d+)(.*)$/u.exec(parentTitle); + const childMatch = /^Variant (\d+)(.*)$/u.exec(childTitle); + if (parentMatch && childMatch) { + return `Variant ${parentMatch[1]}.${childMatch[1]}${childMatch[2]}`; + } + + return `${parentTitle} / ${childTitle}`; +} + /** * If `schema` contains an `allOf` array, merge all members' properties and * required fields into a single flat object schema. Recursively resolves @@ -412,18 +444,24 @@ function buildFieldSections(schema: JsonSchema, $defs: Defs): FieldSection[] { const variants = flat[keyword]; if (!Array.isArray(variants) || variants.length === 0) continue; - return variants.map((variant, index) => { - const variantSchema = resolveRef(variant as JsonSchema, $defs).resolved; + return variants.flatMap((variant, index) => { + const variantSchema = flattenAllOf(resolveRef(variant as JsonSchema, $defs).resolved, $defs); const discriminators = collectConstDiscriminators(variantSchema, $defs); - const preferred = - discriminators.find((entry) => /(^|\.)(type|kind|mode|channel)$/u.test(entry.path)) ?? discriminators[0]; + const preferred = preferredDiscriminator(discriminators); const label = preferred ? `Variant ${index + 1} (${preferred.path}=${JSON.stringify(preferred.value)})` : `Variant ${index + 1}`; + const rows = buildFieldRows(variantSchema, $defs); + if (rows.length === 0 && hasTopLevelUnion(variantSchema)) { + return buildFieldSections(variantSchema, $defs).map((section) => ({ + title: combineVariantTitles(label, section.title), + rows: section.rows, + })); + } return { title: label, - rows: buildFieldRows(variantSchema, $defs), + rows, }; }); } @@ -640,6 +678,123 @@ function generateExample(schema: JsonSchema, $defs: Defs, fieldName?: string, de return {}; } +function isObjectRecord(value: unknown): value is Record { + return typeof value === 'object' && value !== null && !Array.isArray(value); +} + +function buildCapabilitiesOutputExample(snapshot: ReturnType): unknown { + const operation = snapshot.operations.find((entry) => entry.operationId === 'capabilities.get'); + if (!operation) return {}; + + const generic = generateExample(operation.schemas.output, snapshot.$defs); + if (!isObjectRecord(generic)) return generic; + + return { + ...generic, + global: { + trackChanges: { enabled: true }, + comments: { enabled: true }, + lists: { enabled: true }, + dryRun: { enabled: true }, + history: { enabled: true }, + }, + operations: Object.fromEntries( + snapshot.operations.map((entry) => [ + entry.operationId, + { + available: true, + tracked: entry.metadata.supportsTrackedMode, + dryRun: entry.metadata.supportsDryRun, + }, + ]), + ), + }; +} + +function getOperationExamples( + operation: ContractOperationSnapshot, + snapshot: ReturnType, +): { input: unknown; output: unknown } { + const inputOverrides: Partial> = { + insert: { + target: { + kind: 'block', + nodeId: 'node-def456', + nodeType: 'paragraph', + }, + content: { + type: 'paragraph', + content: [{ type: 'text', text: 'example' }], + }, + placement: 'after', + }, + replace: { + target: { + kind: 'selection', + start: { + kind: 'text', + blockId: 'block-abc123', + offset: 0, + }, + end: { + kind: 'text', + blockId: 'block-abc123', + offset: 12, + }, + }, + text: 'Hello, world.', + }, + }; + + const outputOverrides: Partial> = { + 'capabilities.get': buildCapabilitiesOutputExample(snapshot), + insert: { + success: true, + evaluatedRevision: { + before: 'rev-001', + after: 'rev-002', + }, + resolution: { + target: { + kind: 'block', + nodeId: 'node-def456', + nodeType: 'paragraph', + }, + range: { + from: 42, + to: 42, + }, + }, + }, + replace: { + success: true, + evaluatedRevision: { + before: 'rev-001', + after: 'rev-002', + }, + resolution: { + target: { + kind: 'text', + blockId: 'block-abc123', + range: { + start: 0, + end: 12, + }, + }, + range: { + from: 0, + to: 12, + }, + }, + }, + }; + + return { + input: inputOverrides[operation.operationId] ?? generateExample(operation.schemas.input, snapshot.$defs), + output: outputOverrides[operation.operationId] ?? generateExample(operation.schemas.output, snapshot.$defs), + }; +} + // --------------------------------------------------------------------------- // Collapsible raw schema rendering // --------------------------------------------------------------------------- @@ -689,7 +844,11 @@ function buildOperationGroups(operations: ContractOperationSnapshot[]): Operatio }); } -function renderOperationPage(operation: ContractOperationSnapshot, $defs: Defs): string { +function renderOperationPage( + operation: ContractOperationSnapshot, + snapshot: ReturnType, +): string { + const $defs = snapshot.$defs; const title = operation.operationId; const metadata = operation.metadata; const description = OPERATION_DESCRIPTION_MAP[operation.operationId]; @@ -700,8 +859,7 @@ function renderOperationPage(operation: ContractOperationSnapshot, $defs: Defs): const inputFields = renderFieldSections(operation.schemas.input, $defs); const outputFields = renderFieldSections(operation.schemas.output, $defs); - const inputExample = generateExample(operation.schemas.input, $defs); - const outputExample = generateExample(operation.schemas.output, $defs); + const { input: inputExample, output: outputExample } = getOperationExamples(operation, snapshot); const stepOpsSection = renderStepOpsSection(operation); const expectedResultSection = `${escapedExpectedResult}${stepOpsSection ? `\n\n${stepOpsSection}` : ''}`; @@ -977,7 +1135,7 @@ export function buildReferenceDocsArtifacts(): GeneratedFile[] { const operationFiles = snapshot.operations.map((operation) => ({ path: toOperationDocPath(operation.operationId), - content: renderOperationPage(operation, snapshot.$defs), + content: renderOperationPage(operation, snapshot), })); const groupFiles = groups.map((group) => ({ diff --git a/packages/document-api/src/README.md b/packages/document-api/src/README.md index 4310ba89b9..cd4d20f803 100644 --- a/packages/document-api/src/README.md +++ b/packages/document-api/src/README.md @@ -43,8 +43,8 @@ lives in adapter layers that map engine behavior into discovery envelopes and ot - `find` always returns `SDFindResult` with `items: SDNodeResult[]`. - Each item has `{ node, address }`, where `address` is a `NodeAddress`. -- For precise text spans/runs (for direct mutation targeting), use `query.match`, which returns `blocks[].range` and run-level metadata. -- `insert` supports canonical `TextAddress` targeting or default insertion point when target is omitted. +- For precise mutation targeting, use `query.match`, which returns a canonical `SelectionTarget`, block addresses, and block/range metadata. +- `insert` accepts either legacy text input with an optional `TextAddress` target or structural content with an optional `BlockNodeAddress` target. Omitting `target` inserts at the end of the document. - Structural creation is exposed under `create.*` (for example `create.paragraph`), separate from text mutations. ## Adapter Error Convention @@ -98,14 +98,10 @@ const match = editor.doc.query.match({ require: 'first', }); -const firstBlock = match.items?.[0]?.blocks?.[0]; -if (firstBlock) { +const target = match.items?.[0]?.target; +if (target) { editor.doc.replace({ - target: { - kind: 'text', - blockId: firstBlock.blockId, - range: { start: firstBlock.range.start, end: firstBlock.range.end }, - }, + target, text: 'bar', }); } @@ -121,7 +117,7 @@ const receipt = editor.doc.insert( { changeMode: 'tracked' }, ); // receipt.resolution.target contains the resolved insertion point -// receipt.inserted contains TrackedChangeAddress entries for the new change +// receipt.success tells you whether the tracked insert applied ``` ### Workflow: Comment Thread Lifecycle @@ -245,33 +241,33 @@ Return document summary metadata (block count, word count, character count). ### `insert` -Insert content at a target location. When `target` is provided, inserts at that `TextAddress`. When omitted, inserts at the end of the document. +Insert content into the document. Legacy string input inserts at an optional `TextAddress`. Structural content inserts relative to an optional `BlockNodeAddress` using `placement`. When `target` is omitted, content appends at the end of the document. Supports dry-run and tracked mode. -- **Input**: `InsertInput` (`{ target?, text }`) +- **Input**: `InsertInput` (`{ value, type?, target?: TextAddress } | { content, target?: BlockNodeAddress, placement?, nestingPolicy? }`) - **Options**: `MutationOptions` (`{ changeMode?, dryRun? }`) -- **Output**: `TextMutationReceipt` +- **Output**: `SDMutationReceipt` - **Mutates**: Yes - **Idempotency**: non-idempotent -- **Failure codes**: `INVALID_TARGET`, `NO_OP` +- **Failure codes**: see the generated reference docs for the full legacy vs. structural failure surface ### `replace` -Replace text at a `TextAddress` target with new content. The target range must resolve to a valid span. Supports dry-run and tracked mode. +Replace content at a contiguous selection. Text replacement accepts `SelectionTarget` or `ref`. Structural replacement accepts `BlockNodeAddress`, `SelectionTarget`, or `ref` with `content`. Supports dry-run and tracked mode. -- **Input**: `ReplaceInput` (`{ target, text }`) +- **Input**: `ReplaceInput` (`{ target?: SelectionTarget, ref?: string, text } | { target?: BlockNodeAddress | SelectionTarget, ref?: string, content, nestingPolicy? }`) - **Options**: `MutationOptions` (`{ changeMode?, dryRun? }`) -- **Output**: `TextMutationReceipt` +- **Output**: `SDMutationReceipt` - **Mutates**: Yes - **Idempotency**: conditional -- **Failure codes**: `INVALID_TARGET`, `NO_OP` +- **Failure codes**: see the generated reference docs for the full text vs. structural failure surface ### `delete` -Delete the text span covered by a `TextAddress` target. Supports dry-run and tracked mode. +Delete content at a contiguous selection. Accepts either an explicit `SelectionTarget` or a mutation-ready `ref`. Supports dry-run and tracked mode. -- **Input**: `DeleteInput` (`{ target }`) +- **Input**: `DeleteInput` (`{ target?: SelectionTarget, ref?: string, behavior?: 'selection' | 'exact' }`) - **Options**: `MutationOptions` (`{ changeMode?, dryRun? }`) - **Output**: `TextMutationReceipt` - **Mutates**: Yes @@ -328,9 +324,9 @@ Insert a new heading node at a specified location with a given level (1-6). Retu ### `format.apply` -Apply explicit inline style changes (bold, italic, underline, strike) to a `TextAddress` range using directive semantics (`'on'`, `'off'`, `'clear'`). Supports dry-run and tracked mode. Availability depends on the corresponding marks being registered in the editor schema. +Apply explicit inline style changes (bold, italic, underline, strike) to a contiguous selection using directive semantics (`'on'`, `'off'`, `'clear'`). Accepts a `SelectionTarget` or `ref`. Supports dry-run and tracked mode. Availability depends on the corresponding marks being registered in the editor schema. -- **Input**: `StyleApplyInput` (`{ target, inline: { bold?, italic?, underline?, strike? } }`) +- **Input**: `StyleApplyInput` (`{ target?: SelectionTarget, ref?: string, inline: { bold?, italic?, underline?, strike? } }`) - **Options**: `MutationOptions` (`{ changeMode?, dryRun? }`) - **Output**: `TextMutationReceipt` - **Mutates**: Yes diff --git a/packages/document-api/src/contract/contract.test.ts b/packages/document-api/src/contract/contract.test.ts index d209f6021c..478605398c 100644 --- a/packages/document-api/src/contract/contract.test.ts +++ b/packages/document-api/src/contract/contract.test.ts @@ -75,22 +75,51 @@ describe('document-api contract catalog', () => { } }); - it('uses simplified target-based insert input schema without locator constraints', () => { + it('declares insert input as a legacy-text or structural-content union', () => { const schemas = buildInternalContractSchemas(); const insertInputSchema = schemas.operations.insert.input as { - type?: string; - properties?: Record; - required?: string[]; - allOf?: unknown; - additionalProperties?: boolean; + oneOf?: Array<{ + type?: string; + properties?: Record; + required?: string[]; + additionalProperties?: boolean; + }>; }; - // Simplified schema: target (optional) + value (required) + type (optional enum), no allOf constraints - expect(insertInputSchema.type).toBe('object'); - expect(Object.keys(insertInputSchema.properties!).sort()).toEqual(['target', 'type', 'value']); - expect(insertInputSchema.required).toEqual(['value']); - expect(insertInputSchema.allOf).toBeUndefined(); - expect(insertInputSchema.additionalProperties).toBe(false); + expect(Array.isArray(insertInputSchema.oneOf)).toBe(true); + expect(insertInputSchema.oneOf).toHaveLength(2); + + const [legacyVariant, structuralVariant] = insertInputSchema.oneOf!; + + expect(legacyVariant.type).toBe('object'); + expect(Object.keys(legacyVariant.properties!).sort()).toEqual(['target', 'type', 'value']); + expect(legacyVariant.required).toEqual(['value']); + expect(legacyVariant.additionalProperties).toBe(false); + expect((legacyVariant.properties!.target as { $ref?: string }).$ref).toBe('#/$defs/TextAddress'); + + expect(structuralVariant.type).toBe('object'); + expect(Object.keys(structuralVariant.properties!).sort()).toEqual([ + 'content', + 'nestingPolicy', + 'placement', + 'target', + ]); + expect(structuralVariant.required).toEqual(['content']); + expect(structuralVariant.additionalProperties).toBe(false); + expect((structuralVariant.properties!.target as { $ref?: string }).$ref).toBe('#/$defs/BlockNodeAddress'); + expect((structuralVariant.properties!.placement as { enum?: string[] }).enum).toEqual([ + 'before', + 'after', + 'insideStart', + 'insideEnd', + ]); + expect( + ( + structuralVariant.properties!.nestingPolicy as { + properties?: { tables?: { enum?: string[] } }; + } + ).properties?.tables?.enum, + ).toEqual(['forbid', 'allow']); }); it('declares UNSUPPORTED_ENVIRONMENT for insert metadata and generated failure schema', () => { diff --git a/packages/document-api/src/contract/operation-definitions.ts b/packages/document-api/src/contract/operation-definitions.ts index 899a55378e..c2d5430a70 100644 --- a/packages/document-api/src/contract/operation-definitions.ts +++ b/packages/document-api/src/contract/operation-definitions.ts @@ -383,7 +383,7 @@ export const OPERATION_DEFINITIONS = { 'Legacy mode supports text (default), markdown, and html content types via the `type` field. ' + 'Structural mode uses `placement` (before/after/insideStart/insideEnd) to position relative to the target block.', expectedResult: - 'Returns a TextMutationReceipt with applied status; receipt reports NO_OP if the insertion point is invalid or content is empty.', + 'Returns an SDMutationReceipt with applied status; resolution reports a TextAddress for legacy text insertion or a BlockNodeAddress for structural insertion. Receipt reports NO_OP if the insertion point is invalid or content is empty.', requiresDocumentContext: true, metadata: mutationOperation({ idempotency: 'non-idempotent', diff --git a/packages/document-api/src/contract/schemas.ts b/packages/document-api/src/contract/schemas.ts index 6f5ffc6e55..977673edb1 100644 --- a/packages/document-api/src/contract/schemas.ts +++ b/packages/document-api/src/contract/schemas.ts @@ -1395,14 +1395,33 @@ const capabilitiesOutputSchema = objectSchema( const strictEmptyObjectSchema = objectSchema({}); -const insertInputSchema = objectSchema( - { - target: textAddressSchema, - value: { type: 'string' }, - type: { type: 'string', enum: ['text', 'markdown', 'html'] }, - }, - ['value'], -); +const placementSchema: JsonSchema = { enum: ['before', 'after', 'insideStart', 'insideEnd'] }; + +const nestingPolicySchema = objectSchema({ + tables: { enum: ['forbid', 'allow'] }, +}); + +const insertInputSchema: JsonSchema = { + oneOf: [ + objectSchema( + { + target: textAddressSchema, + value: { type: 'string' }, + type: { type: 'string', enum: ['text', 'markdown', 'html'] }, + }, + ['value'], + ), + objectSchema( + { + target: blockNodeAddressSchema, + content: { type: 'object' }, + placement: placementSchema, + nestingPolicy: nestingPolicySchema, + }, + ['content'], + ), + ], +}; // --------------------------------------------------------------------------- // Table operation shared schemas @@ -2578,7 +2597,7 @@ const operationSchemas: Record = { { target: { oneOf: [blockNodeAddressSchema, selectionTargetSchema] }, content: { type: 'object' }, - nestingPolicy: { type: 'object' }, + nestingPolicy: nestingPolicySchema, }, ['target', 'content'], ), @@ -2586,7 +2605,7 @@ const operationSchemas: Record = { { ref: { type: 'string' }, content: { type: 'object' }, - nestingPolicy: { type: 'object' }, + nestingPolicy: nestingPolicySchema, }, ['ref', 'content'], ), diff --git a/packages/document-api/src/overview-examples.test.ts b/packages/document-api/src/overview-examples.test.ts index ab6d6e1352..5f818273a9 100644 --- a/packages/document-api/src/overview-examples.test.ts +++ b/packages/document-api/src/overview-examples.test.ts @@ -41,9 +41,35 @@ function makeFindAdapter() { items: [ { id: 'p1', - handle: { ref: 'p1', refStability: 'ephemeral' as const, targetKind: 'node' as const }, + handle: { ref: 'p1', refStability: 'ephemeral' as const, targetKind: 'text' as const }, + matchKind: 'text' as const, address: { kind: 'block' as const, nodeType: 'paragraph' as const, nodeId: 'p1' }, - context: { textRanges: [SELECTION_TARGET] }, + target: SELECTION_TARGET, + snippet: 'foo', + highlightRange: { start: 0, end: 3 }, + blocks: [ + { + blockId: 'p1', + nodeType: 'paragraph', + range: { start: 0, end: 3 }, + text: 'foo', + ref: 'ref:block-1', + runs: [ + { + range: { start: 0, end: 3 }, + text: 'foo', + styles: { + bold: false, + italic: false, + underline: false, + strike: false, + }, + ref: 'ref:run-1', + }, + ], + }, + ], + context: { target: SELECTION_TARGET, textRanges: [SELECTION_TARGET] }, }, ], page: { limit: 1, offset: 0, returned: 1 }, @@ -355,6 +381,7 @@ function makeApi() { nodeType: 'paragraph' as const, nodeId: 'p1', }, + target: SELECTION_TARGET, snippet: 'foo', highlightRange: { start: 0, end: 3 }, blocks: [ @@ -630,8 +657,12 @@ describe('src/README.md workflow examples', () => { it('find then replace', () => { const doc = makeApi(); - const result = doc.find({ type: 'text', pattern: 'foo' }); - const target = result.items[0]?.context?.textRanges?.[0]; + const match = doc.query.match({ + select: { type: 'text', pattern: 'foo' }, + require: 'first', + }); + + const target = match.items?.[0]?.target; if (target) { doc.replace({ target, text: 'bar' }); } @@ -647,6 +678,7 @@ describe('src/README.md workflow examples', () => { const receipt = doc.insert({ value: 'new content' }, { changeMode: 'tracked' }); // receipt.resolution.target contains the resolved insertion point (TextAddress) + // receipt.success tells you whether the tracked insert applied expect(receipt.resolution).toBeDefined(); expect(receipt.resolution!.target).toBeDefined(); From 5b7c0d90d9ceefb212b91a70eae40a946a491511 Mon Sep 17 00:00:00 2001 From: Nick Bernal Date: Mon, 16 Mar 2026 15:31:39 -0700 Subject: [PATCH 5/5] fix: stale block address resolution and structural fragment schemas --- .../src/contract/contract.test.ts | 29 +++++ packages/document-api/src/contract/schemas.ts | 10 +- .../src/document-api-adapters/find-adapter.ts | 2 +- .../get-node-adapter.test.ts | 46 ++++++++ .../document-api-adapters/get-node-adapter.ts | 26 +++-- .../helpers/adapter-utils.test.ts | 100 +++++++++++++++++- .../helpers/adapter-utils.ts | 15 ++- 7 files changed, 216 insertions(+), 12 deletions(-) diff --git a/packages/document-api/src/contract/contract.test.ts b/packages/document-api/src/contract/contract.test.ts index 478605398c..f2388f8a06 100644 --- a/packages/document-api/src/contract/contract.test.ts +++ b/packages/document-api/src/contract/contract.test.ts @@ -122,6 +122,35 @@ describe('document-api contract catalog', () => { ).toEqual(['forbid', 'allow']); }); + it('accepts both object and array SDFragment in structural insert content schema', () => { + const schemas = buildInternalContractSchemas(); + const insertInput = schemas.operations.insert.input as { oneOf?: Array<{ properties?: Record }> }; + const structuralVariant = insertInput.oneOf![1]; + const contentSchema = structuralVariant.properties!.content as { oneOf?: Array<{ type?: string }> }; + + expect(Array.isArray(contentSchema.oneOf)).toBe(true); + expect(contentSchema.oneOf).toHaveLength(2); + expect(contentSchema.oneOf![0].type).toBe('object'); + expect(contentSchema.oneOf![1].type).toBe('array'); + }); + + it('accepts both object and array SDFragment in structural replace content schema', () => { + const schemas = buildInternalContractSchemas(); + const replaceInput = schemas.operations.replace.input as { + oneOf?: Array<{ oneOf?: Array<{ properties?: Record }> }>; + }; + // The structural branch is the second oneOf element + const structuralBranch = replaceInput.oneOf![1] as { oneOf?: Array<{ properties?: Record }> }; + + for (const variant of structuralBranch.oneOf!) { + const contentSchema = variant.properties!.content as { oneOf?: Array<{ type?: string }> }; + expect(Array.isArray(contentSchema.oneOf)).toBe(true); + expect(contentSchema.oneOf).toHaveLength(2); + expect(contentSchema.oneOf![0].type).toBe('object'); + expect(contentSchema.oneOf![1].type).toBe('array'); + } + }); + it('declares UNSUPPORTED_ENVIRONMENT for insert metadata and generated failure schema', () => { const schemas = buildInternalContractSchemas(); const insertFailureSchema = schemas.operations.insert.failure as { diff --git a/packages/document-api/src/contract/schemas.ts b/packages/document-api/src/contract/schemas.ts index 977673edb1..f0d7b90f37 100644 --- a/packages/document-api/src/contract/schemas.ts +++ b/packages/document-api/src/contract/schemas.ts @@ -1395,6 +1395,10 @@ const capabilitiesOutputSchema = objectSchema( const strictEmptyObjectSchema = objectSchema({}); +const sdFragmentSchema: JsonSchema = { + oneOf: [{ type: 'object' }, { type: 'array', items: { type: 'object' } }], +}; + const placementSchema: JsonSchema = { enum: ['before', 'after', 'insideStart', 'insideEnd'] }; const nestingPolicySchema = objectSchema({ @@ -1414,7 +1418,7 @@ const insertInputSchema: JsonSchema = { objectSchema( { target: blockNodeAddressSchema, - content: { type: 'object' }, + content: sdFragmentSchema, placement: placementSchema, nestingPolicy: nestingPolicySchema, }, @@ -2596,7 +2600,7 @@ const operationSchemas: Record = { objectSchema( { target: { oneOf: [blockNodeAddressSchema, selectionTargetSchema] }, - content: { type: 'object' }, + content: sdFragmentSchema, nestingPolicy: nestingPolicySchema, }, ['target', 'content'], @@ -2604,7 +2608,7 @@ const operationSchemas: Record = { objectSchema( { ref: { type: 'string' }, - content: { type: 'object' }, + content: sdFragmentSchema, nestingPolicy: nestingPolicySchema, }, ['ref', 'content'], diff --git a/packages/super-editor/src/document-api-adapters/find-adapter.ts b/packages/super-editor/src/document-api-adapters/find-adapter.ts index b14750ea0b..ab60e02912 100644 --- a/packages/super-editor/src/document-api-adapters/find-adapter.ts +++ b/packages/super-editor/src/document-api-adapters/find-adapter.ts @@ -149,7 +149,7 @@ function translateToInternalQuery(input: SDFindInput): Query { // Reject legacy selector vocabulary that would otherwise be silently ignored. if (select.type === 'node') { - const raw = select as Record; + const raw = select as unknown as Record; if ('nodeKind' in raw && raw.nodeKind != null) { throw new DocumentApiAdapterError( 'INVALID_INPUT', diff --git a/packages/super-editor/src/document-api-adapters/get-node-adapter.test.ts b/packages/super-editor/src/document-api-adapters/get-node-adapter.test.ts index f5ff1e16b2..d708779ce7 100644 --- a/packages/super-editor/src/document-api-adapters/get-node-adapter.test.ts +++ b/packages/super-editor/src/document-api-adapters/get-node-adapter.test.ts @@ -188,6 +188,52 @@ describe('getNodeAdapter — block', () => { }), ).toThrow('Multiple nodes share paragraph id "dup".'); }); + + it('falls back to nodeId when nodeType is stale after paragraph → heading restyle', () => { + // The block is now a heading (via styleId), but the saved address still says 'paragraph'. + const paragraph = createNode('paragraph', [], { + attrs: { sdBlockId: 'p-restyle', paragraphProperties: { styleId: 'Heading1' } }, + isBlock: true, + inlineContent: true, + }); + const doc = createNode('doc', [paragraph], { isBlock: false }); + const editor = makeEditor(doc); + + // Address saved before the restyle had nodeType: 'paragraph' + const result = getNodeAdapter(editor, { + kind: 'block', + nodeType: 'paragraph', + nodeId: 'p-restyle', + }); + + expect(result.node.kind).toBe('heading'); + // The returned address should reflect the current (correct) nodeType + expect(result.address).toMatchObject({ kind: 'block', nodeType: 'heading', nodeId: 'p-restyle' }); + }); + + it('falls back to nodeId when nodeType is stale after paragraph → listItem restyle', () => { + const paragraph = createNode('paragraph', [], { + attrs: { sdBlockId: 'p-list', paragraphProperties: { numberingProperties: { numId: 1, ilvl: 0 } } }, + isBlock: true, + inlineContent: true, + }); + const doc = createNode('doc', [paragraph], { isBlock: false }); + const editor = makeEditor(doc); + + // Saved address has nodeType: 'paragraph', but the block is now indexed as 'listItem'. + // The lookup should succeed (not throw) and return the canonical address. + const result = getNodeAdapter(editor, { + kind: 'block', + nodeType: 'paragraph', + nodeId: 'p-list', + }); + + // projectContentNode returns 'paragraph' kind for PM paragraph nodes with + // numbering (unlike headings which check styleId), but the address reflects + // the block index's canonical nodeType. + expect(result.node.kind).toBe('paragraph'); + expect(result.address).toMatchObject({ kind: 'block', nodeType: 'listItem', nodeId: 'p-list' }); + }); }); describe('getNodeByIdAdapter', () => { diff --git a/packages/super-editor/src/document-api-adapters/get-node-adapter.ts b/packages/super-editor/src/document-api-adapters/get-node-adapter.ts index 22c2fd429b..7935c65d9e 100644 --- a/packages/super-editor/src/document-api-adapters/get-node-adapter.ts +++ b/packages/super-editor/src/document-api-adapters/get-node-adapter.ts @@ -1,6 +1,7 @@ import type { Editor } from '../core/Editor.js'; import type { BlockNodeType, GetNodeByIdInput, NodeAddress, SDNodeResult } from '@superdoc/document-api'; import type { BlockCandidate, BlockIndex } from './helpers/node-address-resolver.js'; +import { findBlockByNodeIdOnly } from './helpers/node-address-resolver.js'; import { getBlockIndex, getInlineIndex } from './helpers/index-cache.js'; import { findInlineByAnchor } from './helpers/inline-address-resolver.js'; import { projectContentNode, projectInlineNode, projectMarkBasedInline } from './helpers/sd-projection.js'; @@ -35,23 +36,36 @@ export function getNodeAdapter(editor: Editor, address: NodeAddress): SDNodeResu if (address.kind === 'block') { const matches = findBlocksByTypeAndId(blockIndex, address.nodeType, address.nodeId); - if (matches.length === 0) { + if (matches.length > 1) { throw new DocumentApiAdapterError( 'TARGET_NOT_FOUND', - `Node "${address.nodeType}" not found for id "${address.nodeId}".`, + `Multiple nodes share ${address.nodeType} id "${address.nodeId}".`, ); } - if (matches.length > 1) { + + let candidate = matches[0]; + + // Fallback: nodeId-only lookup handles stale subtypes after paragraph ↔ + // heading / listItem restyling (the PM node and its nodeId stay the same + // but the indexed nodeType changes). + if (!candidate) { + try { + candidate = findBlockByNodeIdOnly(blockIndex, address.nodeId); + } catch { + // AMBIGUOUS_TARGET / TARGET_NOT_FOUND — throw the original error below + } + } + + if (!candidate) { throw new DocumentApiAdapterError( 'TARGET_NOT_FOUND', - `Multiple nodes share ${address.nodeType} id "${address.nodeId}".`, + `Node "${address.nodeType}" not found for id "${address.nodeId}".`, ); } - const candidate = matches[0]!; return { node: projectContentNode(candidate.node), - address: buildBlockAddress(address), + address: { kind: 'block', nodeType: candidate.nodeType, nodeId: candidate.nodeId } as NodeAddress, }; } diff --git a/packages/super-editor/src/document-api-adapters/helpers/adapter-utils.test.ts b/packages/super-editor/src/document-api-adapters/helpers/adapter-utils.test.ts index d334beb23f..e6483b12c9 100644 --- a/packages/super-editor/src/document-api-adapters/helpers/adapter-utils.test.ts +++ b/packages/super-editor/src/document-api-adapters/helpers/adapter-utils.test.ts @@ -1,5 +1,13 @@ import type { UnknownNodeDiagnostic } from '@superdoc/document-api'; -import { addDiagnostic, dedupeDiagnostics, findCandidateByPos, paginate, scopeByRange } from './adapter-utils.js'; +import { + addDiagnostic, + dedupeDiagnostics, + findCandidateByPos, + paginate, + resolveWithinScope, + scopeByRange, +} from './adapter-utils.js'; +import type { BlockIndex } from './node-address-resolver.js'; // --------------------------------------------------------------------------- // paginate @@ -206,3 +214,93 @@ describe('findCandidateByPos', () => { expect(findCandidateByPos(single, 15)).toBeUndefined(); }); }); + +// --------------------------------------------------------------------------- +// resolveWithinScope +// --------------------------------------------------------------------------- + +describe('resolveWithinScope', () => { + function makeBlockIndex(entries: Array<{ nodeType: string; nodeId: string; pos: number; end: number }>): BlockIndex { + const candidates = entries.map((e) => ({ + node: {} as import('prosemirror-model').Node, + pos: e.pos, + end: e.end, + nodeType: e.nodeType as import('@superdoc/document-api').BlockNodeType, + nodeId: e.nodeId, + })); + const byId = new Map(); + const ambiguous = new Set(); + for (const c of candidates) { + const key = `${c.nodeType}:${c.nodeId}`; + if (byId.has(key)) { + ambiguous.add(key); + byId.delete(key); + } else if (!ambiguous.has(key)) { + byId.set(key, c); + } + } + return { candidates, byId, ambiguous }; + } + + it('returns range when within matches exactly', () => { + const index = makeBlockIndex([{ nodeType: 'table', nodeId: 't1', pos: 10, end: 50 }]); + const diagnostics: UnknownNodeDiagnostic[] = []; + const result = resolveWithinScope( + index, + { within: { kind: 'block', nodeType: 'table', nodeId: 't1' } }, + diagnostics, + ); + + expect(result).toEqual({ ok: true, range: { start: 10, end: 50 } }); + expect(diagnostics).toHaveLength(0); + }); + + it('returns ok:true with undefined range when within is absent', () => { + const index = makeBlockIndex([]); + const diagnostics: UnknownNodeDiagnostic[] = []; + const result = resolveWithinScope(index, {}, diagnostics); + + expect(result).toEqual({ ok: true, range: undefined }); + }); + + it('falls back to nodeId when nodeType is stale after restyle (paragraph → heading)', () => { + // Block is now indexed as heading, but the saved address says paragraph + const index = makeBlockIndex([{ nodeType: 'heading', nodeId: 'p1', pos: 0, end: 20 }]); + const diagnostics: UnknownNodeDiagnostic[] = []; + const result = resolveWithinScope( + index, + { within: { kind: 'block', nodeType: 'paragraph', nodeId: 'p1' } }, + diagnostics, + ); + + expect(result).toEqual({ ok: true, range: { start: 0, end: 20 } }); + expect(diagnostics).toHaveLength(0); + }); + + it('falls back to nodeId when nodeType is stale after restyle (paragraph → listItem)', () => { + const index = makeBlockIndex([{ nodeType: 'listItem', nodeId: 'p2', pos: 5, end: 30 }]); + const diagnostics: UnknownNodeDiagnostic[] = []; + const result = resolveWithinScope( + index, + { within: { kind: 'block', nodeType: 'paragraph', nodeId: 'p2' } }, + diagnostics, + ); + + expect(result).toEqual({ ok: true, range: { start: 5, end: 30 } }); + expect(diagnostics).toHaveLength(0); + }); + + it('returns ok:false with diagnostic when neither exact nor fallback match', () => { + const index = makeBlockIndex([{ nodeType: 'table', nodeId: 'other', pos: 0, end: 10 }]); + const diagnostics: UnknownNodeDiagnostic[] = []; + const result = resolveWithinScope( + index, + { within: { kind: 'block', nodeType: 'paragraph', nodeId: 'missing' } }, + diagnostics, + ); + + expect(result).toEqual({ ok: false }); + expect(diagnostics).toHaveLength(1); + expect(diagnostics[0].message).toContain('missing'); + }); +}); diff --git a/packages/super-editor/src/document-api-adapters/helpers/adapter-utils.ts b/packages/super-editor/src/document-api-adapters/helpers/adapter-utils.ts index 5f532f62f7..5ec133f37a 100644 --- a/packages/super-editor/src/document-api-adapters/helpers/adapter-utils.ts +++ b/packages/super-editor/src/document-api-adapters/helpers/adapter-utils.ts @@ -380,7 +380,20 @@ export function resolveWithinScope( ): WithinResult { if (!query.within) return { ok: true, range: undefined }; - const within = findBlockById(index, query.within); + // Try exact nodeType:nodeId match first. + let within = findBlockById(index, query.within); + + // Fallback: nodeId-only lookup handles stale subtypes after paragraph ↔ + // heading / listItem restyling (the PM node and its nodeId stay the same + // but the indexed nodeType changes). + if (!within && query.within.kind === 'block') { + try { + within = findBlockByNodeIdOnly(index, query.within.nodeId); + } catch { + // TARGET_NOT_FOUND / AMBIGUOUS_TARGET — fall through to diagnostic + } + } + if (!within) { addDiagnostic( diagnostics,