@@ -3095,6 +3095,218 @@ export const SUCCESS_SCENARIOS = {
30953095 } ,
30963096 ...DEFERRED_NEW_NAMESPACE_SUCCESS_SCENARIOS ,
30973097
3098+ // ---------------------------------------------------------------------------
3099+ // Header/footer operations
3100+ // ---------------------------------------------------------------------------
3101+
3102+ 'doc.headerFooters.list' : async ( harness : ConformanceHarness ) : Promise < ScenarioInvocation > => {
3103+ const stateDir = await harness . createStateDir ( 'doc-headerFooters-list-success' ) ;
3104+ const docPath = await harness . copyFixtureDoc ( 'doc-headerFooters-list' ) ;
3105+ return {
3106+ stateDir,
3107+ args : [ ...commandTokens ( 'doc.headerFooters.list' ) , docPath , '--limit' , '10' ] ,
3108+ } ;
3109+ } ,
3110+ 'doc.headerFooters.get' : async ( harness : ConformanceHarness ) : Promise < ScenarioInvocation > => {
3111+ const stateDir = await harness . createStateDir ( 'doc-headerFooters-get-success' ) ;
3112+ const docPath = await harness . copyFixtureDoc ( 'doc-headerFooters-get' ) ;
3113+ const { address } = await resolveFirstSection ( harness , stateDir , docPath , 'doc.headerFooters.get' ) ;
3114+ const slotTarget = {
3115+ kind : 'headerFooterSlot' ,
3116+ section : address ,
3117+ headerFooterKind : 'header' ,
3118+ variant : 'default' ,
3119+ } ;
3120+ return {
3121+ stateDir,
3122+ args : [ ...commandTokens ( 'doc.headerFooters.get' ) , docPath , '--target-json' , JSON . stringify ( slotTarget ) ] ,
3123+ } ;
3124+ } ,
3125+ 'doc.headerFooters.resolve' : async ( harness : ConformanceHarness ) : Promise < ScenarioInvocation > => {
3126+ const stateDir = await harness . createStateDir ( 'doc-headerFooters-resolve-success' ) ;
3127+ const docPath = await harness . copyFixtureDoc ( 'doc-headerFooters-resolve' ) ;
3128+ const { address } = await resolveFirstSection ( harness , stateDir , docPath , 'doc.headerFooters.resolve' ) ;
3129+ const slotTarget = {
3130+ kind : 'headerFooterSlot' ,
3131+ section : address ,
3132+ headerFooterKind : 'header' ,
3133+ variant : 'default' ,
3134+ } ;
3135+ return {
3136+ stateDir,
3137+ args : [ ...commandTokens ( 'doc.headerFooters.resolve' ) , docPath , '--target-json' , JSON . stringify ( slotTarget ) ] ,
3138+ } ;
3139+ } ,
3140+ 'doc.headerFooters.refs.set' : async ( harness : ConformanceHarness ) : Promise < ScenarioInvocation > => {
3141+ const stateDir = await harness . createStateDir ( 'doc-headerFooters-refs-set-success' ) ;
3142+ const docPath = await harness . copyFixtureDoc ( 'doc-headerFooters-refs-set' ) ;
3143+ const { item, address } = await resolveFirstSection ( harness , stateDir , docPath , 'doc.headerFooters.refs.set' ) ;
3144+ const footerRefs = item . footerRefs as Record < string , unknown > | undefined ;
3145+ const refId =
3146+ ( typeof footerRefs ?. default === 'string' ? footerRefs . default : undefined ) ??
3147+ ( typeof footerRefs ?. even === 'string' ? footerRefs . even : undefined ) ;
3148+ if ( ! refId ) {
3149+ throw new Error ( 'No footer relationship id available for doc.headerFooters.refs.set.' ) ;
3150+ }
3151+ const slotTarget = {
3152+ kind : 'headerFooterSlot' ,
3153+ section : address ,
3154+ headerFooterKind : 'footer' ,
3155+ variant : 'first' ,
3156+ } ;
3157+ return {
3158+ stateDir,
3159+ args : [
3160+ ...commandTokens ( 'doc.headerFooters.refs.set' ) ,
3161+ docPath ,
3162+ '--target-json' ,
3163+ JSON . stringify ( slotTarget ) ,
3164+ '--ref-id' ,
3165+ refId ,
3166+ '--out' ,
3167+ harness . createOutputPath ( 'doc-headerFooters-refs-set-output' ) ,
3168+ ] ,
3169+ } ;
3170+ } ,
3171+ 'doc.headerFooters.refs.clear' : async ( harness : ConformanceHarness ) : Promise < ScenarioInvocation > => {
3172+ const stateDir = await harness . createStateDir ( 'doc-headerFooters-refs-clear-success' ) ;
3173+ const sourceDoc = await harness . copyFixtureDoc ( 'doc-headerFooters-refs-clear' ) ;
3174+ const { item, address } = await resolveFirstSection (
3175+ harness ,
3176+ stateDir ,
3177+ sourceDoc ,
3178+ 'doc.headerFooters.refs.clear:prepare' ,
3179+ ) ;
3180+ const footerRefs = item . footerRefs as Record < string , unknown > | undefined ;
3181+ const refId =
3182+ ( typeof footerRefs ?. default === 'string' ? footerRefs . default : undefined ) ??
3183+ ( typeof footerRefs ?. even === 'string' ? footerRefs . even : undefined ) ;
3184+ if ( ! refId ) {
3185+ throw new Error ( 'No footer relationship id available for doc.headerFooters.refs.clear.' ) ;
3186+ }
3187+
3188+ // First set a ref on the 'first' variant so we can clear it
3189+ const preparedDoc = harness . createOutputPath ( 'doc-headerFooters-refs-clear-prepared' ) ;
3190+ const setSlotTarget = {
3191+ kind : 'headerFooterSlot' ,
3192+ section : address ,
3193+ headerFooterKind : 'footer' ,
3194+ variant : 'first' ,
3195+ } ;
3196+ const prepared = await harness . runCli (
3197+ [
3198+ ...commandTokens ( 'doc.headerFooters.refs.set' ) ,
3199+ sourceDoc ,
3200+ '--target-json' ,
3201+ JSON . stringify ( setSlotTarget ) ,
3202+ '--ref-id' ,
3203+ refId ,
3204+ '--out' ,
3205+ preparedDoc ,
3206+ ] ,
3207+ stateDir ,
3208+ ) ;
3209+ if ( prepared . result . code !== 0 || prepared . envelope . ok !== true ) {
3210+ throw new Error ( 'Failed to prepare explicit header/footer ref for clear scenario.' ) ;
3211+ }
3212+
3213+ const clearSlotTarget = {
3214+ kind : 'headerFooterSlot' ,
3215+ section : address ,
3216+ headerFooterKind : 'footer' ,
3217+ variant : 'first' ,
3218+ } ;
3219+ return {
3220+ stateDir,
3221+ args : [
3222+ ...commandTokens ( 'doc.headerFooters.refs.clear' ) ,
3223+ preparedDoc ,
3224+ '--target-json' ,
3225+ JSON . stringify ( clearSlotTarget ) ,
3226+ '--out' ,
3227+ harness . createOutputPath ( 'doc-headerFooters-refs-clear-output' ) ,
3228+ ] ,
3229+ } ;
3230+ } ,
3231+ 'doc.headerFooters.refs.setLinkedToPrevious' : async ( harness : ConformanceHarness ) : Promise < ScenarioInvocation > => {
3232+ const stateDir = await harness . createStateDir ( 'doc-headerFooters-refs-setLinkedToPrevious-success' ) ;
3233+ const fixture = await createDocWithSecondSection ( harness , stateDir , 'doc-headerFooters-refs-setLinkedToPrevious' ) ;
3234+ const secondAddress = requireSectionAddress ( fixture . second , 'doc.headerFooters.refs.setLinkedToPrevious' ) ;
3235+ const slotTarget = {
3236+ kind : 'headerFooterSlot' ,
3237+ section : secondAddress ,
3238+ headerFooterKind : 'header' ,
3239+ variant : 'default' ,
3240+ } ;
3241+ return {
3242+ stateDir,
3243+ args : [
3244+ ...commandTokens ( 'doc.headerFooters.refs.setLinkedToPrevious' ) ,
3245+ fixture . docPath ,
3246+ '--target-json' ,
3247+ JSON . stringify ( slotTarget ) ,
3248+ '--linked' ,
3249+ 'false' ,
3250+ '--out' ,
3251+ harness . createOutputPath ( 'doc-headerFooters-refs-setLinkedToPrevious-output' ) ,
3252+ ] ,
3253+ } ;
3254+ } ,
3255+ 'doc.headerFooters.parts.list' : async ( harness : ConformanceHarness ) : Promise < ScenarioInvocation > => {
3256+ const stateDir = await harness . createStateDir ( 'doc-headerFooters-parts-list-success' ) ;
3257+ const docPath = await harness . copyFixtureDoc ( 'doc-headerFooters-parts-list' ) ;
3258+ return {
3259+ stateDir,
3260+ args : [ ...commandTokens ( 'doc.headerFooters.parts.list' ) , docPath , '--limit' , '10' ] ,
3261+ } ;
3262+ } ,
3263+ 'doc.headerFooters.parts.create' : async ( harness : ConformanceHarness ) : Promise < ScenarioInvocation > => {
3264+ const stateDir = await harness . createStateDir ( 'doc-headerFooters-parts-create-success' ) ;
3265+ const docPath = await harness . copyFixtureDoc ( 'doc-headerFooters-parts-create' ) ;
3266+ return {
3267+ stateDir,
3268+ args : [
3269+ ...commandTokens ( 'doc.headerFooters.parts.create' ) ,
3270+ docPath ,
3271+ '--kind' ,
3272+ 'header' ,
3273+ '--out' ,
3274+ harness . createOutputPath ( 'doc-headerFooters-parts-create-output' ) ,
3275+ ] ,
3276+ } ;
3277+ } ,
3278+ 'doc.headerFooters.parts.delete' : async ( harness : ConformanceHarness ) : Promise < ScenarioInvocation > => {
3279+ const stateDir = await harness . createStateDir ( 'doc-headerFooters-parts-delete-success' ) ;
3280+ const docPath = await harness . copyFixtureDoc ( 'doc-headerFooters-parts-delete' ) ;
3281+ // Create a new part first, then delete it (to avoid deleting a referenced part)
3282+ const preparedDoc = harness . createOutputPath ( 'doc-headerFooters-parts-delete-prepared' ) ;
3283+ const createResult = await harness . runCli (
3284+ [ ...commandTokens ( 'doc.headerFooters.parts.create' ) , docPath , '--kind' , 'header' , '--out' , preparedDoc ] ,
3285+ stateDir ,
3286+ ) ;
3287+ if ( createResult . result . code !== 0 || createResult . envelope . ok !== true ) {
3288+ throw new Error ( 'Failed to create header part for delete scenario.' ) ;
3289+ }
3290+ const createdData = createResult . envelope . data as Record < string , unknown > ;
3291+ const resultPayload = createdData . result as { refId ?: string } | undefined ;
3292+ const refId = resultPayload ?. refId ;
3293+ if ( ! refId ) {
3294+ throw new Error ( 'Created part has no refId for delete scenario.' ) ;
3295+ }
3296+ const partTarget = { kind : 'headerFooterPart' , refId } ;
3297+ return {
3298+ stateDir,
3299+ args : [
3300+ ...commandTokens ( 'doc.headerFooters.parts.delete' ) ,
3301+ preparedDoc ,
3302+ '--target-json' ,
3303+ JSON . stringify ( partTarget ) ,
3304+ '--out' ,
3305+ harness . createOutputPath ( 'doc-headerFooters-parts-delete-output' ) ,
3306+ ] ,
3307+ } ;
3308+ } ,
3309+
30983310 // ---------------------------------------------------------------------------
30993311 // History operations
31003312 // ---------------------------------------------------------------------------
0 commit comments