Skip to content

Commit b628be9

Browse files
authored
fix(doc-api): stabilize bibliography.configure targets in citations stories (#2507)
* fix(doc-api): stabilize bibliography.configure targets in citations stories * fix(doc-api): stringify numeric sdBlockId in bibliography resolver
1 parent d882431 commit b628be9

6 files changed

Lines changed: 55 additions & 10 deletions

File tree

packages/super-editor/src/document-api-adapters/citations-export.integration.test.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,14 @@ describe('citations export integration', () => {
206206
);
207207

208208
expect(configureResult.success).toBe(true);
209+
if (!configureResult.success) return;
210+
211+
const bibliographyInfo = editor.doc.citations.bibliography.get({
212+
target: configureResult.bibliography,
213+
});
214+
215+
expect(bibliographyInfo.style).toBe('MLA');
216+
expect(bibliographyInfo.address.nodeId).toBe(configureResult.bibliography.nodeId);
209217
expect(findBibliographyNode(editor)?.attrs.style).toBe('MLA');
210218
});
211219
});

packages/super-editor/src/document-api-adapters/helpers/citation-resolver.test.ts

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import {
77
resolvePostMutationBibliographyId,
88
} from './citation-resolver.js';
99

10-
function makeBibliographyDoc(sdBlockId: string | undefined = 'bib-runtime', style = 'APA') {
10+
function makeBibliographyDoc(sdBlockId: string | number | undefined = 'bib-runtime', style = 'APA') {
1111
return {
1212
descendants: (cb: (node: unknown, pos: number) => boolean | void) => {
1313
cb(
@@ -49,6 +49,27 @@ describe('citation-resolver bibliography ids', () => {
4949
expect(resolved.nodeId).toMatch(/^bibliography-auto-[0-9a-f]{8}$/);
5050
});
5151

52+
it('coerces a numeric sdBlockId to string in commandNodeId', () => {
53+
const doc = makeBibliographyDoc(42 as unknown as string);
54+
const [resolved] = findAllBibliographies(doc);
55+
56+
expect(typeof resolved.commandNodeId).toBe('string');
57+
expect(resolved.commandNodeId).toBe('42');
58+
});
59+
60+
it('resolves bibliography target when sdBlockId is numeric', () => {
61+
const doc = makeBibliographyDoc(42 as unknown as string);
62+
const [resolved] = findAllBibliographies(doc);
63+
64+
// Should be findable via the stringified commandNodeId
65+
const found = resolveBibliographyTarget(doc, {
66+
kind: 'block',
67+
nodeType: 'bibliography',
68+
nodeId: '42',
69+
});
70+
expect(found.nodeId).toBe(resolved.nodeId);
71+
});
72+
5273
it('extracts bibliography info with the public address and persisted style', () => {
5374
const doc = makeBibliographyDoc('bib-runtime', 'MLA');
5475
const [resolved] = findAllBibliographies(doc);

packages/super-editor/src/document-api-adapters/helpers/citation-resolver.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,8 @@ export function findAllBibliographies(doc: ProseMirrorNode): ResolvedBibliograph
121121
let occurrenceIndex = 0;
122122
doc.descendants((node, pos) => {
123123
if (node.type.name === 'bibliography') {
124-
const commandNodeId = node.attrs?.sdBlockId as string | undefined;
124+
const rawBlockId = node.attrs?.sdBlockId;
125+
const commandNodeId = rawBlockId != null ? String(rawBlockId) : undefined;
125126
const nodeId = resolvePublicReferenceBlockNodeId(node, occurrenceIndex);
126127
occurrenceIndex += 1;
127128
results.push({ node, pos, nodeId, commandNodeId });
@@ -258,8 +259,8 @@ function resolveParentBlockId(doc: ProseMirrorNode, pos: number): string {
258259
const resolved = doc.resolve(pos);
259260
for (let depth = resolved.depth; depth >= 0; depth--) {
260261
const node = resolved.node(depth);
261-
const blockId = node.attrs?.sdBlockId as string | undefined;
262-
if (blockId) return blockId;
262+
const rawBlockId = node.attrs?.sdBlockId;
263+
if (rawBlockId != null) return String(rawBlockId);
263264
}
264265
return '';
265266
}

packages/super-editor/src/document-api-adapters/plan-engine/citation-wrappers.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ import type {
3737
} from '@superdoc/document-api';
3838
import { buildDiscoveryResult, buildDiscoveryItem, buildResolvedHandle } from '@superdoc/document-api';
3939
import {
40+
findAllBibliographies,
4041
findAllCitations,
4142
resolveCitationTarget,
4243
extractCitationInfo,
@@ -421,7 +422,8 @@ export function bibliographyConfigureWrapper(
421422
rejectTrackedMode('citations.bibliography.configure', options);
422423

423424
const resolved = resolveBibliographyTarget(editor.state.doc, input.target);
424-
const address: BibliographyAddress = { kind: 'block', nodeType: 'bibliography', nodeId: resolved.nodeId };
425+
const stableNodeId = resolved.commandNodeId ?? resolved.nodeId;
426+
const address: BibliographyAddress = { kind: 'block', nodeType: 'bibliography', nodeId: stableNodeId };
425427

426428
if (options?.dryRun) return bibSuccess(address);
427429

@@ -445,7 +447,13 @@ export function bibliographyConfigureWrapper(
445447

446448
syncBibliographyStyleToConverter(editor, input.style);
447449

448-
return bibSuccess(address);
450+
const bibliographies = findAllBibliographies(editor.state.doc);
451+
const postMutationBibliography =
452+
bibliographies.find((bibliography) => bibliography.pos === resolved.pos) ??
453+
bibliographies.find((bibliography) => bibliography.commandNodeId === stableNodeId);
454+
const postMutationId =
455+
postMutationBibliography?.nodeId ?? resolvePostMutationBibliographyId(editor.state.doc, stableNodeId);
456+
return bibSuccess({ kind: 'block', nodeType: 'bibliography', nodeId: postMutationId });
449457
}
450458

451459
export function bibliographyRebuildWrapper(

tests/doc-api-stories/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
"test": "pnpm --silent --prefix ../../packages/sdk run generate && pnpm --silent --prefix ../../packages/superdoc run build:es && pnpm --silent --prefix ../../apps/cli run build && pnpm --silent --prefix ../../packages/sdk/langs/node run build && vitest run --config ./vitest.config.ts"
88
},
99
"dependencies": {
10-
"@superdoc-dev/sdk": "file:../../packages/sdk/langs/node"
10+
"@superdoc-dev/sdk": "workspace:*"
1111
},
1212
"devDependencies": {
1313
"vitest": "catalog:"

tests/doc-api-stories/tests/citations/all-commands.ts

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -486,17 +486,24 @@ describe('document-api story: all citations commands', () => {
486486
throw new Error('citations.bibliography.configure requires a bibliography target fixture.');
487487
}
488488

489-
const configureResult = await callDocOperation<any>('citations.bibliography.configure', {
489+
const beforeInfo = await callDocOperation<any>('citations.bibliography.get', {
490490
sessionId,
491491
target: f.bibliographyTarget,
492+
});
493+
const configureTarget = (beforeInfo?.address as BibliographyAddress | undefined) ?? f.bibliographyTarget;
494+
495+
const configureResult = await callDocOperation<any>('citations.bibliography.configure', {
496+
sessionId,
497+
target: configureTarget,
492498
style: 'APA',
493499
});
500+
const configuredTarget = (configureResult?.bibliography as BibliographyAddress | undefined) ?? configureTarget;
494501

495502
const info = await callDocOperation<any>('citations.bibliography.get', {
496503
sessionId,
497-
target: f.bibliographyTarget,
504+
target: configuredTarget,
498505
});
499-
expect(typeof info?.style).toBe('string');
506+
expect(info?.style).toBe('APA');
500507

501508
return configureResult;
502509
},

0 commit comments

Comments
 (0)