From a1fb67b356e9deade32bab83ae2cb6d7ae214582 Mon Sep 17 00:00:00 2001 From: Andrew Jiang Date: Wed, 10 Apr 2024 12:40:56 +1000 Subject: [PATCH] feat: add api summary markdown pages (#3350) * stash: api summary markdown page * wire up convertToNavigation * revert tsconfig * delete comments * thread through fullSlug * remove unused export * fix: build failures --- .pnp.cjs | 16 +- ....73.1-9d67ec828-0e4a6ea31f-9790af8fab.zip} | Bin 889275 -> 911957 bytes .../generateFdrApiDefinitionForWorkspaces.ts | 3 +- .../commands/register/registerWorkspacesV2.ts | 3 +- .../configuration/fern/definition/docs.yml | 73 +++++--- packages/cli/configuration/package.json | 2 +- .../src/docs-yml/ParsedDocsConfiguration.ts | 46 +++-- .../configuration/src/docs-yml/getAllPages.ts | 51 +++++- .../src/docs-yml/parseDocsConfiguration.ts | 65 +++++-- .../resources/docs/types/ApiNavigationItem.ts | 23 +++ .../docs/types/ApiNavigationItems.ts | 17 ++ .../docs/types/ApiSectionConfiguration.ts | 9 +- .../resources/docs/types/ApiSectionLayout.ts | 23 --- .../sdk/api/resources/docs/types/index.ts | 3 +- .../resources/docs/types/ApiNavigationItem.ts | 23 +++ .../docs/types/ApiNavigationItems.ts | 16 ++ .../docs/types/ApiSectionConfiguration.ts | 6 +- .../resources/docs/types/ApiSectionLayout.ts | 16 -- .../resources/docs/types/index.ts | 3 +- packages/cli/docs-preview/package.json | 2 +- packages/cli/docs-preview/src/previewDocs.ts | 3 +- .../remote-workspace-runner/package.json | 2 +- .../src/convertIrToNavigation.ts | 164 ++++++++++++++++++ .../src/publishDocs.ts | 16 +- packages/cli/register/package.json | 2 +- packages/cli/register/src/index.ts | 1 - .../ir-to-fdr-converter/convertIrToFdrApi.ts | 10 +- .../convertIrToNavigation.ts | 128 -------------- packages/cli/register/src/registerApi.ts | 13 +- packages/core/package.json | 2 +- yarn.lock | 18 +- 31 files changed, 468 insertions(+), 291 deletions(-) rename .yarn/cache/{@fern-api-fdr-sdk-npm-0.73.0-d986da306-9790941d2b-6fad80ce05.zip => @fern-api-fdr-sdk-npm-0.73.1-9d67ec828-0e4a6ea31f-9790af8fab.zip} (79%) create mode 100644 packages/cli/configuration/src/docs-yml/schemas/sdk/api/resources/docs/types/ApiNavigationItem.ts create mode 100644 packages/cli/configuration/src/docs-yml/schemas/sdk/api/resources/docs/types/ApiNavigationItems.ts delete mode 100644 packages/cli/configuration/src/docs-yml/schemas/sdk/api/resources/docs/types/ApiSectionLayout.ts create mode 100644 packages/cli/configuration/src/docs-yml/schemas/sdk/serialization/resources/docs/types/ApiNavigationItem.ts create mode 100644 packages/cli/configuration/src/docs-yml/schemas/sdk/serialization/resources/docs/types/ApiNavigationItems.ts delete mode 100644 packages/cli/configuration/src/docs-yml/schemas/sdk/serialization/resources/docs/types/ApiSectionLayout.ts create mode 100644 packages/cli/generation/remote-generation/remote-workspace-runner/src/convertIrToNavigation.ts delete mode 100644 packages/cli/register/src/ir-to-fdr-converter/convertIrToNavigation.ts diff --git a/.pnp.cjs b/.pnp.cjs index 5996a0d7a9d..f348c2d84be 100644 --- a/.pnp.cjs +++ b/.pnp.cjs @@ -6485,7 +6485,7 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { "packageDependencies": [\ ["@fern-api/configuration", "workspace:packages/cli/configuration"],\ ["@fern-api/core-utils", "workspace:packages/commons/core-utils"],\ - ["@fern-api/fdr-sdk", "npm:0.73.0-d986da306"],\ + ["@fern-api/fdr-sdk", "npm:0.73.1-9d67ec828"],\ ["@fern-api/fs-utils", "workspace:packages/commons/fs-utils"],\ ["@fern-api/task-context", "workspace:packages/cli/task-context"],\ ["@fern-fern/fiddle-sdk", "npm:0.0.503"],\ @@ -6513,7 +6513,7 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { "packageLocation": "./packages/core/",\ "packageDependencies": [\ ["@fern-api/core", "workspace:packages/core"],\ - ["@fern-api/fdr-sdk", "npm:0.73.0-d986da306"],\ + ["@fern-api/fdr-sdk", "npm:0.73.1-9d67ec828"],\ ["@fern-api/venus-api-sdk", "npm:0.0.38"],\ ["@fern-fern/fiddle-sdk", "npm:0.0.503"],\ ["@types/jest", "npm:29.0.3"],\ @@ -6601,7 +6601,7 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { ["@fern-api/docs-preview", "workspace:packages/cli/docs-preview"],\ ["@fern-api/configuration", "workspace:packages/cli/configuration"],\ ["@fern-api/core-utils", "workspace:packages/commons/core-utils"],\ - ["@fern-api/fdr-sdk", "npm:0.73.0-d986da306"],\ + ["@fern-api/fdr-sdk", "npm:0.73.1-9d67ec828"],\ ["@fern-api/fs-utils", "workspace:packages/commons/fs-utils"],\ ["@fern-api/ir-generator", "workspace:packages/cli/generation/ir-generator"],\ ["@fern-api/register", "workspace:packages/cli/register"],\ @@ -6679,10 +6679,10 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { }]\ ]],\ ["@fern-api/fdr-sdk", [\ - ["npm:0.73.0-d986da306", {\ - "packageLocation": "./.yarn/cache/@fern-api-fdr-sdk-npm-0.73.0-d986da306-9790941d2b-6fad80ce05.zip/node_modules/@fern-api/fdr-sdk/",\ + ["npm:0.73.1-9d67ec828", {\ + "packageLocation": "./.yarn/cache/@fern-api-fdr-sdk-npm-0.73.1-9d67ec828-0e4a6ea31f-9790af8fab.zip/node_modules/@fern-api/fdr-sdk/",\ "packageDependencies": [\ - ["@fern-api/fdr-sdk", "npm:0.73.0-d986da306"],\ + ["@fern-api/fdr-sdk", "npm:0.73.1-9d67ec828"],\ ["form-data", "npm:4.0.0"],\ ["js-base64", "npm:3.7.7"],\ ["lodash", "npm:4.17.21"],\ @@ -7359,7 +7359,7 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { ["@fern-api/configuration", "workspace:packages/cli/configuration"],\ ["@fern-api/core", "workspace:packages/core"],\ ["@fern-api/core-utils", "workspace:packages/commons/core-utils"],\ - ["@fern-api/fdr-sdk", "npm:0.73.0-d986da306"],\ + ["@fern-api/fdr-sdk", "npm:0.73.1-9d67ec828"],\ ["@fern-api/ir-generator", "workspace:packages/cli/generation/ir-generator"],\ ["@fern-api/ir-sdk", "workspace:packages/ir-sdk"],\ ["@fern-api/task-context", "workspace:packages/cli/task-context"],\ @@ -7388,7 +7388,7 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { ["@fern-api/core", "workspace:packages/core"],\ ["@fern-api/core-utils", "workspace:packages/commons/core-utils"],\ ["@fern-api/docs-validator", "workspace:packages/cli/yaml/docs-validator"],\ - ["@fern-api/fdr-sdk", "npm:0.73.0-d986da306"],\ + ["@fern-api/fdr-sdk", "npm:0.73.1-9d67ec828"],\ ["@fern-api/fs-utils", "workspace:packages/commons/fs-utils"],\ ["@fern-api/ir-generator", "workspace:packages/cli/generation/ir-generator"],\ ["@fern-api/ir-migrations", "workspace:packages/cli/generation/ir-migrations"],\ diff --git a/.yarn/cache/@fern-api-fdr-sdk-npm-0.73.0-d986da306-9790941d2b-6fad80ce05.zip b/.yarn/cache/@fern-api-fdr-sdk-npm-0.73.1-9d67ec828-0e4a6ea31f-9790af8fab.zip similarity index 79% rename from .yarn/cache/@fern-api-fdr-sdk-npm-0.73.0-d986da306-9790941d2b-6fad80ce05.zip rename to .yarn/cache/@fern-api-fdr-sdk-npm-0.73.1-9d67ec828-0e4a6ea31f-9790af8fab.zip index 5953f1fa158ec51e72c833ff58877fd8c3ee3991..83427613295f2c043e61c0597081cba15a1dfc82 100644 GIT binary patch delta 58783 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 {k?m~5(q1au+tAfwnhWNAT{bp-D|{!a}F zTG+>fP&Od`-^?_b6(I8b-FX{c5#kE~88x3-)CRg@1q7f2_=n)o!6pQVlq3-Ncg_Eq zZo>S}=_X}}dIEH<=0h|rFd>&Lgo+-8DRTzeByHY_NCWu|22i(kmLmQFpv+1G9HU^N zAtoB6!3LU5N_nHAfHE@G+&2DXlaKh)ejC*Ao%;>4nKe$))~I`Q;uy^%<8n4yDF;Pc z^@U6CDUa#adJaPr=Q)++{oPhOCn_f9J$XB_%v`1Rv`vG5g}P-x+gl3jm39k(l+9Vq z&QHwD+)otsI|xdjIo?mDTgz)wtyY;ihTU^Jj!+SpwyZdVLOe{I(N6@7hX5`rHTyPV zUpX}eK78TAW(U&iK6mOQ&16W*vE8Ox`AZwKkjb9kerxo^+mFDwzzpCKsY6I6^russ zIZDKSGkI9^day91|I@29Zl9UBGb731B7+f?d4X&***KjYye zrK??*TR_(qsG-^7yM&HXWV~JXooo4Z_lF0Bw*0!+cAN2A86IwwAM@GvZUi=xuAYpg#KD@8Q2K>l*SN_LdgjfJJN* zG2{k^@V|BCooih70$J)0J*Uv{4a*ZQzi&jlWq(oRyZwUQe5|}*&*i4rT+RPy?&QCqppby~sMwUei_Q!ACPT1HOp47KfOA{=pWN~#;5J4ZQjjrNh;Z!8<2pkR(xW_9|mhyFrrtNeht1B>GS#t(%7 zs-@$|U~DcWNXiKs4+NtI5d$Pu_SNuKidyeOk#v{T?8lP<(LpDZR_V3h4}r)i*jN4& zzd{a!#JYYuCZd+QmFDxF9lHj<#N*Xb@%e4{?X(E+ws2~uVPe1%ixVp~+QVUY8akVE==&Xi-->&m_llX3DdRHPq6;Uy_jD zMO^%+#d>$LlPzizmH0af7TJmvT)VHe;T-fYVOH?2(t(8r5F#llm}r`SK=NQ=(h#{L z+VDN_Pm-$d0;Q<9E(qNqSMT<~>f!dm>C37Co>8BYo9_aK_zfe8l zeFD{7E#5z-pPuR%jBm z#FBt4SYkSZ+$^R`@I8c$K{yqmSZD|fW2VB z-UW@lV%J!}-Xek}v5TS{6B`;6yJGAedq*@+V;5uW4UIjP_n(>FyL)}#mxp`WoH(U@8;$Im#$;7OJ-M%SG&n>`*r zq#*J%QT+!x$H#*AHFg3WbvA}--1q!WyR^RQp64RcPcmC*jhn|{vP>~sDPxk^ZKv|k zbF7J){|jpsdugqS1$l2e@XB+}&hf83S4QxqEM8Qmn4S|ANB#5D*P{AhDm2>QrI?GR zCf6S9#1t_@2?WyG38>J)WX$k(0o6=mAaNhilJeG5Lr+0q%9@&p~?&= z!oj@;6O}CmH(bh6t5}!bbg&deCW{~6)0*Yj*@!LWYQncr{BKpVKAe(E>sKhb;li)T z%J{Y|4%LV0u2OP@zM-5UW9V(9ZFLaT?q%S@k;v3}lgm+h8JM<|BcHgdf6yMa}XUU;clcxl@JX78XSzibiERMSY-Q=9q#EtUjm>Rmkp(m znnETu(&SFfOSyYe#p#CNZ;H#k77eYYA4K676g_pV3ZD;DK`nV!iz{6`nU5F@Ob%17 z)J8R_M_E<%rIbq1_;;PugVjy6s|o@Xat^8K>awMk%A>kc)hisn&aDpBOZ9|!_gY?L zih{dJ11kJPH-a|skNM)qI8l{k+bPwM+2hh`o6KaY4Ufz<^~H3B=}sMeQ_48z62XdA zs@+QOrQ2?!Ha1kIwabxlQS)OO)6m^6iFONNO7kWne9J4j>uGaseL1CSQ?!i<)IAy= z6mMo{`jBTG_?xde-Kp%J$Q2ary9LU+2}KOYkoM_by(M*hBa2gYPjF&ys;jS{Y-$Pl zb`(1j^3nBRzGRF_NIlm?Pce<){PTK<*t}S9`cO_|)Y0$jLo}e3Afz-jc~N#fw2qPu zAU3oOs?GpPZvekP%YR!QDmID!4I$CJ19H$bwflD-bgCijoE5*Rb|ZatrEn+k+S9>- zNCf^^=usnmpt9IObvU)j54JqIP~l4GJmHWf^-MeGyry)aa!vHpQ;-*o*s8XnC^ZDH-7zrbY0NmYPJEl{{*{= znP#=s2jf}_SDG7bFeu+8LT?y_T!AAq+v>|IwI|v|P4maOktrE9XmdGq@nK1JNl&`j zP9LrWCaaPZ(LrBWig`@3iy3HId(^Ag4hZR+Np@Mc)XftB9PEIs-J8s!sp*O0w>33- zCyvp2q1(JX#UY(C(T8StgcAv);Ka$PsXj@QIh&!%-XB>iH6b}KE$ocnSAT-Jc#7_C^Pr@z=v_R>_8T~$uKFfQ?qcz^?jWOD`w(vpVxOa^>hlH9w(LGJF8KR^#rw zNw8AG*5s$$)vFkx<_OMWr}l&LJ+i(V*>_Lb5X!gVOFbRZDLUvM82 zvAm;~J$39h)S#7iqFD2xag(5-R+!oQZ5l?3AE>XROgv!!jRm4W>RuRuz=*`3L?1BX zphz^Xii?@D2O$ifRf0dq$VzhtBgMIyb}=hAMJr`5Lf%UrvQx`Zt;uLg+965kVIH~+ zq=a~VWyR-+`a@6F1bu|^@rYeJn9^&wnCSGM&aLt7QJcb0eU$ER(v8wLObv;yL?L}l z`Ki`01nk~%dO2L5LXivI-Ix+gmc{Vu=?Pjv?hB|zvH=w$00Xvle<6~uPO|h-<cLBHbbz}~(O#xsSLL%unDWxTWXMmvA$$3x ze&{^7CehrVQIeBxl5UQE%EDNqJ0(ogm!@;ygF5||9Oz^XbSX+-CPRJpZQ0N>ubOG+ z6y$VTj$Kht2~$z4)b{k#9h7DdniZ)pW*O>K&d=(Y{$`FiFErbrFF|5Zx!6IR6p10W z7*m$Nt4fOFUi*2liaUtBl=I(k`bG)k_t z+0E!iEoN|;#zSt$V^!Uo$zjUgCt|!uNr||i=?habo{I6CN(q)lw)UA6Oz|`tC}=h; z=AJ?=S^iu~+sR?d&o5*#S|*`2&z%FousjEUd?xQr7 zkfyIhUwebQ0QUms5iKj;jUvjlnm z(?P+9ZYd~3aGt{^V@b=8W7zTO$Y#w!_-2SH*=RSmKY`V)mSjyMvbZyAGTX6Q7CW(4 zC2y82yTLGJpNA$H3(Z}LzUK1^q*Y@DKGerNg)JyJSYgUVJ@r_puRq- zO}>trewPKQpa}q2F6xI18G*6hHlpHQ(6>}?C3y*dq)+F z&>WxM?~2mP419XK7GtCRD0(~6vgG&3OI81X3pGoS&mnyeimRfSCHVo93zm|>O}~V4 z%??HHIBP4&?xm$?F&A76wt*RcvvNy2OK;OxQm%)pf@T`FQ}0XFcHpwN<=Y{BqKuPt zp&e-4Z^NYYk`U~ZWbHsgCBju11M7z=l_R9gi_1tl|1MA(MRKm=Df)^_0G(q>opQ1? zW3E636i=GF8-|6lugc?Mt~&cr1Dled@l(l9GN<-&E<+RMmE+xJ*p@{F}2&RruI&e%jXB z;7h>=^(Mx~+H`3*! zwMURaV{1vdRoBBxZ7isLAx(A8>t9>HbFyUFYI3EFEv6z=<`~Q!YQsE{Sv@UprYk|u zkHO~gwj9A`4xcPtH5n+|j``D-PwiwyNc`erq|_5Ic&|MjI-y^sobNz~{0wy#=DNDm zrjuYy>&Ss=Kq1~rez7oOiPxC?YU8Ku)%nwbQ~GEnr<1Hf=`OATH0?CLRoBSpg1!b> z3cI;eMvMohj;GNo3!Oo=r7qIEP|u0=@S^Ii5DL+G4eKfm#kSEEpcZG5zX9E3RqWmd z-4H0YNmK9cvU;S~H=3wPmflP+s-cE9kK;VWQ@3{5KWv$W%v9|m^IfYQ*3FX4D7|+~ z?$A@V0z*es#lMEYH_;c4?IoqVcS7SnG8|;l7k29{rMvmKdeA@F(68S|IvRZh!@rn| zdT(kr6suhuFJPvg)K|KkazUS$x?O}@nf+90Kbq@@KzscOBm4SG!OQ}#Ml%1&(=#6B z>>J=Dy*W;Y`SSk|i9_G3(tZ?s3Hql8s)AVTzKkk=Vvs81P6scemY*D~$`q%~tB@l{ zmzFg|EA39PEipP0QoJmuyFxv3Fk^{Cn=e@0)j(TkLSIY`G84Eq_Mnu0=qZ<8g?k%^ z%BGxq3@e7qTu`DB*HGF`hROOFQX08VxdyL~4CC^TqQL`no;3XiO0?j02(}u|WU*Lg zrsrO0jxTfulO;w|^|FW4mh1ZQO1}{-{2e8nL}Hfr-%Qk3C4Urrv6ALwj4IzmLO+gV z-F6fa0guXlK<5^66N@@C2kD&W>Y<~^=Qc()2S4b&XzmRNWc-bexBV?xxFUF?DE%Lt zV|#N8MLu&hOK(#8jG;rf^~;r#W2JWV3UtJqJdv5ZIS_j?mXnSn?Dv*eejCRn(}yAl zxY~TwC+SR0ccpSdTt`4Xsj{UD1rvzn_HJ%5Ix>30|29k!9vhogB~ zULn3&xgal|Af?l@anFMUk&1A4?-T&YN8N*-f07iaF%`x2 zRWZ1$9+)WLJ_HIRv%m=2)CS63UZO0LG+8($_#2c;lck}I<8Gc5KMmFnvU7nCVdIg5 zhqcKLFy!?L`8mV98&jm781043fL@nJsBiP9s^kKc;c2i?p~uM2f*+aOhtePGt163r z;&>0BghXU6*9-eY;qHcfau7Lin#%LQAR4_3R&}hFi5lPYOxFteP_w&O`awZC*OfIk zsiY)Xqb(Hj3a<2?!OFu4>-NrC~BCuR3Wuf;jEOwuIxVJ2O8j%xJBEN+zv zavO?R<{_Fr`r)5x-bcMyq824Aj07qdY-D>I_YG2S%tiXz&)F!N_Z15uxIfoIxzDh$ zBwCm#!H~slUCyU*e{LZ2EmrjsU6}ewldUUG@;s{+G2r%ORqw@x{8)|7z9o({#8tW9 zw6SLBfRyB=LWm-7>3w8(HD;cs3Km%=t?(LK?mPsPTZC1;Ll-Ib)1=yDIm@RimUKBr zvUfrT(Lz!)a0gcIAWQ`B+4ym*JS^NmLY2`gqy{Md6l*{~-`5o%E$d22ws%y%R>#%5 zdGZX?Bz{)N4&q}e?o{XtD(KPQ_ya2j)uJyHZWK|L{;rZeDAV0gL5W=Lpe!&%DVJ@( zJvN%5yO@&gX6p=czsQd0PP#J1>qu50ZH+YQx}4BL;MilMyHc7y!L zB|MYO&yy021|wNq3;~MAM&=Esq@f6Qx{D!H3E3nmIScR zj5*GJHz1Tq5b5{m^3wM)2CH`qO-1TVxeiKZhmCw_-QHl=`xU;H3P80tnR05IU|MR zu3#h&R+zH%to-1MkxJ}gEQ!ZvVvvHdF*3}v_{HbsaP}LXSZ`gLrSg1fbP&>BabBjK zehV{zU@H=slP#0%z6k>|Q1G3$8j2}DT#$la=No;fP%y~j3xd4)B1^B+-KAC~5ZHt` zT{SurY^bE%_@9)I)Z+w6WH;nqtVdtIB*|A78qIVy#5u2rF0-k@)crIn$@LI8xA8AI zY7R7-^T~CJf_yS0@d}4v99f=WIpu5-m=*^{hF|6KNL0yT%AjjfFsvAcJ26oPf5(}R z-q)otSXGs{8*JOSQHi=IeZ`LwGKv+jtjz0V*;f&&rDag{)EX1~fC`r}{H_=tN|B_p=re1F8OkdE zKBPls4Ws!-A^OB^<0clG*$iZAD_M`3y+O%*B0sX(;f98~jdZ69iZy+Mu@v3Dg?gM6 zVD_N&sa%|FVaYRAN}!Z=SkrOh@iNY==Qcx;hWg5AtS2L>G`**RBCTdOiYgBqVh6T& zu9FQr4|^ytRX_4l_I>o#Gb=b}w8krkMLRoGDfO>v%t+HKu%Fy0{9Ze?n)FJBNV&h1 z|BY-9pw!Y8q*k>JJt_BstBH~xW1jc9GODL~=*9gVTOLARpGX##``^hzimPfUE7#&$e$8agC#Jn7CyTWQ+Jp~{W_q+rMvw23*@QO_=6*_f-cof1ru zMG(=8pPAf%vWufVWJPgr@I|(nf;A23P1Xv@m>62@&Q{riLjmjHH`jK(Ely zP+fUsVspbOwh)%nK?#!;{(+f#oHz8Kq$b$>ON#RJk=uMCa96yfev+@7iK;b*#cXdU zBX+W_;-9ssmYQIT_)crI5=&FV5M{fs%w|euv!0@xqNa&{Z*yK-@D3UElylgKO`T>) z;+K4?Gckm3Q=w*_`RP1&#A1KzNq`6~r0gV>#l1QgvAiPeBe- z)&;5h9u(2aP(_(;m8xHBn7!$7J*bK;p}KZ-r<0*qYWfv3ooZufs>8ZoXM{E-(ha>(Ti9$}R0bZS zLVxmZgYQs_cBt1eI4#JPd`=dYZa%kzV3pz`T4{C7g5XI{GO>KItv!Y%Ath+&P<++J z@F%gZ*^{gtpwXbT%=^p^hDdDOM8_FQ@mp_Z%IWT@r;i=bFSiZlV3btJfi$8cG<$?G zxeI;iXsD@+rgFXDa%O$EQfU|A&9+XEC>?IAon3f}UIg1rqS6(NaH?XKF6iw2B4tM6 z`+El9l_TVDacB5_vkUyLTTWJhoMPBx!Z1pHXLJcPuP-{Tlwqj2UL}+Ql$`=r%Wf#n zJ{8!p9ykx+Y2m^TQyN#4ly2P(wUn}z`f0?yWT$WmmEu?Qvhhl#9uszwEh9)L2wSYPHgp{in)Uvshb zc?PHKzBlYq&NSpAn@2+iBJ1ZHF>yA{j>2io&w~(l$L`@@jal%xa<>V~OrgjW)S}#q z_U7_;Q)W+dB8x8XUNco1>jCkG!m_)&Pj^NedQsd=&l0R5SP{yT7F0OFuu6y10AukL zzA@a*Og|?e1>y0L7%oUTZx_4U;z@*hLy_wvvD^a2Doa~&Y7?nNeI+j?4nqU{k9z!o z+8f=~TtRl;qWik{os5a48#<#?!(k!2jY`3pfNp3*Fzic{N1&eWYs)o>X9N~1+a2vM zX9P4Bwc{p`NE6f1CyS0i>|>?2cQk>tm7d;`C5|Y}?;th4jKXkzD%RW8E#-PI+)%jaNkW0yr(1WGn6eowf>o?W+JNH`d-WiaFz$NZZO3p zYpUU)zD~)(xDW_c&h-IY^zA0 zFhx~mbi1ie3Q}avw4X3W-W{*%7(l2Zzd3so9Lh|!Bxp+Iz))6-rwY^2R?~+`+4Iv4 zk;>%Z%t==UjGzm1Fi_|=3geifGf_={9m!%Fm0P1&q6Z}mP>QqL$TN?x{x_Nxrc!hy zM$uy4adr$VjG(w7if`H^By?=7s#%1RcDv!&&s;;WWA1SfOWtz~J9K-g@FJ9|cy%;H zZweM-^6R_{tJiZ3BdO3{H(NZ#+;In1ui4x9d4>oagy`{$A)GSyf(EDlc8 zAVgGbdY8cRG&gKcn!&$NuS7n6@p3v^bX*h81Z} zC3*&`bkZfPwGbMTj_oq>xva9lNic4?p{7!Ip_5>(kC=GXNQaYHsupFAECr-}0yT35 zN-(Q7h9sgdX-iIO`&Xdn?YhXJLDARTJSc7kj=Hz}6}up_RwC$&epXdVGdWcG>ldMt zno-V+Qs$tqUiJW=CeKw!|F6ZgsY%&Ewl^!()-dFLx?fuwWTb)U%9!= z@kNPo*Za}F-?5y`uk&;Ubn2X2o;+nV4ZrnrmM=`k)%YO1#aitelvaXS?@b%$1Eg_o zHGEw5t0aebVKv!O1l!F0Z(_!>a19zz%ioxnp}hE=|KfbiS}bWSTw}BI0o%DL>o6sn zxz0gJjm4az*?KII1#Zw#J<~Q|MsgO1W`z?U+yIr?UTROjQt*5FW>5=lm)+a!(k36Kn5oWgcx-=5Mat8Ee;~=1`?+Am8B8C_@pSj0q)jk5@Fskk zzZC-c4vNH5y{&#!`ytjt8*T&jY9@R71LYWjs?FRCjkq1q_`N{PU#bC(^+ z{Pyi&bvVjuyA_Y)YN`e3(GEnb;0c*0+%ObE-FLy(ww+KYaY{x6NTGs)Y<0X{k|)m$ zO;{?O5yilGB=M3-z97fb8F})|)W~+G6`A($r~NIBd=$S6Nlra4-FLqH1&eEE;8Ka* z;Oj3)mwhJP0myN!U#S;WzkJo}WTZu_coqSk@$Jr94@>+{Rv&&OL8g9( zQ{Q_@#)+Q{kbzyc2dm8;sqisgh|W~HiIT87o*2lJCquU8!I0A6LJ4m+?(q29BP z<~vU#zxkSUr2ifOQo8Sj4?S_c*ib`#0+Onj)p7ZJo;>3mk6Zyy*OXLq4nH+VDJi5;Z1k-;us#?ni%$HBMArIjRMGAMNYB(L$XL zz(bFJ9Mh9jbA*v%i{MDwr)#K(?gzo&f6v~-1yRmfbU-<-CJP;9R+$If!zI)5gNEX? z=bYlaqq^cD=V%al9YXRgA9EUg?NB5Wc~nPlb@dQzEXMIqZsT!>4K5UY96dl(exl$FlBebG=FzF-zWtRj{W9-m~>`O5^ZZ$faT7>#0Ekg}zCn^EvRBdD4X!SXl-*$yb_p z%hlxKseuh(c`D1$P-$hRJi5!G7~3U0M_xLrWa9+Kp!A0gUE)~ z@lLyL@FC-$*bz*?J(HY=jLV=rxrjk>6BiffN*x)@0Hi_+Duq<5 zK9q0?@xRREwIQlWT$t1i2m$c$!NV~{n-3;B;DG~Ov7cdSr>7>lWkprx7D|!gPAbo1 zu#=N+!imH#Z=pB;FC_J$ger{@Tnu*D90GN(K;X|(ss$Y8zJhi0_MxhZ59NBh_#qY+ z`e1Rf80~$@s^lCh_Yc;NBd=j56Ia$r;aPv2bk4bgtXi(a{6FEsd}>0n4|TqQuU}_B zO>XL9b;uT7FNOqpvs8IqI{7@1i&gnj&rbH`yZSw;`XBJ4e*uktOa<02nHrZ?fMRZ< zmffjnCzPfKH_1YhU6u09y*lx8U~)EDG7Gl6WS#2)(F* z?jzzhcrB|-UdnAlH|1On8NV($=&A|;B5BKwnY?>q4FCQb@?823wEEO`R6HPge8^fH zdD>JSUG7un2i9T!q;FVT{|4(~U73c!`+UA@2p}r0iNb{XPU*%?MrQ}93QAZ*RWF1N z{DUFl*+yEyAo~0P*_s}%F&E#2^#GQ>Z)mK1Y-&^K2`ooSq)RYY2dm?X{ci_XGn#Wg z7#1WEKzQj-FUD8&>jUIvU`v(F7$7kwDzB7@RjEJ%VZpBwVk1UGUXP%3tCe8m6s}7( zX{$svjmN%i*vUbZUJWphL64EsPHj~RCX&_Bm(v%+FD&J3NET+Rn_gEymk<;Y#bSS{2{4dcbEP?f_Um zhnl&&R?UgO{RKW3=V`@9!%&J_43KQ|TyzM>ddkpe_DAyK<7;{eJNtVx*#Y~ht=z_P z$y39?)Y!AG4EC{z7TfFjDqOr?l(`sC64769Rn5BFR^o{2!Jw)RX`qvhjZW2;MRr%0sLO0HOd9 z!KnX0EjvNgC@rY}>!s-lGs(x(*pNaJ^<`Mog0(?(!_7aVvaI<8{gz2mKXZhsB$LCH zoMc%~fcPlJ*dZJe{esZ=Phs*2rRIXfJn)#6`R0LS_!ngRg6fT41<#m|^PA!#U7Z-cQY zCFtSGp`|Q0g)9bR4W%Qd<=jhT7>r$%jp>q;d66OIlTjp*Kce7HOx2|0xspRAa6~>7 zXflQ?{=Z5i0s)j_HkP8P(=;l_SFylk0mTIn11s&vk)X*D# zyR3841I{RjmX?EeCJT6$4N}iRzBW(eLC_{ARV@esA9BlQ3{d{vE|mog34ozM3ik!N<}C9D?qr@=X!9aF z4~O!XXbeBzWwVf|6a-)=lG-iP@M({dw#2-trWLX7 zyGfJf)u%;Mr??RCY6TlBDOb;EQvt-ckg+&f3&Gr&b80GrTw4h`uj)5a+Gk7E>|ad9 zD59{jf)3Z8ltq__)%^xc2q2FlF!TOTCpo}=+-Y+WV|iuOB_@mE8h`dL4ox37|QEQN%R!I+;I}lDQOI+Yo(Cr?7K3F*spql1ji+fFNzs7V26QfRB_2^fRunWpKqL3TPrgG!E5e*I7VAuvRFX4WRQCU}vk2wk*YzG4eS8kMR|aHI)Z0Oc8LJ5b9I|0Kw*!kdK*ev}FOv0!4JM zlCgra-$PQ8DjQ>!w|do%Kh3F%sP(A=tyU&_S<5J(L_w60i)f1m{eXFW%~B6P>ka5BRR2e0O%CPf~rGdVqQtUUe}{2O_++nUuW`3KdEYm1(lGU>iQ_~ zzQY27Ei-zW`=3jg>^O(j0PoKN>|0dYR#OR{nuIG20y#s22uL6R3u_`eKL^pBenw35 zn*q&s)PPL%O3`cqeCsw`t3L%U+Vq_nT@Rj`?ZQnyCDT#fpu+zBTy+GuC{JcUl#(G zi?P6PTyKXnqu&TrGq^fWyT_G~wo{(#RaLs2 ztWH7AAv2}AltJLJ_Ins3wQfA$y~Vtc8mdYuh7uK_-&=q@p_ZyroaVGZQybP2OkJ(jx`7&%{9bYdu+|(8@gs7$Y3*iwCb!EO?#`Y}Kta zo^Q+TjA)((87C6!#9@S3w3V@{;(_A|?TliX%tvaTX$4JPV@Zx|4Vlm4hX55B=xbkC zzup=$cnlS)Vgb#r8ma{9sRoa(NA zH0KT?ey%52x4}}j;ItCAd+EqRtN zScXdMghZzFfXeZUYRsPB@5`5&B(I> zNbT>Dl9xRLK>ggGcvSE`dd7g!D%qdnJKHnaV<1!}k71r|QVXn+&75Hnc)D@i&IQ)U zIXFAJY5aX}ld^%3sw&<;a7QD-Mp;YXgeaRcaT+bt1R=zTqpAvyyFf$WjBGu@-XTao za3Yh%GPju`Vo{0@dTET5N|FLx+fwwl zw{6pUSEbn z`pL@Le;CLSGbI@Z(gP`EDz3*B6}iB0@Zx7lo~5HP*s4DJ=9wqY7)`3Fvsp|)jjAgD zU?pLPQ5>4HHBk4FoXk9x>_I6bjdheHoIPN{t~*g%%1$=svpOCv`xd|Td#e1*16pLO zt6xXK=&^?P1E7C6W@?!&r>s#)DF8 z8B=V#CBPWj^gVw7FKxNX!?hi%?cL0Kmo9k%L!`!sI!yqtAaGr_?>F}6)p+OY$d*?~hgUW-ZK{k1{zfF7!;9NDM} z3gD10R|)I{ZIa|?hfqnfXWMJ%lsTG)vv)H~3Dl4+Zvj(~K#46(R-r?-TuotCfa^pTVSt|Gi5(UPD{MM64(*lQbaWO@ zS)ZN`C;j%b+ffqo55SNo{c{-hJI{c0-2=?)OexuD$dL+%Y6ix8dk$(<1jfingJ;6r zznQ9v8-1RMVyJdl<{79WA2IzsH4CP99+9s9z@Vbevk{4^$D|xUMLyJZH-;=Bb0E0u zxD?D$%r6{AA1i!gf$C$_QDh3%^In~C zP;*nT+BW~3Of`KT`j3F~GOgJ8_^~Qma)2MIr|2(Aj#n@?2`#AzP}Co;7J8g&G$_OV zR9&&sOivukTk{y+FI)gG{spLLfpL%0^D_S(OxG5ob|3mn8Ut6Pja!1Q<~PxkFu>z{AZ}BF~vdb8%X_2rAe2XzGgZ4HihGltsoUCGDmv9Y|ly zKm>()KxN?1u+;0e6#Qhyy}5#1`WKL^-I0kW{bH=8yGcXWqA%5;ihSkdwclb0H^0Xf za~x&70iaYY6qZ~9@=hRqIHws)FmJ98Ob_>H02IXt@Xk^!>vnu1B{F?+(DubLEX1Cq zEgOyFDIqV;>UK|ule?F50?(zBc5=9K8JHYyP(TskY}N`?nzk=xDCd;HStdTGL0K!H zy6Y9y`4t^(+)Atj{QO$VB)Q}47$^bM0}6GE%w`3zyG+!$`9>cK3O*8Ef$LlPb%8hsyrX(o%LL zJDP*9OG`c)&}=n$i?R4&GiRZuC(#jnWb$|&m3t~J2^^AM^46^Zud53cz68ere9B81 z_kaQtJE*JgYI1kWm8B$*$sttco<^vryHhd_sU7z8*f--}aDQ645u=ihU5-I2}bpdKBPUGHccw6#wast_er-J`L&v&AL%*n=Lo&_oC z13IIqt>`QZ1#-UIGFG<$Iq~=mf!j8CI66oM252V}MStQ-u^pY*?*BCDcJx>qcObP3Au_eNXf&AIogjDG z336{dCCb$d=qMjq^*wii{Gq6n1~RIll3iTN01t)b9v3%H(VLHOcXM8~S&xs;UgJzM zd${Ro$SGu`+#VSEuC%Bal(`2TfomC-Ii&OqQ;9e{S_v3|Y@?ei#qUGdj+Yh1nVJ)A zOe=>|>7tX0+7DAFB1EY;sQ)oFtDIAqCq{Yt%N@o|2T;xtR5%Oc;MvlGZPiiM~dyrD=ZLD#TLLr#um!vsxl-3JC#%s ztzzOKRMwcoNVPb<%tq}3#wwEWQ!pKp};3+*hmtUMsAT@~J25FfI%# zNKK32R5m{E7P@*IUd_a2 zuG2_0T#8bn(CEYx;eO`LY0SJt23_T)h|^F>JOy$!-1CHQPQDw+6h^iCavfHQLcVIQu{mcQJTU=0&vV`G3O4BR$!~5VHQy*hHz&TUH_9 zumUKh9!m4(dG3EML2y+c7Tm53?WcNygHwZme`s+T`MKBMiG1s_vA)vfdzDg=mi`5q zD+5)E6|2#1nCNmv>UIU@I}Mh8EN|{6hkyF3pt{COhXBw*dmIMri5T&XkI`i9j|7h8 zc%|Vm{@a*-9))&|-RE#+_HbF|nJvr#)a^PbVI!qXiea?YwMr(8=x!uvZiGwKL=fG;^Now+CFkb+UC_4sFW$PWdj-vviJGQjJ zkV7ogKDh&xgHt)qiIg-GrPKW`GP3b+kQ0C6VBomQKpb96nTcS67p~Nwu1b4T+1Z|E zX{qKvQ29JVRS9xkihcm^gC2t1F_ks?q}9bS{RwGkihBZa9_0kH(iX7B0E!%n z0nX-!#sXILitm}%4foS6x4#cWD;go8uluT{g8ck{q&NwWx7NzN+_V-z-7CGI3lWC{W^_)@AdaEnoS+b$72>0a7Vc3~Z9 zzgvjtNU9kjyb%{|FcomOKv_YyF}d|!RahY3{3S2a1m4$wL^T!2H_A4dYAW~dbM3Uj z&_F3ld$=TzK2!xu$vw&mULaS0tV)MaHs9qY_Ag7E(vr9^4^NxSc{41{9HuZe%362+|Ic9uq~XIw7{D!FJwCEb3J_O2SY(0@EW~z zN=zW)_&pyM2v_dEQuRvEzPwQJ$P1M-ueB;Z%nMicyp_^Gj+Lh7en|ZO|1{Y>_g?DR zVR1Nn?}zN({;28&r1_gFDV07sLETq0K01HzU>Je`0LzbV+MG2TWoZk*G zVJ+&m#=a%AcER1w_SOA#Li@%WAPxo-r$eM{^i1-LE3W7!hTzagg zDZq5OU-9{CX@%Z#gVf9Z>RE;;P=HMNbn10{Wcahkw$>r z;I+o(DFITzvI)~`Ant^6s8T)1K^CyPtYSz%-KwGDE4>70x0%IJ1H*$IEQ%~)s-Qe7 zq@@6Ywh>#;Pf9?#YGIWZKub!3vb2b#h#U(bUb9jlA1W%zz}ETDveNM1wKTF-rZ^Rj zH4P>p@uCze!66(%RYQ?#WGNb2-Xs8bdKwUAvRMDVa;e-()cU0^-@=*BmuAH=G^>os z&-$SAw49m{D*!R=t`)8}5hek)tET)@mUV3Cy38;n4?uyiB7k$tt71;v&gkyE!f+r` z>K6((MJp@Hv-B3FN<~SG@pccO)0iC^YW|m6J7DLyrxLcl!m7UcjX2EG#GnGE^<4V}v<^YGSmjgLcnKS_ z+O5nZIF!Lv3NMir;R3PHq>4zSE$)yAH;I|Enc;Dmc(*ZItd1w6^W+(=Npmy~X~dcY zMy>$Ws*E%puOffDr5A}ypGE5o#gXgkl}-7q`PJut^W+()vHKWjG}u3W5Lnoyw|MSW zSsBaz$^L_1yrqs+5U>HbbRyOy*YF%@x!b%jbf&7wLw zKoM=6Ix0N#1q97ml$;QlUJdEqZ7W^JV_!JHSltw=8;Vz!Ojw*e;fhn`r2rzmx(Px2 zP)gGl7Iok>1&+>(X4ing*eF;#-jQpPK-AgD9m{C+-glD4fP49jjIzUxCb-?1E!nYk zu5_~|%q^{f?8VeX_9DAVn^`r{Y}VVma7V@NmyYm^d859zW3|Q)*M>yJB)$pUNIw+4}eYre_P;4{~;wIEJRaWNr zXCJ1_NbH8kGN7$ma;&|48|S|7T&ZyDjlX|soz$_SG$ znOtxvd!YjBY}Up$0Lwa@Sz2J7jqlYE{D_g9B>}9fp)4HD!u=>A8%qnqeEUX_@y3b- zSGt7JM!g+QXS4B?`9*$^{E#}hXAl6uAWCV>Y7-?Hs~*LqwMtDu-jGbKnwa>8(L-JF zE)X8PGSZDkh)(6E;O71)^Bi)~5K8ya%IJCrO;E;7lVxCo&l%}@e+d2D47zSJIKg2I zowJeaHa7+8=2LQjx?_rRzl^3WtWy9 zhs{-`1zygBmbHYD*(oeNjt+Xb;Ku5f@S{@<5`0N@dZEE&w9!`}Amz#_%do>AYg(tY zSg4v22sj^#X$3PIaIFCQ4FsH^;F8PMNYsqA0Go?$sVNh2L3k_lkO!F67mEU{As}$w zzk`iKzX)N0e)DXDPkR0(EFvDi@+MI7(djnO9I}+-E7k!e-fdeuuo|@m%eY*y>;Sg{ zw5Kf$|Cny4mZr+>VAy-5YM~@SJ6vhMic7Q$VTZlBa_cwo15Z@>(bx9i_E;mcf#<2b zD7GVlw7UaRo3fVu8zQl5%{xMH%{n&Rhfwr^skb*+D611(E7S?XjW=++m54P^!<7fP zJe6Z3aBAZ^n<8{0X+=EDrS#KV2n0W>*#(MjxXjchXQf&FkoZ57G}USHAJPp#*@C3N z?_HtiirGEu-JSyS=WfvJ*bU@?*dyn@8qZZpveoed`L~0RKXGemxXFP|u!}JfoT)UBBOodz`BnsMjc85o#rY(S^+)4PQneMU^6o=m#`&)t@zCesof+E2Jtbsi#Gl zQ=`uTRmEU5(d4c#(df>?%pO6vKTlOjnV!WdI#6joG;jbMUXD3EN5TFOl}TEAyh3Ab z@dY(WJ57hTzfL9p=UFO`Q&NCw04otW_391o)hQbXb8w{uiHKKq0(JYL#_;gx({al zTm_>$y7*DqE=c>wc#yL(>1V$~&gZ3Kkr1w&0P4TDh2^vl0CE-_2H6`-oq#z%Dz}I_ zKx-H^FstKMO%@Dyr9pla4Cpl>6slWFcc!6hvqRAQC}}uUZw-T0&-)Gqyn!WHp~{E{ zjS4&!u8~OR5T0k6VVazpiK(K1 zvVHfU=dOh|!2)RIW6XIoi}(>G4u%l0|3qq7Oe|NK|{Y$@I-Ls54)Q zklEJ@1UAiEN?$vy@p{|8bYYBXl5ztVWRAfXA5T{S`nezR*gY1`lzOY?p#;T^L#M@W zG1)!Gi&lE7RszBm#zWYI3oqG*gWTklCb6Qp`qCB=yu#pyn-JrEK>jZLr!gtsyAmu5 ztv#zTFc}wMvVoi#xFv3SBBFVJ0usLRg$)QSn!vE>X?7y)R>(sa4kMDWv-CJmmk2z< z%+>I<)kLVI>Bz@q#@P-}gi(<7Nt^||pmf-T-JeOogY0Po>9jvJ9wfN39&gF}V0Q=~ z10hs%62^72lTBW_zv$&6lMMuS@FFl@0JeEh*-3B*f1OnY<_&wv%&Oo?E0$v%kH@m2 zl%aazLu%4fA4)glrpS;f5W(6JYvb__?5u-=>m#mfJX>axuH)^j{50T42yB~*9M#0u zzfG@@4f^&Y%>C^xrE|P_E%+x;?)pf<*c8+|P%LD;t4ZKqUa6AcgLU$W(;;wt8WLFJ zr|JdML?2vD30|l&6t_}xB=P>1cwx&(-ZP=n@1e$K9Zc}qJ0u!RcxMYR@R=B`=ciUH z(L$4Ento8aV_MH5IB+XaYxR}&1!=`4(?o#NtQ0pJX_dibo<#sj3uB6fqUOM}j1aq= zz@?dJ|6H(?xnPaPgx;nhaA|@Usx-u_MqCadDW-bLv=UTj4?dsbF{(=`rbxvT;D3=P zesJo*J3KGF(FG0gNeUX^O3i$z2R7(oe_AqB$(qC2f9%x$50!26XH>tig|HYDp{5}aX+E?m z4Uzb7AtEt7(wwV4l8)z%AZD;M-Yp9XoS92k)|91yF4`l^Q$?mz?b}# zxfpJEFNPb1qf|EpIaIfUT5YoDX>oC5UK+dvVQF5=VFFKK`ODc>wWTm|v$izhApc^~ zBtHU20_>p>fVlBRa3}BnWzemFa{wF#2YKppkl)qkve~Q*0S4n0ml405m6>j;qq|S7 zw&G)G$GI74VrOJ!&I%~iXr>k@&P`@v;4gT)gEY>h;tm0>snP<2-=eKJ26uiXGHGt9 zwct(%&ZBaG2ei$vNMc%ylQM8{c)W9!<-@c1VwxQv`3suHG78 zm%I2Q(iq3_!`ET6qX{O_>oI=>+|7$|aX3uM%S><9K{_7O<@Kg*%CkP4XB#B0{svQo zV(za}iqPi`NVO`q@@;m|b#H{_se{-L8zj!O3q~t%g3*41rJ!)ZSQ7w9EJuVY6femk z)r{rni#J-uhRu+^li(zcceH$|X$HQ;)v;;MspVvt+9+c&1?C@6%}WVUI3yu@==)os z|JNwy#WN(Xlo;ruocS@!^d+$*?@4X=fUZz+aSN_2U@Ys zG*U^$C4~QCCY`<)a1A_sg_|8~<14kV8vI?n9fG&;m<|`cK*Al^0sZfGfE<;?`t@mc zYal>s@4&}9i^;9t4`Jb6&Yg%w-$`s_qKayBC4>)WQ!ko&Q+A+hVJ*W#<9C}( z-r7^|eQDmG2#I(c%d`jG8Dwyy)sG@~X?skym3-4U+iR5p(>WCVD7FEPGiL6A$A$Kx zs}_Ck!5J(wgd!}s{@i;XTst>YmBy_bK9X#qANE7#{64gp8?)GV06T5qHdh`|g^DeI z{^$TS=D@WHo`tF%fNOuxWxXj3X~UW4UU1{bI88&3n zvK`VEu6$UaN|%yfs;EN{j3O4qQ-X&vmwU^UjhLj{9201^2&LFBEOS`tyhP;`r?N*; z>lWcAKJIIPSM#F3jv`yQeFh!cU`jY&hpPY9SUBHwSe3JN~|ZglI0sf0!QY}1)-QX%>QMtldJAd}}g zH|()fKi+x=56Wz>rwV+U_x})~GCNf=uHNb(eUf?Byi2+&x!x|894moT=2LKd>LtW7 zcsG-`Dh>8<+;HFF2$YM+*Y(R_57^5US)kIQ=*??WBOK7c@isdc4affQ!9?xEO*s3d zq(GzXy#n8=9FUCw+iPCb^1La8W?e;qaZ{maHDcFI6J>wzDVkxKKlONrRl?jD*BGu? zIEkL(;k-QiTJkeU-%MK`Cfax%DeXBdQvzJAqH^a5{}{t1P*K@?lz)h4uS9NbwdDF0 zXf-@8wH!z_L^^~9+ybxY36&?{YR<|bw;@pbq!e&q)@_K z6Hlesl zevQPvA0qJ{xKe_p?Y)!5dcKbC`>9HvJRQ;2N7xg>-&M(#ugNclqebpqqv>f{++=6) zg^fp@5qcgEss7W{uOa|F8g#%sfNgEP0QA zI0vunbL5~ij+8L@o8ZmHauSo(;L)zF8rwY|(!3X@bY@f;vKCXh~*@eKQaj?kk6;%2^W%3GT>NB8ekM2{WZH?&tEINKxz0Xd6Oa?L>5nz1Iw4{h3kWL`Wv#amR~ zoKp#Raj*uvg4N!~!2-|>Hw(Ifn(ZqS#N$y(qFn*6J#kfjvP&V%Y_6UYTi$32JYQ zh;4Xbj*EEnN{~a9nSh?yg@H#4p`K>QmBPXn%Yjl|Ia6Gw09+b29cLkI_y5(nkWz{T zM8Ab?JlhjkHI$2`xw`hCkUu>9nCy?WER32kQ4LkRaq$O-)ABzo-o^Q#eH^kN-LW{G z0+qBXI6`1&VPaDD|7Bf!R8>_PmwmW!c^vM&NEC!5LMj&qA%%-vLIgu3BqUQ)6ETKK ztklNGsL+Kba+HTeGj7zi)GV!5MYSeprW^&E97k{{Y?;nXpi`vgAb#K&&uHA@x+lcdY;NHvo+ryI=zgDs0)%#ba@ zk2wDF4U1*jWN9ggZQ0dG=Bp?qb8w36f5C1O;^F|id1dOqnPj)09rQ?`pt!Xwb{kKP zMvs3Ujls2%H>P87iHcZVFQKH3xQ4bMi=(%4bO*OffH&9zxZtHof&^F0((k1o2K6nI z`SPT_AiTBz46$d$q5&UIlU9Q8b}m*;3uxg-r{H;qnpF|RoOANlJ8>~)7V74LX7DlysFioa}DU$rxpl`S^@hE)xv4=6AZN7{$sQW!peUSxJO3a01HG?^pO6&e%%(I}F1@dVr zu-fm2=jW;j_$mu}RATZKu&?%}LVYs@>I2o%PfMzr$BJuYYa0$>*?j(w)Jg2rPsEiX z7Fhz1OG6{7mg|@#zIzhaI<48gb7Vf;E;{uHR%Y9njX~Q z5ahD1m7-(#+ap*JK+P@Gc%Yp=0~x^K_)dMY0&~ns^DK7jJth0zFLCnelL4OhQ?V6{lm6{m^mzOCwe=gS|knIs9{_45Fi5!Us@{#H7rnUH{*+@!DMR-PpDAWn>b)%?~>4c*@^;bKhzE6!>)K6 zHBl7qir^6i=#cf(Azsx^{rm)&V%coR^8~qtAC|?=b;!=iFT)1gkpkQ*#lIwpnIBeP zh(3R0yX>yn1DLMGn~-}3LIiZm$TtUYDY07slf{oM-SzbjV|4oIV1Ycj2s!Sou^?yc zqK+|0V*-Ug^Ksq;wGFkr#_)4RNX52WG>c2-*i7{4<2Yr4Fs-NYuUa|156mw{a$zsZ zoPB3d99YoD#9$dAUFANhTRBTDV!wS!2ZByrf*7v-x+I9`V<^8#=N?&M_2)=V2Zfo(cv3EAmW8aYD z1az`OcHm7NIGsHR(#jl+1l0P9;t>xZs_z{d8x7pCz&3`TAxXin<$d0eg6+i*+=Fri z?zx!Y_m{)-d++k20#@BFWUg7S1}uPMBWeWwSFR3 z*F)%t@8-hM&TdN4O!9)x&2o?GCK{28HdON4+AMw7jS94yv4+Z<598twbz{)f+rbbM z#$gK(?~li%iJ$I;4fy2vB6T8k(6Jcl+yFI& zCLVOOlS+xXc;8|SZLm>*7OXGq&0m5HH$Q^rcur~8XbIj$|L}?aLzEHAVlk)5O70m& z@vv;xcUpQE6fdz~C~zsF0x^Y}fFK&tt8W>akcg!Ty0HaYOc1>wj^exMyJ#xbC8%%5R^v8YK1f-6 z`PePs{o;{=`>h(7mFMYRtmI3!;x-gh&;Q=Ao0tCn%+q~%H4vXeg4-2egRq{@b#E>r zc!kNy|6mPVF1|o6_b}fVTE;}_>Us=Wg+2y#)xTxN=^eHRo^lkk+6N?_by1+jH-x{! zSjhGosGFAKt@bdldRAQ{%Vk>CrM0lmx@55y?5!vsxdN(BzovK{yk`YoZZ-^2-hyeB z%*A_a$K$}9`G&+een@9=wbvovk|&_cMZs2jlR{OovC`!D5zBSlbH!vVm|bF)^!8X# zqrcT7<0$=AY6`Dk3Ga==CS!>2W0yztc!J86!mq6Yu;!Y{e(x)oi$warTMgY`uj@`K z*qrZ8_6G3U346HHTHn3*hBPzCT(xU3E`T(DbDX*<{ViLg-lP0&R0t0^VSkc0^w~pr z#9Gy@+=1=&=Y!Y^Vqyv2Rs!!|tHvrFO2`WVE|9-8I+s^b!66N3p>vO^b9a7hcdGt% zxR)EB!WqkcH}SG6ld$U*+}PB^6?)sd_60!jmUe!2Eac8M?$y( zud7t43fGOt5y-6!t40{X>C&EQTQ^5X*29fr=5n)gBHh+MuUyxV{3WO7xqXL zK+{k~|Fodu@6deh^{Hh_Q;gZ>SJw@o4tSJZXX;d?ms5s4duu(;+ ztVU#-JBC`Z)W26NhG#UYC>Q+e0)^{t?t6}=sU}!|J02&xMul?{xs`-u14V?bV4kxX;!?M8 z+U%FaxwiSomsscBlyXZ$K-F@PDgKz6)6AMoVOK--VDw17G>>qOLRWj78A1zAh!~dWwNCV zaW-ii_*SpC;4`VdRgF;UJVyFLnW8%%&~)Cg#~#Fq%@tjKzb%LwYzwvp PN5398DtQ_f)JOdvp7mYe delta 50202 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 diff --git a/packages/cli/cli/src/commands/generate-fdr/generateFdrApiDefinitionForWorkspaces.ts b/packages/cli/cli/src/commands/generate-fdr/generateFdrApiDefinitionForWorkspaces.ts index 72eb4f6a6c8..0b28a9791d8 100644 --- a/packages/cli/cli/src/commands/generate-fdr/generateFdrApiDefinitionForWorkspaces.ts +++ b/packages/cli/cli/src/commands/generate-fdr/generateFdrApiDefinitionForWorkspaces.ts @@ -38,8 +38,7 @@ export async function generateFdrApiDefinitionForWorkspaces({ const apiDefinition = convertIrToFdrApi({ ir, - snippetsConfig: {}, - navigation: undefined + snippetsConfig: {} }); const resolvedOutputFilePath = path.resolve(outputFilepath); diff --git a/packages/cli/cli/src/commands/register/registerWorkspacesV2.ts b/packages/cli/cli/src/commands/register/registerWorkspacesV2.ts index 0de8b7bc2a3..268c13b8b08 100644 --- a/packages/cli/cli/src/commands/register/registerWorkspacesV2.ts +++ b/packages/cli/cli/src/commands/register/registerWorkspacesV2.ts @@ -25,8 +25,7 @@ export async function registerWorkspacesV2({ context, token, audiences: { type: "all" }, - snippetsConfig: {}, - navigation: undefined + snippetsConfig: {} }); context.logger.info(chalk.green("Registered API")); } diff --git a/packages/cli/configuration/fern/definition/docs.yml b/packages/cli/configuration/fern/definition/docs.yml index 0c7ad299bce..679d4945027 100644 --- a/packages/cli/configuration/fern/definition/docs.yml +++ b/packages/cli/configuration/fern/definition/docs.yml @@ -369,37 +369,62 @@ types: type: optional docs: Defaults to false snippets: optional - layout: - type: optional - docs: | - If `layout` is set to `sidebar`, the API section will render with a sidebar. - If `layout` is set to `full`, the API section will render without a sidebar. - - ApiSectionLayout: - docs: | + summary: + type: optional + docs: | + Relative path to the markdown file. This summary is displayed at the top of the API section. + layout: + type: optional + docs: | + Advanced usage: when specified, this object will be used to customize the order that your API endpoints are displayed in the docs site, including subpackages, and additional markdown pages (to be rendered in between API endpoints). If not specified, the order will be inferred from the OpenAPI Spec or Fern Definition. + + ApiNavigationItem: + docs: | Use the `layout` object to customize the order that your API endpoints are displayed in the docs site. - type: unknown - examples: + discriminated: false + union: + - type: string + docs: | + This should be either an endpoint, websocket, webhook, or subpackage ID + - type: map + docs: | + Keyed by subpackage ID, this object allows you to group endpoints and pages together. + - type: PageConfiguration + docs: | + This should be a markdown file that will be displayed in the API section. + + ApiNavigationItems: + type: list + examples: - name: Ordering Groups - value: + value: - users # users endpoints will be displayed first - roles - permissions - name: Ordering Endpoints - value: - - roles - - get - - create - - update + value: + - roles: + - get + - create + - update + - users: + - get + - create + - update + - permissions: + - get + - create + - update + - name: Ordering Groups and Pages + value: - users - - get - - create - - update + - roles: + - get + - create + - ./pages/inner-page.mdx + - update - permissions - - get - - create - - update LinkConfiguration: properties: @@ -421,12 +446,12 @@ types: The primary accent color is used for buttons, links, and other interactive elements. @default: #818CF8 - + accentPrimary: type: optional name: accentPrimaryDeprecated availability: deprecated - docs: | + docs: | Use `accent-primary` instead. background: diff --git a/packages/cli/configuration/package.json b/packages/cli/configuration/package.json index 46c59e1b469..979caaa5e68 100644 --- a/packages/cli/configuration/package.json +++ b/packages/cli/configuration/package.json @@ -29,7 +29,7 @@ }, "dependencies": { "@fern-api/core-utils": "workspace:*", - "@fern-api/fdr-sdk": "^0.73.0-d986da306", + "@fern-api/fdr-sdk": "0.73.1-9d67ec828", "@fern-api/fs-utils": "workspace:*", "@fern-api/task-context": "workspace:*", "@fern-fern/fiddle-sdk": "^0.0.503", diff --git a/packages/cli/configuration/src/docs-yml/ParsedDocsConfiguration.ts b/packages/cli/configuration/src/docs-yml/ParsedDocsConfiguration.ts index 380b964e45c..60afcb9fe5e 100644 --- a/packages/cli/configuration/src/docs-yml/ParsedDocsConfiguration.ts +++ b/packages/cli/configuration/src/docs-yml/ParsedDocsConfiguration.ts @@ -1,6 +1,5 @@ import { DocsV1Write } from "@fern-api/fdr-sdk"; import { AbsoluteFilePath, RelativeFilePath } from "@fern-api/fs-utils"; -import { z, ZodType } from "zod"; import { Audiences } from "../commons"; import { WithoutQuestionMarks } from "../commons/WithoutQuestionMarks"; import { DocsInstances, TabConfig, VersionAvailability } from "./schemas"; @@ -157,7 +156,8 @@ export declare namespace DocsNavigationItem { audiences: Audiences; showErrors: boolean; snippetsConfiguration: SnippetsConfiguration | undefined; - navigation: APINavigationSchema | undefined; + summaryAbsolutePath: AbsoluteFilePath | undefined; + navigation: ParsedApiNavigationItem[]; } export interface Link { @@ -174,27 +174,21 @@ export declare namespace DocsNavigationItem { } } -// eslint-disable-next-line @typescript-eslint/consistent-indexed-object-style -export interface ApiNavigationGroup { - [key: string]: ApiNavigationItem[]; -} -export const ApiNavigationGroup: ZodType = z.lazy(() => z.record(z.array(ApiNavigationItem))); - -export const ApiNavigationItem = z.union([z.string(), ApiNavigationGroup]); -export type ApiNavigationItem = z.infer; - -/** - * NavigationSchema is a recursive schema that can be either a record, - * a list of records, or a list of strings where the strings are endpoint ids - * and the records are groups of endpoint ids for a subpackage. - * - * @example - * - groupA - * - groupB: - * - methodA - * - methodB - * - groupC: - * - methodC - */ -export const APINavigationSchema = z.array(ApiNavigationItem); -export type APINavigationSchema = z.infer; +export declare namespace ParsedApiNavigationItem { + export interface Subpackage { + type: "subpackage"; + subpackageId: string; + summaryAbsolutePath: AbsoluteFilePath | undefined; + items: ParsedApiNavigationItem[]; + } + + export interface Item { + type: "item"; + value: string; // this could be either an endpoint or subpackage. + } +} + +export type ParsedApiNavigationItem = + | ParsedApiNavigationItem.Item + | ParsedApiNavigationItem.Subpackage + | DocsNavigationItem.Page; diff --git a/packages/cli/configuration/src/docs-yml/getAllPages.ts b/packages/cli/configuration/src/docs-yml/getAllPages.ts index 33a3c2dd4c8..5f8aa8d4c2b 100644 --- a/packages/cli/configuration/src/docs-yml/getAllPages.ts +++ b/packages/cli/configuration/src/docs-yml/getAllPages.ts @@ -1,7 +1,7 @@ import { assertNever } from "@fern-api/core-utils"; import { AbsoluteFilePath, RelativeFilePath, relativize } from "@fern-api/fs-utils"; import { readFile } from "fs/promises"; -import { DocsNavigationConfiguration, DocsNavigationItem } from "./ParsedDocsConfiguration"; +import { DocsNavigationConfiguration, DocsNavigationItem, ParsedApiNavigationItem } from "./ParsedDocsConfiguration"; export async function getAllPages({ navigation, @@ -63,7 +63,21 @@ export async function getAllPagesFromNavigationItem({ absolutePathToFernFolder: AbsoluteFilePath; }): Promise> { switch (item.type) { - case "apiSection": + case "apiSection": { + const toRet = combineMaps( + await Promise.all( + item.navigation.map((apiNavigation) => + getAllPagesFromApiNavigationItem({ item: apiNavigation, absolutePathToFernFolder }) + ) + ) + ); + if (item.summaryAbsolutePath != null) { + toRet[await relativize(absolutePathToFernFolder, item.summaryAbsolutePath)] = ( + await readFile(item.summaryAbsolutePath) + ).toString(); + } + return toRet; + } case "link": return {}; case "page": @@ -88,3 +102,36 @@ export async function getAllPagesFromNavigationItem({ function combineMaps(maps: Record[]) { return maps.reduce((acc, record) => ({ ...acc, ...record }), {}); } + +async function getAllPagesFromApiNavigationItem({ + item, + absolutePathToFernFolder +}: { + item: ParsedApiNavigationItem; + absolutePathToFernFolder: AbsoluteFilePath; +}): Promise> { + if (item.type === "page") { + return { + [await relativize(absolutePathToFernFolder, item.absolutePath)]: ( + await readFile(item.absolutePath) + ).toString() + }; + } else if (item.type === "subpackage") { + const toRet = combineMaps( + await Promise.all( + item.items.map(async (subItem) => { + return await getAllPagesFromApiNavigationItem({ item: subItem, absolutePathToFernFolder }); + }) + ) + ); + + if (item.summaryAbsolutePath != null) { + toRet[await relativize(absolutePathToFernFolder, item.summaryAbsolutePath)] = ( + await readFile(item.summaryAbsolutePath) + ).toString(); + } + + return toRet; + } + return {}; +} diff --git a/packages/cli/configuration/src/docs-yml/parseDocsConfiguration.ts b/packages/cli/configuration/src/docs-yml/parseDocsConfiguration.ts index ce7cb58b10e..cfb443ef414 100644 --- a/packages/cli/configuration/src/docs-yml/parseDocsConfiguration.ts +++ b/packages/cli/configuration/src/docs-yml/parseDocsConfiguration.ts @@ -1,4 +1,4 @@ -import { assertNever } from "@fern-api/core-utils"; +import { assertNever, isPlainObject } from "@fern-api/core-utils"; import { DocsV1Write } from "@fern-api/fdr-sdk"; import { AbsoluteFilePath, dirname, resolve } from "@fern-api/fs-utils"; import { TaskContext } from "@fern-api/task-context"; @@ -9,12 +9,12 @@ import { convertColorsConfiguration } from "./convertColorsConfiguration"; import { getAllPages } from "./getAllPages"; import { AbsoluteJsFileConfig, - APINavigationSchema, DocsNavigationConfiguration, DocsNavigationItem, FontConfig, ImageReference, JavascriptConfig, + ParsedApiNavigationItem, ParsedDocsConfiguration, TabbedDocsNavigation, TypographyConfig, @@ -539,15 +539,6 @@ async function convertNavigationItem({ }; } if (isRawApiSectionConfig(rawConfig)) { - let navigation: APINavigationSchema | undefined = undefined; - if (rawConfig.layout != null) { - const parseResponse = APINavigationSchema.safeParse(rawConfig.layout); - if (parseResponse.success) { - navigation = parseResponse.data; - } else { - context.logger.error(`Failed to parse API layout configuration: ${parseResponse.error.message}`); - } - } return { type: "apiSection", title: rawConfig.api, @@ -559,7 +550,14 @@ async function convertNavigationItem({ rawConfig.snippets != null ? convertSnippetsConfiguration({ rawConfig: rawConfig.snippets }) : undefined, - navigation + navigation: rawConfig.layout?.flatMap((item) => parseApiNavigationItem(item, absolutePathToConfig)) ?? [], + summaryAbsolutePath: + rawConfig.summary != null + ? resolveFilepath({ + absolutePath: absolutePathToConfig, + rawUnresolvedFilepath: rawConfig.summary + }) + : undefined }; } if (isRawLinkConfig(rawConfig)) { @@ -572,6 +570,44 @@ async function convertNavigationItem({ assertNever(rawConfig); } +function parseApiNavigationItem( + item: RawDocs.ApiNavigationItem, + absolutePathToConfig: AbsoluteFilePath +): ParsedApiNavigationItem[] { + if (typeof item === "string") { + return [ + { + type: "item", + value: item + } + ]; + } + + // eslint-disable-next-line @typescript-eslint/no-explicit-any + if (isRawPageConfig(item)) { + return [ + { + type: "page", + title: item.page, + absolutePath: resolveFilepath({ + absolutePath: absolutePathToConfig, + rawUnresolvedFilepath: item.path + }), + slug: item.slug ?? undefined + } + ]; + } + + return Object.entries(item).map(([key, values]): ParsedApiNavigationItem.Subpackage => { + return { + type: "subpackage", + subpackageId: key, + summaryAbsolutePath: undefined, // TODO: implement subpackage summary page + items: values.flatMap((value) => parseApiNavigationItem(value, absolutePathToConfig)) + }; + }); +} + function convertSnippetsConfiguration({ rawConfig }: { @@ -585,9 +621,8 @@ function convertSnippetsConfiguration({ }; } -function isRawPageConfig(item: RawDocs.NavigationItem): item is RawDocs.PageConfiguration { - // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition - return (item as RawDocs.PageConfiguration).page != null; +function isRawPageConfig(item: unknown): item is RawDocs.PageConfiguration { + return isPlainObject(item) && typeof item.page === "string" && typeof item.path === "string"; } function isRawSectionConfig(item: RawDocs.NavigationItem): item is RawDocs.SectionConfiguration { diff --git a/packages/cli/configuration/src/docs-yml/schemas/sdk/api/resources/docs/types/ApiNavigationItem.ts b/packages/cli/configuration/src/docs-yml/schemas/sdk/api/resources/docs/types/ApiNavigationItem.ts new file mode 100644 index 00000000000..6168193cde7 --- /dev/null +++ b/packages/cli/configuration/src/docs-yml/schemas/sdk/api/resources/docs/types/ApiNavigationItem.ts @@ -0,0 +1,23 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as FernDocsConfig from "../../.."; + +/** + * Use the `layout` object to customize the order that your API endpoints + * are displayed in the docs site. + */ +export type ApiNavigationItem = + /** + * This should be either an endpoint, websocket, webhook, or subpackage ID + * */ + | string + /** + * Keyed by subpackage ID, this object allows you to group endpoints and pages together. + * */ + | Record + /** + * This should be a markdown file that will be displayed in the API section. + * */ + | FernDocsConfig.PageConfiguration; diff --git a/packages/cli/configuration/src/docs-yml/schemas/sdk/api/resources/docs/types/ApiNavigationItems.ts b/packages/cli/configuration/src/docs-yml/schemas/sdk/api/resources/docs/types/ApiNavigationItems.ts new file mode 100644 index 00000000000..15498b6f200 --- /dev/null +++ b/packages/cli/configuration/src/docs-yml/schemas/sdk/api/resources/docs/types/ApiNavigationItems.ts @@ -0,0 +1,17 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as FernDocsConfig from "../../.."; + +/** + * @example + * [] + * + * @example + * [] + * + * @example + * [] + */ +export type ApiNavigationItems = FernDocsConfig.ApiNavigationItem[]; diff --git a/packages/cli/configuration/src/docs-yml/schemas/sdk/api/resources/docs/types/ApiSectionConfiguration.ts b/packages/cli/configuration/src/docs-yml/schemas/sdk/api/resources/docs/types/ApiSectionConfiguration.ts index fdae1cfe600..36e61ff1887 100644 --- a/packages/cli/configuration/src/docs-yml/schemas/sdk/api/resources/docs/types/ApiSectionConfiguration.ts +++ b/packages/cli/configuration/src/docs-yml/schemas/sdk/api/resources/docs/types/ApiSectionConfiguration.ts @@ -12,9 +12,8 @@ export interface ApiSectionConfiguration { /** Defaults to false */ displayErrors?: boolean; snippets?: FernDocsConfig.SnippetsConfiguration; - /** - * If `layout` is set to `sidebar`, the API section will render with a sidebar. - * If `layout` is set to `full`, the API section will render without a sidebar. - */ - layout?: FernDocsConfig.ApiSectionLayout | undefined; + /** Relative path to the markdown file. This summary is displayed at the top of the API section. */ + summary?: string; + /** Advanced usage: when specified, this object will be used to customize the order that your API endpoints are displayed in the docs site, including subpackages, and additional markdown pages (to be rendered in between API endpoints). If not specified, the order will be inferred from the OpenAPI Spec or Fern Definition. */ + layout?: FernDocsConfig.ApiNavigationItems; } diff --git a/packages/cli/configuration/src/docs-yml/schemas/sdk/api/resources/docs/types/ApiSectionLayout.ts b/packages/cli/configuration/src/docs-yml/schemas/sdk/api/resources/docs/types/ApiSectionLayout.ts deleted file mode 100644 index 4dd2b6d98d1..00000000000 --- a/packages/cli/configuration/src/docs-yml/schemas/sdk/api/resources/docs/types/ApiSectionLayout.ts +++ /dev/null @@ -1,23 +0,0 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ - -/** - * Use the `layout` object to customize the order that your API endpoints - * are displayed in the docs site. - * - * @example - * [ - * "users", - * "roles", - * "permissions" - * ] - * - * @example - * [ - * "roles - get - create - update", - * "users - get - create - update", - * "permissions - get - create - update" - * ] - */ -export type ApiSectionLayout = unknown; diff --git a/packages/cli/configuration/src/docs-yml/schemas/sdk/api/resources/docs/types/index.ts b/packages/cli/configuration/src/docs-yml/schemas/sdk/api/resources/docs/types/index.ts index 6a50405e1b0..3f3fbee422f 100644 --- a/packages/cli/configuration/src/docs-yml/schemas/sdk/api/resources/docs/types/index.ts +++ b/packages/cli/configuration/src/docs-yml/schemas/sdk/api/resources/docs/types/index.ts @@ -29,7 +29,8 @@ export * from "./FontConfigVariant"; export * from "./PageConfiguration"; export * from "./SectionConfiguration"; export * from "./ApiSectionConfiguration"; -export * from "./ApiSectionLayout"; +export * from "./ApiNavigationItem"; +export * from "./ApiNavigationItems"; export * from "./LinkConfiguration"; export * from "./SnippetsConfiguration"; export * from "./ColorsConfiguration"; diff --git a/packages/cli/configuration/src/docs-yml/schemas/sdk/serialization/resources/docs/types/ApiNavigationItem.ts b/packages/cli/configuration/src/docs-yml/schemas/sdk/serialization/resources/docs/types/ApiNavigationItem.ts new file mode 100644 index 00000000000..b92ee90a459 --- /dev/null +++ b/packages/cli/configuration/src/docs-yml/schemas/sdk/serialization/resources/docs/types/ApiNavigationItem.ts @@ -0,0 +1,23 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as serializers from "../../.."; +import * as FernDocsConfig from "../../../../api"; +import * as core from "../../../../core"; + +export const ApiNavigationItem: core.serialization.Schema< + serializers.ApiNavigationItem.Raw, + FernDocsConfig.ApiNavigationItem +> = core.serialization.undiscriminatedUnion([ + core.serialization.string(), + core.serialization.record( + core.serialization.string(), + core.serialization.lazy(async () => (await import("../../..")).ApiNavigationItems) + ), + core.serialization.lazyObject(async () => (await import("../../..")).PageConfiguration), +]); + +export declare namespace ApiNavigationItem { + type Raw = string | Record | serializers.PageConfiguration.Raw; +} diff --git a/packages/cli/configuration/src/docs-yml/schemas/sdk/serialization/resources/docs/types/ApiNavigationItems.ts b/packages/cli/configuration/src/docs-yml/schemas/sdk/serialization/resources/docs/types/ApiNavigationItems.ts new file mode 100644 index 00000000000..f9b87a0ee95 --- /dev/null +++ b/packages/cli/configuration/src/docs-yml/schemas/sdk/serialization/resources/docs/types/ApiNavigationItems.ts @@ -0,0 +1,16 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as serializers from "../../.."; +import * as FernDocsConfig from "../../../../api"; +import * as core from "../../../../core"; + +export const ApiNavigationItems: core.serialization.Schema< + serializers.ApiNavigationItems.Raw, + FernDocsConfig.ApiNavigationItems +> = core.serialization.list(core.serialization.lazy(async () => (await import("../../..")).ApiNavigationItem)); + +export declare namespace ApiNavigationItems { + type Raw = serializers.ApiNavigationItem.Raw[]; +} diff --git a/packages/cli/configuration/src/docs-yml/schemas/sdk/serialization/resources/docs/types/ApiSectionConfiguration.ts b/packages/cli/configuration/src/docs-yml/schemas/sdk/serialization/resources/docs/types/ApiSectionConfiguration.ts index 07c300a92f6..30c5fb6c2bb 100644 --- a/packages/cli/configuration/src/docs-yml/schemas/sdk/serialization/resources/docs/types/ApiSectionConfiguration.ts +++ b/packages/cli/configuration/src/docs-yml/schemas/sdk/serialization/resources/docs/types/ApiSectionConfiguration.ts @@ -15,7 +15,8 @@ export const ApiSectionConfiguration: core.serialization.ObjectSchema< audiences: core.serialization.list(core.serialization.string()).optional(), displayErrors: core.serialization.property("display-errors", core.serialization.boolean().optional()), snippets: core.serialization.lazyObject(async () => (await import("../../..")).SnippetsConfiguration).optional(), - layout: core.serialization.lazy(async () => (await import("../../..")).ApiSectionLayout).optional(), + summary: core.serialization.string().optional(), + layout: core.serialization.lazy(async () => (await import("../../..")).ApiNavigationItems).optional(), }); export declare namespace ApiSectionConfiguration { @@ -25,6 +26,7 @@ export declare namespace ApiSectionConfiguration { audiences?: string[] | null; "display-errors"?: boolean | null; snippets?: serializers.SnippetsConfiguration.Raw | null; - layout?: (serializers.ApiSectionLayout.Raw | undefined) | null; + summary?: string | null; + layout?: serializers.ApiNavigationItems.Raw | null; } } diff --git a/packages/cli/configuration/src/docs-yml/schemas/sdk/serialization/resources/docs/types/ApiSectionLayout.ts b/packages/cli/configuration/src/docs-yml/schemas/sdk/serialization/resources/docs/types/ApiSectionLayout.ts deleted file mode 100644 index b1b631b0f81..00000000000 --- a/packages/cli/configuration/src/docs-yml/schemas/sdk/serialization/resources/docs/types/ApiSectionLayout.ts +++ /dev/null @@ -1,16 +0,0 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ - -import * as serializers from "../../.."; -import * as FernDocsConfig from "../../../../api"; -import * as core from "../../../../core"; - -export const ApiSectionLayout: core.serialization.Schema< - serializers.ApiSectionLayout.Raw, - FernDocsConfig.ApiSectionLayout -> = core.serialization.unknown(); - -export declare namespace ApiSectionLayout { - type Raw = unknown; -} diff --git a/packages/cli/configuration/src/docs-yml/schemas/sdk/serialization/resources/docs/types/index.ts b/packages/cli/configuration/src/docs-yml/schemas/sdk/serialization/resources/docs/types/index.ts index 6a50405e1b0..3f3fbee422f 100644 --- a/packages/cli/configuration/src/docs-yml/schemas/sdk/serialization/resources/docs/types/index.ts +++ b/packages/cli/configuration/src/docs-yml/schemas/sdk/serialization/resources/docs/types/index.ts @@ -29,7 +29,8 @@ export * from "./FontConfigVariant"; export * from "./PageConfiguration"; export * from "./SectionConfiguration"; export * from "./ApiSectionConfiguration"; -export * from "./ApiSectionLayout"; +export * from "./ApiNavigationItem"; +export * from "./ApiNavigationItems"; export * from "./LinkConfiguration"; export * from "./SnippetsConfiguration"; export * from "./ColorsConfiguration"; diff --git a/packages/cli/docs-preview/package.json b/packages/cli/docs-preview/package.json index efd45f9c4ab..baced6bd131 100644 --- a/packages/cli/docs-preview/package.json +++ b/packages/cli/docs-preview/package.json @@ -29,7 +29,7 @@ "dependencies": { "@fern-api/configuration": "workspace:*", "@fern-api/core-utils": "workspace:*", - "@fern-api/fdr-sdk": "^0.73.0-d986da306", + "@fern-api/fdr-sdk": "0.73.1-9d67ec828", "@fern-api/fs-utils": "workspace:*", "@fern-api/ir-generator": "workspace:*", "@fern-api/register": "workspace:*", diff --git a/packages/cli/docs-preview/src/previewDocs.ts b/packages/cli/docs-preview/src/previewDocs.ts index 43dd9e10707..f6054e0b433 100644 --- a/packages/cli/docs-preview/src/previewDocs.ts +++ b/packages/cli/docs-preview/src/previewDocs.ts @@ -96,8 +96,7 @@ class ReferencedAPICollector { }); const apiDefinition = convertIrToFdrApi({ ir, - snippetsConfig: {}, - navigation: api.navigation + snippetsConfig: {} }); const dbApiDefinition = convertAPIDefinitionToDb( apiDefinition, diff --git a/packages/cli/generation/remote-generation/remote-workspace-runner/package.json b/packages/cli/generation/remote-generation/remote-workspace-runner/package.json index c5f9afb5ae2..8be48ed0cd9 100644 --- a/packages/cli/generation/remote-generation/remote-workspace-runner/package.json +++ b/packages/cli/generation/remote-generation/remote-workspace-runner/package.json @@ -32,7 +32,7 @@ "@fern-api/core": "workspace:*", "@fern-api/core-utils": "workspace:*", "@fern-api/docs-validator": "workspace:*", - "@fern-api/fdr-sdk": "^0.73.0-d986da306", + "@fern-api/fdr-sdk": "0.73.1-9d67ec828", "@fern-api/fs-utils": "workspace:*", "@fern-api/ir-generator": "workspace:*", "@fern-api/ir-migrations": "workspace:*", diff --git a/packages/cli/generation/remote-generation/remote-workspace-runner/src/convertIrToNavigation.ts b/packages/cli/generation/remote-generation/remote-workspace-runner/src/convertIrToNavigation.ts new file mode 100644 index 00000000000..ca4fad23a20 --- /dev/null +++ b/packages/cli/generation/remote-generation/remote-workspace-runner/src/convertIrToNavigation.ts @@ -0,0 +1,164 @@ +import { docsYml } from "@fern-api/configuration"; +import { DocsV1Write } from "@fern-api/fdr-sdk"; +import { AbsoluteFilePath, dirname, relative } from "@fern-api/fs-utils"; +import { FernIr, IntermediateRepresentation } from "@fern-api/ir-sdk"; + +export function convertIrToNavigation( + ir: IntermediateRepresentation, + rootSummaryAbsolutePath: AbsoluteFilePath | undefined, + navigation: docsYml.ParsedApiNavigationItem[] | undefined, + absoluteFilepathToDocsConfig: AbsoluteFilePath, + fullSlugs: Record +): DocsV1Write.ApiNavigationConfigRoot | undefined { + if (navigation == null) { + return undefined; + } + + const defaultRoot = convertIrToDefaultNavigationConfigRoot(ir); + + const items = visitAndSortNavigationSchema( + navigation, + defaultRoot.items, + ir, + absoluteFilepathToDocsConfig, + fullSlugs + ); + + return { + items, + summaryPageId: + rootSummaryAbsolutePath == null + ? undefined + : relative(dirname(absoluteFilepathToDocsConfig), rootSummaryAbsolutePath) + }; +} + +export function convertIrToDefaultNavigationConfigRoot( + ir: IntermediateRepresentation +): DocsV1Write.ApiNavigationConfigRoot { + const items: DocsV1Write.ApiNavigationConfigItem[] = convertPackageToNavigationConfigItems(ir.rootPackage, ir); + return { items }; +} + +function convertPackageToNavigationConfigItems( + package_: FernIr.Package, + ir: IntermediateRepresentation +): DocsV1Write.ApiNavigationConfigItem[] { + if (package_.navigationConfig != null) { + const pointsToPackage = ir.subpackages[package_.navigationConfig.pointsTo]; + if (pointsToPackage != null) { + return convertPackageToNavigationConfigItems(pointsToPackage, ir); + } + } + + const items: DocsV1Write.ApiNavigationConfigItem[] = []; + + if (package_.service != null) { + const httpService = ir.services[package_.service]; + + httpService?.endpoints.forEach((endpoint) => { + items.push({ type: "endpointId", value: endpoint.name.originalName }); + }); + } + + if (package_.websocket != null) { + const channel = ir.websocketChannels?.[package_.websocket]; + if (channel != null) { + items.push({ type: "websocketId", value: channel.name.originalName }); + } + } + + if (package_.webhooks != null) { + const webhooks = ir.webhookGroups[package_.webhooks]; + + webhooks?.forEach((webhook) => { + items.push({ type: "webhookId", value: webhook.name.originalName }); + }); + } + + package_.subpackages.forEach((subpackageId) => { + const subpackage = ir.subpackages[subpackageId]; + + if (subpackage != null) { + items.push({ + type: "subpackage", + subpackageId, + items: convertPackageToNavigationConfigItems(subpackage, ir) + }); + } + }); + + return items; +} + +function createItemMatcher(key: string, ir: IntermediateRepresentation) { + return function (item: DocsV1Write.ApiNavigationConfigItem): boolean { + if (item.type === "subpackage") { + // subpackages are keyed by a generated ID, so we need to look up the original name + return ir.subpackages[item.subpackageId]?.name.originalName === key; + } else if (item.type === "page") { + return false; + } else { + // endpoints, webhooks, and websockets are keyed by their original name + return key === item.value; + } + }; +} + +function visitAndSortNavigationSchema( + navigationItems: docsYml.ParsedApiNavigationItem[], + defaultItems: DocsV1Write.ApiNavigationConfigItem[], + ir: IntermediateRepresentation, + absoluteFilepathToDocsConfig: AbsoluteFilePath, + fullSlugs: Record +): DocsV1Write.ApiNavigationConfigItem[] { + const items: DocsV1Write.ApiNavigationConfigItem[] = []; + for (const navigationItem of navigationItems) { + if (navigationItem.type === "item") { + const foundItem = defaultItems.find(createItemMatcher(navigationItem.value, ir)); + + if (foundItem != null && foundItem.type !== "subpackage") { + items.push(foundItem); + } else if (foundItem != null) { + items.push({ + type: "subpackage", + subpackageId: foundItem.subpackageId, + items: [] + }); + } + } else if (navigationItem.type === "page") { + items.push({ + type: "page", + id: relative(dirname(absoluteFilepathToDocsConfig), navigationItem.absolutePath), + title: navigationItem.title, + icon: undefined, + hidden: undefined, + urlSlugOverride: navigationItem.slug, + fullSlug: fullSlugs[navigationItem.absolutePath]?.fullSlug?.split("/") + }); + } else { + // item must be a collection of subpackages + const foundItem = defaultItems.find(createItemMatcher(navigationItem.subpackageId, ir)); + + if (foundItem != null && foundItem.type === "subpackage") { + items.push({ + type: "subpackage", + subpackageId: foundItem.subpackageId, + summaryPageId: + navigationItem.summaryAbsolutePath == null + ? undefined + : relative(dirname(absoluteFilepathToDocsConfig), navigationItem.summaryAbsolutePath), + items: visitAndSortNavigationSchema( + navigationItem.items, + foundItem.items, + ir, + absoluteFilepathToDocsConfig, + fullSlugs + ) + }); + } + } + } + + return items; +} diff --git a/packages/cli/generation/remote-generation/remote-workspace-runner/src/publishDocs.ts b/packages/cli/generation/remote-generation/remote-workspace-runner/src/publishDocs.ts index 80d09938529..aabfe9b4bc6 100644 --- a/packages/cli/generation/remote-generation/remote-workspace-runner/src/publishDocs.ts +++ b/packages/cli/generation/remote-generation/remote-workspace-runner/src/publishDocs.ts @@ -16,6 +16,7 @@ import { imageSize } from "image-size"; import * as mime from "mime-types"; import terminalLink from "terminal-link"; import { promisify } from "util"; +import { convertIrToNavigation } from "./convertIrToNavigation"; export async function publishDocs({ token, @@ -316,7 +317,7 @@ async function convertDocsConfiguration({ version, fullSlugs }); - const config: Omit, "logo" | "colors" | "typography" | "colorsV2"> = { + const config: ConvertedDocsConfiguration["config"] = { title: parsedDocsConfig.title, // deprecated, use colorsV3 instead of logoV2 logoV2: undefined, @@ -893,13 +894,13 @@ async function convertNavigationItem({ } case "apiSection": { const workspace = getFernWorkspaceForApiSection({ apiSection: item, fernWorkspaces }); - const apiDefinitionId = await registerApi({ + const { id: apiDefinitionId, ir } = await registerApi({ organization, workspace, context, token, audiences: item.audiences, - navigation: item.navigation, + // navigation: item.navigation, snippetsConfig: convertDocsSnippetsConfigurationToFdr({ snippetsConfiguration: item.snippetsConfiguration ?? { python: undefined, @@ -932,7 +933,14 @@ async function convertNavigationItem({ }; }) } - : undefined + : undefined, + navigation: convertIrToNavigation( + ir, + item.summaryAbsolutePath, + item.navigation, + parsedDocsConfig.absoluteFilepath, + fullSlugs + ) }; break; } diff --git a/packages/cli/register/package.json b/packages/cli/register/package.json index fcd0a03e718..8402a986f0b 100644 --- a/packages/cli/register/package.json +++ b/packages/cli/register/package.json @@ -31,7 +31,7 @@ "@fern-api/configuration": "workspace:*", "@fern-api/core": "workspace:*", "@fern-api/core-utils": "workspace:*", - "@fern-api/fdr-sdk": "^0.73.0-d986da306", + "@fern-api/fdr-sdk": "0.73.1-9d67ec828", "@fern-api/ir-generator": "workspace:*", "@fern-api/ir-sdk": "workspace:*", "@fern-api/task-context": "workspace:*", diff --git a/packages/cli/register/src/index.ts b/packages/cli/register/src/index.ts index ca1e0a3d93c..b5ad83795f8 100644 --- a/packages/cli/register/src/index.ts +++ b/packages/cli/register/src/index.ts @@ -1,3 +1,2 @@ export { convertIrToFdrApi } from "./ir-to-fdr-converter/convertIrToFdrApi"; -export { convertIrToDefaultNavigationConfigRoot } from "./ir-to-fdr-converter/convertIrToNavigation"; export { registerApi } from "./registerApi"; diff --git a/packages/cli/register/src/ir-to-fdr-converter/convertIrToFdrApi.ts b/packages/cli/register/src/ir-to-fdr-converter/convertIrToFdrApi.ts index 196140c21c7..828de120cb5 100644 --- a/packages/cli/register/src/ir-to-fdr-converter/convertIrToFdrApi.ts +++ b/packages/cli/register/src/ir-to-fdr-converter/convertIrToFdrApi.ts @@ -1,22 +1,17 @@ -import { docsYml } from "@fern-api/configuration"; import { entries } from "@fern-api/core-utils"; import { APIV1Write } from "@fern-api/fdr-sdk"; import { IntermediateRepresentation } from "@fern-api/ir-sdk"; -import { convertIrToNavigation } from "./convertIrToNavigation"; import { convertIrAvailability, convertPackage } from "./convertPackage"; import { convertTypeReference, convertTypeShape } from "./convertTypeShape"; import { convertAuth } from "./covertAuth"; export function convertIrToFdrApi({ ir, - snippetsConfig, - navigation + snippetsConfig }: { ir: IntermediateRepresentation; snippetsConfig: APIV1Write.SnippetsConfig; - navigation: docsYml.APINavigationSchema | undefined; }): APIV1Write.ApiDefinition { - const convertedNavigation = convertIrToNavigation(ir, navigation); const fdrApi: APIV1Write.ApiDefinition = { types: {}, subpackages: {}, @@ -29,8 +24,7 @@ export function convertIrToFdrApi({ key: header.name.wireValue, type: convertTypeReference(header.valueType) }) - ), - navigation: convertedNavigation + ) }; for (const [typeId, type] of entries(ir.types)) { diff --git a/packages/cli/register/src/ir-to-fdr-converter/convertIrToNavigation.ts b/packages/cli/register/src/ir-to-fdr-converter/convertIrToNavigation.ts deleted file mode 100644 index bd481515f70..00000000000 --- a/packages/cli/register/src/ir-to-fdr-converter/convertIrToNavigation.ts +++ /dev/null @@ -1,128 +0,0 @@ -import { docsYml } from "@fern-api/configuration"; -import { APIV1Write } from "@fern-api/fdr-sdk"; -import { FernIr, IntermediateRepresentation } from "@fern-api/ir-sdk"; - -export function convertIrToNavigation( - ir: IntermediateRepresentation, - navigation: docsYml.APINavigationSchema | undefined -): APIV1Write.ApiNavigationConfigRoot | undefined { - if (navigation == null) { - return undefined; - } - - const defaultRoot = convertIrToDefaultNavigationConfigRoot(ir); - - const items = visitAndSortNavigationSchema(navigation, defaultRoot.items, ir); - - return { items }; -} - -export function convertIrToDefaultNavigationConfigRoot( - ir: IntermediateRepresentation -): APIV1Write.ApiNavigationConfigRoot { - const items: APIV1Write.ApiNavigationConfigItem[] = convertPackageToNavigationConfigItems(ir.rootPackage, ir); - return { items }; -} - -function convertPackageToNavigationConfigItems( - package_: FernIr.Package, - ir: IntermediateRepresentation -): APIV1Write.ApiNavigationConfigItem[] { - if (package_.navigationConfig != null) { - const pointsToPackage = ir.subpackages[package_.navigationConfig.pointsTo]; - if (pointsToPackage != null) { - return convertPackageToNavigationConfigItems(pointsToPackage, ir); - } - } - - const items: APIV1Write.ApiNavigationConfigItem[] = []; - - if (package_.service != null) { - const httpService = ir.services[package_.service]; - - httpService?.endpoints.forEach((endpoint) => { - items.push({ type: "endpointId", value: endpoint.name.originalName }); - }); - } - - if (package_.websocket != null) { - const channel = ir.websocketChannels?.[package_.websocket]; - if (channel != null) { - items.push({ type: "websocketId", value: channel.name.originalName }); - } - } - - if (package_.webhooks != null) { - const webhooks = ir.webhookGroups[package_.webhooks]; - - webhooks?.forEach((webhook) => { - items.push({ type: "webhookId", value: webhook.name.originalName }); - }); - } - - package_.subpackages.forEach((subpackageId) => { - const subpackage = ir.subpackages[subpackageId]; - - if (subpackage != null) { - items.push({ - type: "subpackage", - subpackageId, - items: convertPackageToNavigationConfigItems(subpackage, ir) - }); - } - }); - - return items; -} - -function createItemMatcher(key: string, ir: IntermediateRepresentation) { - return function (item: APIV1Write.ApiNavigationConfigItem): boolean { - if (item.type === "subpackage") { - // subpackages are keyed by a generated ID, so we need to look up the original name - return ir.subpackages[item.subpackageId]?.name.originalName === key; - } else { - // endpoints, webhooks, and websockets are keyed by their original name - return key === item.value; - } - }; -} - -function visitAndSortNavigationSchema( - navigationItems: docsYml.APINavigationSchema, - defaultItems: APIV1Write.ApiNavigationConfigItem[], - ir: IntermediateRepresentation -): APIV1Write.ApiNavigationConfigItem[] { - const items: APIV1Write.ApiNavigationConfigItem[] = []; - for (const navigationItem of navigationItems) { - if (typeof navigationItem === "string") { - const foundItem = defaultItems.find(createItemMatcher(navigationItem, ir)); - - if (foundItem != null && foundItem.type !== "subpackage") { - items.push(foundItem); - } else if (foundItem != null) { - items.push({ - type: "subpackage", - subpackageId: foundItem.subpackageId, - items: [] - }); - } - } else { - // item must be a collection of groups - - for (const [groupName, group] of Object.entries(navigationItem)) { - // item could either be a group name or method name - const foundItem = defaultItems.find(createItemMatcher(groupName, ir)); - - if (foundItem != null && foundItem.type === "subpackage") { - items.push({ - type: "subpackage", - subpackageId: foundItem.subpackageId, - items: visitAndSortNavigationSchema(group, foundItem.items, ir) - }); - } - } - } - } - - return items; -} diff --git a/packages/cli/register/src/registerApi.ts b/packages/cli/register/src/registerApi.ts index 8c0e01b619f..b7f3a0cea3e 100644 --- a/packages/cli/register/src/registerApi.ts +++ b/packages/cli/register/src/registerApi.ts @@ -1,8 +1,9 @@ import { FernToken } from "@fern-api/auth"; -import { Audiences, docsYml } from "@fern-api/configuration"; +import { Audiences } from "@fern-api/configuration"; import { createFdrService } from "@fern-api/core"; import { APIV1Write, FdrAPI } from "@fern-api/fdr-sdk"; import { generateIntermediateRepresentation } from "@fern-api/ir-generator"; +import { IntermediateRepresentation } from "@fern-api/ir-sdk"; import { TaskContext } from "@fern-api/task-context"; import { FernWorkspace } from "@fern-api/workspace-loader"; import { convertIrToFdrApi } from "./ir-to-fdr-converter/convertIrToFdrApi"; @@ -13,8 +14,7 @@ export async function registerApi({ context, token, audiences, - snippetsConfig, - navigation + snippetsConfig }: { organization: string; workspace: FernWorkspace; @@ -22,8 +22,7 @@ export async function registerApi({ token: FernToken; audiences: Audiences; snippetsConfig: APIV1Write.SnippetsConfig; - navigation: docsYml.APINavigationSchema | undefined; -}): Promise { +}): Promise<{ id: FdrAPI.ApiDefinitionId; ir: IntermediateRepresentation }> { const ir = await generateIntermediateRepresentation({ workspace, audiences, @@ -36,7 +35,7 @@ export async function registerApi({ token: token.value }); - const apiDefinition = convertIrToFdrApi({ ir, snippetsConfig, navigation }); + const apiDefinition = convertIrToFdrApi({ ir, snippetsConfig }); context.logger.debug("Calling registerAPI... ", JSON.stringify(apiDefinition, undefined, 4)); const response = await fdrService.api.v1.register.registerApiDefinition({ orgId: organization, @@ -46,7 +45,7 @@ export async function registerApi({ if (response.ok) { context.logger.debug(`Registered API Definition ${response.body.apiDefinitionId}`); - return response.body.apiDefinitionId; + return { id: response.body.apiDefinitionId, ir }; } else { switch (response.error.error) { case "UnauthorizedError": diff --git a/packages/core/package.json b/packages/core/package.json index 7f46e836b3e..4435d7b5b05 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -27,7 +27,7 @@ "depcheck": "depcheck" }, "dependencies": { - "@fern-api/fdr-sdk": "^0.73.0-d986da306", + "@fern-api/fdr-sdk": "0.73.1-9d67ec828", "@fern-api/venus-api-sdk": "0.0.38", "@fern-fern/fiddle-sdk": "^0.0.503" }, diff --git a/yarn.lock b/yarn.lock index 0ea4d8d65e2..b2671820afb 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3447,7 +3447,7 @@ __metadata: resolution: "@fern-api/configuration@workspace:packages/cli/configuration" dependencies: "@fern-api/core-utils": "workspace:*" - "@fern-api/fdr-sdk": ^0.73.0-d986da306 + "@fern-api/fdr-sdk": 0.73.1-9d67ec828 "@fern-api/fs-utils": "workspace:*" "@fern-api/task-context": "workspace:*" "@fern-fern/fiddle-sdk": ^0.0.503 @@ -3491,7 +3491,7 @@ __metadata: version: 0.0.0-use.local resolution: "@fern-api/core@workspace:packages/core" dependencies: - "@fern-api/fdr-sdk": ^0.73.0-d986da306 + "@fern-api/fdr-sdk": 0.73.1-9d67ec828 "@fern-api/venus-api-sdk": 0.0.38 "@fern-fern/fiddle-sdk": ^0.0.503 "@types/jest": ^29.0.3 @@ -3553,7 +3553,7 @@ __metadata: dependencies: "@fern-api/configuration": "workspace:*" "@fern-api/core-utils": "workspace:*" - "@fern-api/fdr-sdk": ^0.73.0-d986da306 + "@fern-api/fdr-sdk": 0.73.1-9d67ec828 "@fern-api/fs-utils": "workspace:*" "@fern-api/ir-generator": "workspace:*" "@fern-api/register": "workspace:*" @@ -3625,9 +3625,9 @@ __metadata: languageName: unknown linkType: soft -"@fern-api/fdr-sdk@npm:^0.73.0-d986da306": - version: 0.73.0-d986da306 - resolution: "@fern-api/fdr-sdk@npm:0.73.0-d986da306" +"@fern-api/fdr-sdk@npm:0.73.1-9d67ec828": + version: 0.73.1-9d67ec828 + resolution: "@fern-api/fdr-sdk@npm:0.73.1-9d67ec828" dependencies: form-data: 4.0.0 js-base64: 3.7.7 @@ -3637,7 +3637,7 @@ __metadata: qs: 6.12.0 tinycolor2: ^1.6.0 url-join: 4.0.1 - checksum: 6fad80ce0554aeb049752546a871f8f1f1bc5d70596c48a70bf78cd8cf0bfac13fb7087923ff7d6eb290e3b4bf35e7cd30fdbd4d16abc311b1400945a883a4e1 + checksum: 9790af8fabecec84b3b60d586a9ed47fc353687d80bd79e7d25d7de845cbe1dd68ffe59f88d6709efdadf268f954687eadc67610c97a17b328085a2d701cb23c languageName: node linkType: hard @@ -4268,7 +4268,7 @@ __metadata: "@fern-api/configuration": "workspace:*" "@fern-api/core": "workspace:*" "@fern-api/core-utils": "workspace:*" - "@fern-api/fdr-sdk": ^0.73.0-d986da306 + "@fern-api/fdr-sdk": 0.73.1-9d67ec828 "@fern-api/ir-generator": "workspace:*" "@fern-api/ir-sdk": "workspace:*" "@fern-api/task-context": "workspace:*" @@ -4295,7 +4295,7 @@ __metadata: "@fern-api/core": "workspace:*" "@fern-api/core-utils": "workspace:*" "@fern-api/docs-validator": "workspace:*" - "@fern-api/fdr-sdk": ^0.73.0-d986da306 + "@fern-api/fdr-sdk": 0.73.1-9d67ec828 "@fern-api/fs-utils": "workspace:*" "@fern-api/ir-generator": "workspace:*" "@fern-api/ir-migrations": "workspace:*"