{"version":3,"sources":["/home/runner/work/deox/deox/packages/blogger-feed/dist/index.cjs","../src/constants.ts","../src/errors.ts","../src/utils.ts","../src/methods.ts","../src/blog.ts","../src/client.ts","../src/request.ts","../src/feed-parser.ts","../src/comments.ts","../src/pages.ts","../src/posts.ts","../src/blogger-feed.ts"],"names":["isString"],"mappings":"AAAA;ACCO,IAAM,gBAAA,EAAkB,uCAAA;AAGxB,IAAM,iBAAA,EAAmB;AAAA,EAC9B,IAAA,EAAM;AAAA,IACJ,KAAA,EAAO,yBAAA;AAAA,IACP,IAAA,EAAM;AAAA,EACR,CAAA;AAAA,EACA,IAAA,EAAM;AAAA,IACJ,KAAA,EAAO,yBAAA;AAAA,IACP,IAAA,EAAM;AAAA,EACR,CAAA;AAAA,EACA,OAAA,EAAS;AAAA,IACP,KAAA,EAAO,4BAAA;AAAA,IACP,IAAA,EAAM;AAAA,EACR,CAAA;AAAA,EACA,IAAA,EAAM;AAAA,IACJ,KAAA,EAAO,yBAAA;AAAA,IACP,IAAA,EAAM;AAAA,EACR;AACF,CAAA;ADDA;AACA;AEhBO,IAAM,SAAA,EAAN,MAAA,QAAuB,MAAM;AAAA,EAClC,WAAA,CAAY,OAAA,EAAiB,OAAA,EAAwB;AACnD,IAAA,KAAA,CAAM,OAAA,EAAS,OAAO,CAAA;AACtB,IAAA,IAAA,CAAK,KAAA,EAAO,UAAA;AAAA,EACd;AACF,CAAA;AAKO,IAAM,aAAA,EAAN,MAAA,QAA2B,SAAS;AAAA,EACzC,WAAA,CAAY,OAAA,EAAiB,OAAA,EAAwB;AACnD,IAAA,KAAA,CAAM,OAAA,EAAS,OAAO,CAAA;AACtB,IAAA,IAAA,CAAK,KAAA,EAAO,cAAA;AAAA,EACd;AACF,CAAA;AAKO,IAAM,gBAAA,EAAN,MAAA,QAA8B,SAAS;AAAA,EAG5C,WAAA,CAAY,OAAA,EAAiB,GAAA,EAAmB,OAAA,EAAwB;AACtE,IAAA,KAAA,CAAM,OAAA,EAAS,OAAO,CAAA;AACtB,IAAA,IAAA,CAAK,KAAA,EAAO,iBAAA;AACZ,IAAA,IAAA,CAAK,IAAA,EAAM,MAAA,CAAO,GAAG,CAAA;AAAA,EACvB;AACF,CAAA;AAMO,IAAM,sBAAA,EAAN,MAAA,QAKG,SAAS;AAAA,EAKjB,WAAA,CAAY,MAAA,EAAW,OAAA,EAAwB;AAC7C,IAAA,KAAA,CAAM,MAAA,CAAO,KAAA,EAAO,OAAO,CAAA;AAC3B,IAAA,IAAA,CAAK,KAAA,EAAO,uBAAA;AAEZ,IAAA,IAAA,CAAK,MAAA,EAAQ,MAAA,CAAO,KAAA;AACpB,IAAA,IAAA,CAAK,KAAA,EAAO,MAAA,CAAO,IAAA;AAAA,EACrB;AACF,CAAA;AFPA;AACA;AGlDA,kDAAyB;AAIlB,IAAM,WAAA,EAAa,CAAC,GAAA,EAAA,GAAiB,MAAA,EAAA,GAAqB;AAC/D,EAAA,IAAI,QAAA,EAAU,GAAA;AAEd,EAAA,IAAA,CAAA,IAAS,EAAA,EAAI,CAAA,EAAG,EAAA,EAAI,MAAA,CAAO,MAAA,EAAQ,EAAA,GAAK,CAAA,EAAG;AACzC,IAAA,GAAA,CAAI,CAAC,QAAA,GAAW,CAAC,MAAA,CAAO,MAAA,CAAO,OAAA,EAAS,MAAA,CAAO,CAAC,CAAC,CAAA,EAAG;AAClD,MAAA,OAAO,EAAE,MAAA,EAAQ,KAAA,EAAO,KAAA,EAAO,KAAA,EAAU,CAAA;AAAA,IAC3C;AACA,IAAA,QAAA,EAAU,OAAA,CAAQ,MAAA,CAAO,CAAC,CAAU,CAAA;AAAA,EACtC;AAEA,EAAA,OAAO,EAAE,MAAA,EAAQ,IAAA,EAAM,KAAA,EAAO,QAAQ,CAAA;AACxC,CAAA;AAGO,IAAM,UAAA,EAAY,CAAC,GAAA,EAAA,GAAiB,IAAA,EAAA,GAA4B,UAAA,CAAW,GAAA,EAAK,GAAG,IAAI,CAAA,CAAE,KAAA;AAGhG,IAAM,kBAAA,EAAoB,CAA6C,UAAA,EAAA,GACrE,MAAA,CAAO,IAAA,CAAK,UAAU,CAAA,CAAE,MAAA,CAAO,CAAC,GAAA,EAAK,GAAA,EAAA,GAAQ;AAC3C,EAAA,MAAM,MAAA,EAAQ,UAAA,CAAW,GAAc,CAAA;AAEvC,EAAA,GAAA,CAAI,GAAG,EAAA,EAAI;AAAA,IACT;AAAA,EACF,CAAA;AAEA,EAAA,OAAO,GAAA;AACT,CAAA,EAAG,CAAC,CAA0B,CAAA;AAGzB,IAAM,cAAA,EAAgB,CAC3B,MAAA,EACA,SAAA,EACA,OAAA,EAAA,GACG;AACH,EAAA,GAAA,CAAI,OAAA,EAAS;AACX,IAAA,MAAA,CAAO,MAAA,CAAO,MAAA,EAAQ,OAAO,CAAA;AAAA,EAC/B;AACA,EAAA,MAAA,CAAO,gBAAA,CAAiB,MAAA,EAAQ,iBAAA,CAAkB,SAAS,CAAC,CAAA;AAE5D,EAAA,OAAO,MAAA;AACT,CAAA;AAGO,IAAM,WAAA,EAAa;AAAA;AAAA,EAExB,CAAA,CAAE,IAAA,EAAe,IAAA,EAAc;AAC7B,IAAA,GAAA,CAAI,CAAC,iCAAA,IAAa,CAAA,EAAG,MAAM,IAAI,YAAA,CAAa,CAAA,EAAA;AAC9C,EAAA;AAAA;AAGgC,EAAA;AACb,IAAA;AAE4B,IAAA;AAC/C,EAAA;AAAA;AAGgC,EAAA;AACb,IAAA;AAEmC,IAAA;AACtD,EAAA;AACF;AH2BiD;AACA;AIzE5B;AAGS,EAAA;AACjB,IAAA;AACX,EAAA;AAAA;AAGiE,EAAA;AA7BnE,IAAA;AA8B2C,IAAA;AAClB,MAAA;AACF,MAAA;AACE,MAAA;AACL,MAAA;AACI,MAAA;AACJ,MAAA;AACuB,MAAA;AACP,QAAA;AACM,UAAA;AAC9B,YAAA;AACD,UAAA;AAC0B,UAAA;AAC7B,QAAA;AACO,QAAA;AACT,MAAA;AACiC,MAAA;AACP,QAAA;AACU,UAAA;AAC9B,YAAA;AACD,UAAA;AAC0B,UAAA;AAC7B,QAAA;AACO,QAAA;AACT,MAAA;AACF,IAAA;AAEgC,IAAA;AAClC,EAAA;AACF;AJwEiD;AACA;AK7Hf;AAAA;AAAA;AAAA;AAAA;AAAA;AAMqB,EAAA;AACjB,IAAA;AACxB,MAAA;AAAA;AAEM,QAAA;AACd,MAAA;AACA,MAAA;AACD,IAAA;AAG0C,IAAA;AAEpC,IAAA;AACT,EAAA;AACF;AL4HiD;AACA;AMxJxB;AN0JwB;AACA;AO3JtB;AACF;AP6JwB;AACA;AQ/JrBA;AAKf;AAS4B;AAdzC,EAAA;AAeyB,EAAA;AACA,EAAA;AACG,EAAA;AAEmB,EAAA;AACA,IAAA;AACR,MAAA;AAEQ,MAAA;AACE,MAAA;AACA,MAAA;AACL,MAAA;AAEA,MAAA;AACD,QAAA;AACpB,QAAA;AACR,UAAA;AACC,UAAA;AACyB,UAAA;AACE,UAAA;AACnC,QAAA;AAEA,QAAA;AACiB,QAAA;AAEkB,QAAA;AACrC,MAAA;AACF,IAAA;AACF,EAAA;AAE+C,EAAA;AACjD;AASyC;AAKnC,EAAA;AACI,IAAA;AACI,IAAA;AACJ,IAAA;AACR,EAAA;AAC+B,EAAA;AAEY,EAAA;AAED,EAAA;AACL,IAAA;AACT,IAAA;AACA,MAAA;AACL,QAAA;AACD,UAAA;AAChB,QAAA;AACF,MAAA;AACF,IAAA;AACF,EAAA;AAEO,EAAA;AACT;AAS8C;AAClB,EAAA;AAEkB,EAAA;AACA,IAAA;AACC,MAAA;AAEN,MAAA;AACH,MAAA;AACF,QAAA;AAC9B,MAAA;AACF,IAAA;AACF,EAAA;AAEO,EAAA;AACT;AAS4C;AACP,EAAA;AACW,IAAA;AACnB,IAAA;AAChB,MAAA;AACT,IAAA;AACO,IAAA;AACR,EAAA;AAEgC,EAAA;AACnC;AASiE;AAC/B,EAAA;AACxB,IAAA;AACE,IAAA;AACD,IAAA;AACT,EAAA;AAEM,EAAA;AACa,IAAA;AACG,EAAA;AACT,EAAA;AACkC,IAAA;AACD,MAAA;AACD,QAAA;AACxB,QAAA;AACC,QAAA;AACE,MAAA;AACJ,QAAA;AAChB,MAAA;AACF,IAAA;AACF,EAAA;AAEO,EAAA;AACT;AAS6C;AAChB,EAAA;AAEa,EAAA;AACO,IAAA;AACN,MAAA;AACI,MAAA;AACD,MAAA;AACE,MAAA;AAEF,MAAA;AAEd,MAAA;AAGY,MAAA;AAEG,MAAA;AAC3C,IAAA;AACF,EAAA;AAEO,EAAA;AACT;AASyD;AAC9B,EAAA;AAChB,IAAA;AACD,IAAA;AACG,IAAA;AACX,EAAA;AAE8C,EAAA;AAER,EAAA;AACM,IAAA;AACD,MAAA;AACf,MAAA;AACe,MAAA;AAGjC,QAAA;AACkC,UAAA;AACC,UAAA;AACC,UAAA;AACxC,QAAA;AAC2B,QAAA;AACH,QAAA;AACH,UAAA;AACA,UAAA;AACH,YAAA;AAChB,UAAA;AACF,QAAA;AACF,MAAA;AACF,IAAA;AACF,EAAA;AAEO,EAAA;AACT;AAW6C;AACE,EAAA;AACA,EAAA;AACJ,EAAA;AAEZ,EAAA;AACE,EAAA;AACnB,IAAA;AAC0B,EAAA;AAC1B,IAAA;AACZ,EAAA;AAE4D,EAAA;AAEhC,EAAA;AAER,EAAA;AACX,IAAA;AACT,EAAA;AAE0B,EAAA;AAER,EAAA;AACK,IAAA;AACvB,EAAA;AAEO,EAAA;AACT;AASgE;AACnB,EAAA;AAEf,EAAA;AACA,IAAA;AAC5B,EAAA;AAEO,EAAA;AACT;AAS8D;AACjB,EAAA;AAEf,EAAA;AACA,IAAA;AAC5B,EAAA;AAEO,EAAA;AACT;AAS+D;AAClB,EAAA;AAEf,EAAA;AACA,IAAA;AAC5B,EAAA;AAEO,EAAA;AACT;AASsD;AACL,EAAA;AACH,EAAA;AACG,EAAA;AACD,EAAA;AACH,EAAA;AACL,EAAA;AAED,EAAA;AACA,IAAA;AAEtB,IAAA;AACgC,MAAA;AACpC,MAAA;AACgC,MAAA;AACL,MAAA;AAC7B,MAAA;AACL,MAAA;AACS,MAAA;AACgC,MAAA;AAC3C,IAAA;AAEO,IAAA;AACT,EAAA;AAEO,EAAA;AACT;AASqD;AACL,EAAA;AACH,EAAA;AACI,EAAA;AACF,EAAA;AACA,EAAA;AACA,EAAA;AACH,EAAA;AACJ,EAAA;AAIlB,EAAA;AAMgB,IAAA;AAEf,IAAA;AACM,MAAA;AAChB,MAAA;AACI,MAAA;AACF,MAAA;AAC8B,MAAA;AAClC,MAAA;AACL,MAAA;AACwC,MAAA;AACxC,MAAA;AACA,MAAA;AACqC,MAAA;AACA,MAAA;AACC,MAAA;AACjB,MAAA;AACvB,IAAA;AAEO,IAAA;AACT,EAAA;AAEO,EAAA;AACT;AAS8D;AA5Z9D,EAAA;AA6ZgD,EAAA;AACX,EAAA;AACI,EAAA;AACF,EAAA;AACE,EAAA;AACI,EAAA;AACD,EAAA;AACL,EAAA;AACA,EAAA;AACH,EAAA;AACI,EAAA;AAI3B,EAAA;AAQsB,IAAA;AAEN,IAAA;AAChB,MAAA;AACI,MAAA;AACF,MAAA;AACJ,MAAA;AACL,MAAA;AAC2C,MAAA;AACH,MAAA;AACA,MAAA;AACN,MAAA;AACR,MAAA;AACpB,MAAA;AACgC,QAAA;AACK,QAAA;AAC3C,MAAA;AACW,MAAA;AACb,IAAA;AAEO,IAAA;AACT,EAAA;AAEO,EAAA;AACT;AAS4C;AACf,EAAA;AACM,EAAA;AAER,EAAA;AACd,IAAA;AACG,IAAA;AAEe,IAAA;AACc,MAAA;AACH,QAAA;AACd,QAAA;AACa,UAAA;AACM,YAAA;AAClB,YAAA;AACU,cAAA;AAC3B,YAAA;AACK,UAAA;AACwB,YAAA;AACf,YAAA;AACO,cAAA;AACrB,YAAA;AACF,UAAA;AACF,QAAA;AACF,MAAA;AACF,IAAA;AACF,EAAA;AAEyB,EAAA;AAC3B;AAU+C;AACN,EAAA;AAEI,EAAA;AAExB,EAAA;AACO,IAAA;AACqB,IAAA;AAC7C,IAAA;AACA,IAAA;AACwC,IAAA;AACJ,IAAA;AACG,IAAA;AACnB,IAAA;AACI,IAAA;AACJ,IAAA;AACtB,EAAA;AAEO,EAAA;AACT;AAa0C;AACpB,EAAA;AACX,IAAA;AACT,EAAA;AACqB,EAAA;AACN,IAAA;AACf,EAAA;AACO,EAAA;AACT;AAiB6C;AACE,EAAA;AAGhB,EAAA;AACU,IAAA;AACC,IAAA;AACxC,EAAA;AAE+C,EAAA;AACT,EAAA;AACxC;ARjFiD;AACA;AO3db;AAC+D,EAAA;AAChF,IAAA;AACU,IAAA;AACA,IAAA;AACY,MAAA;AAChB,QAAA;AAClB,MAAA;AACH,IAAA;AAC8E,IAAA;AACxC,MAAA;AACI,QAAA;AACxC,MAAA;AACF,IAAA;AAC8B,IAAA;AACJ,MAAA;AACG,MAAA;AACA,QAAA;AACC,QAAA;AACD,UAAA;AACR,YAAA;AACf,UAAA;AACK,QAAA;AACY,UAAA;AACnB,QAAA;AACF,MAAA;AACF,IAAA;AACF,EAAA;AACF;AAgC6D;AAUD;AA1F5D,EAAA;AA2FG,EAAA;AAEiC,EAAA;AACY,EAAA;AACX,EAAA;AAEW,EAAA;AAC/B,EAAA;AAC0B,EAAA;AAClB,EAAA;AAEoB,EAAA;AACd,IAAA;AACL,MAAA;AACH,MAAA;AACnB,IAAA;AAC4B,IAAA;AACN,MAAA;AACiB,MAAA;AACvC,IAAA;AACgC,IAAA;AACjC,EAAA;AACH;AASuG;AA1HvG,EAAA;AA2HoC,EAAA;AAChC,IAAA;AACkB,EAAA;AACyB,IAAA;AAClC,MAAA;AACR,IAAA;AACF,EAAA;AAEiB,EAAA;AACV,IAAA;AACuC,IAAA;AAC/C,EAAA;AAEyC,EAAA;AACvB,EAAA;AACV,IAAA;AACoB,IAAA;AAC5B,EAAA;AAE4B,EAAA;AAC9B;AAUuE;AACvB,EAAA;AAGJ,EAAA;AAC5B,IAAA;AACA,IAAA;AACH,IAAA;AACK,IAAA;AACA,IAAA;AACF,IAAA;AACA,IAAA;AACN,IAAA;AACC,IAAA;AACT,EAAA;AAEY,EAAA;AACgB,IAAA;AACuB,MAAA;AACzB,MAAA;AACF,QAAA;AACL,QAAA;AACqC,UAAA;AAClD,QAAA;AACa,QAAA;AACsC,UAAA;AACnD,QAAA;AACiB,QAAA;AACW,UAAA;AAC5B,QAAA;AACF,MAAA;AACF,IAAA;AACF,EAAA;AAGc,EAAA;AAGK,EAAA;AAE4B,EAAA;AAG7B,EAAA;AAIG,EAAA;AACvB;APmZiD;AACA;AMxlBM;AAEhB;AAEe;AAalC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAa8C,EAAA;AAClB,IAAA;AAC/B,MAAA;AACuB,MAAA;AAC7B,IAAA;AACiB,MAAA;AACM,MAAA;AACpB,QAAA;AACgC,MAAA;AAClC,QAAA;AACa,UAAA;AACL,QAAA;AAAC,QAAA;AACf,MAAA;AACU,MAAA;AACQ,QAAA;AAClB,MAAA;AACsC,MAAA;AACpB,QAAA;AAClB,MAAA;AAE8B,MAAA;AACM,MAAA;AACtC,IAAA;AAC+B,IAAA;AAGM,IAAA;AACnB,MAAA;AAClB,IAAA;AACF,EAAA;AASW,EAAA;AACW,IAAA;AA1ExB,MAAA;AA2EsC,MAAA;AAEW,MAAA;AAEhC,MAAA;AACA,QAAA;AACC,QAAA;AACyB,QAAA;AACD,QAAA;AACpC,MAAA;AAEY,MAAA;AACX,IAAA;AACL,EAAA;AAES,EAAA;AACa,IAAA;AA3FxB,MAAA;AA4FoB,MAAA;AACF,MAAA;AACX,IAAA;AACL,EAAA;AAEU,EAAA;AACY,IAAA;AAlGxB,MAAA;AAmGoB,MAAA;AACF,MAAA;AACX,IAAA;AACL,EAAA;AAEiB,EAAA;AAC8B,IAAA;AAC/C,EAAA;AAEkB,EAAA;AACyB,IAAA;AAC3C,EAAA;AAEoD,EAAA;AACL,IAAA;AAC/C,EAAA;AACF;ANujBiD;AACA;AS3qBrB;AA2BU;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAQqD,EAAA;AACpE,IAAA;AAGqB,IAAA;AAEH,IAAA;AAC3B,MAAA;AACS,MAAA;AACjB,MAAA;AACD,IAAA;AAG8B,IAAA;AACa,MAAA;AAC5C,IAAA;AAEiC,IAAA;AACnC,EAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAWiF,EAAA;AACtC,IAAA;AAChB,IAAA;AAES,IAAA;AACW,MAAA;AAC3C,MAAA;AAAA;AAEwB,QAAA;AACL,QAAA;AACjB,QAAA;AACF,MAAA;AACF,IAAA;AAEgB,IAAA;AAEQ,IAAA;AAEjB,IAAA;AACT,EAAA;AACF;ATwoBiD;AACA;AUtsBd;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAQqD,EAAA;AACzC,IAAA;AACjC,MAAA;AACS,MAAA;AACjB,MAAA;AACD,IAAA;AAE6B,IAAA;AAChC,EAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAUiG,EAAA;AACtD,IAAA;AAEN,IAAA;AAChB,MAAA;AACjB,MAAA;AACD,IAAA;AAEmB,IAAA;AAGuB,IAAA;AAEpC,IAAA;AACT,EAAA;AACF;AVisBiD;AACA;AWlwBrB;AAyBO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAQqD,EAAA;AAClE,IAAA;AAGqB,IAAA;AAEI,IAAA;AACjC,MAAA;AACS,MAAA;AACjB,MAAA;AACD,IAAA;AAE6B,IAAA;AAChC,EAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAUiG,EAAA;AACtD,IAAA;AAEN,IAAA;AAChB,MAAA;AACjB,MAAA;AACD,IAAA;AAEmB,IAAA;AAGuB,IAAA;AAEpC,IAAA;AACT,EAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAUoG,EAAA;AAC3D,IAAA;AAEI,IAAA;AACjC,MAAA;AACH,QAAA;AACH,QAAA;AACF,MAAA;AACA,MAAA;AACD,IAAA;AAE6B,IAAA;AAChC,EAAA;AACF;AX+tBiD;AACA;AYtyBxB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAkB8C,EAAA;AACzB,IAAA;AACb,IAAA;AACA,IAAA;AACM,IAAA;AACR,IAAA;AAC7B,EAAA;AACF;AAxB6B;AACa;AACN;AACH;AACH;AZszBmB;AACA;AACA;AACA;AACA;AACA;AACA;AACA","file":"/home/runner/work/deox/deox/packages/blogger-feed/dist/index.cjs","sourcesContent":[null,"/** Name for global variable for jsonp callbacks */\nexport const JSONP_NAMESPACE = '__deox_blogger_feed_jsonp_callbacks__';\n\n/** Feed ot entry not found error */\nexport const NOT_FOUND_ERRORS = {\n  post: {\n    error: 'The post was not found.',\n    code: 'post_not_found',\n  },\n  page: {\n    error: 'The page was not found.',\n    code: 'page_not_found',\n  },\n  comment: {\n    error: 'The comment was not found.',\n    code: 'comment_not_found',\n  },\n  blog: {\n    error: 'The blog was not found.',\n    code: 'blog_not_found',\n  },\n} as const;\n","import type { NOT_FOUND_ERRORS } from './constants';\n\n/**\n * Represents a SDK error\n */\nexport class SDKError extends Error {\n  constructor(message: string, options?: ErrorOptions) {\n    super(message, options);\n    this.name = 'SDKError';\n  }\n}\n\n/**\n * Represents a SDK type error\n */\nexport class SDKTypeError extends SDKError {\n  constructor(message: string, options?: ErrorOptions) {\n    super(message, options);\n    this.name = 'SDKTypeError';\n  }\n}\n\n/**\n * Represents a error thrown while making an API request\n */\nexport class SDKRequestError extends SDKError {\n  readonly url: string;\n\n  constructor(message: string, url: string | URL, options?: ErrorOptions) {\n    super(message, options);\n    this.name = 'SDKRequestError';\n    this.url = String(url);\n  }\n}\n\n/**\n * Represents a error thrown when client is requesting for some resources which does not exists.\n * For example requesting for a post with specific `post_id` but that doesn't exists.\n */\nexport class SDKInputNotFoundError<\n  T extends {\n    error: string;\n    code: (typeof NOT_FOUND_ERRORS)[keyof typeof NOT_FOUND_ERRORS]['code'];\n  },\n> extends SDKError {\n  readonly error: T['error'];\n\n  readonly code: T['code'];\n\n  constructor(result: T, options?: ErrorOptions) {\n    super(result.error, options);\n    this.name = 'SDKInputNotFoundError';\n\n    this.error = result.error;\n    this.code = result.code;\n  }\n}\n","import { isString } from '@deox/utils/predicate';\nimport { SDKTypeError } from './errors';\n\n/** Checks whether the deep nested property in an object exists and gets its value */\nexport const nestedData = (obj: unknown, ...levels: string[]) => {\n  let current = obj;\n\n  for (let i = 0; i < levels.length; i += 1) {\n    if (!current || !Object.hasOwn(current, levels[i])) {\n      return { exists: false, value: undefined };\n    }\n    current = current[levels[i] as never];\n  }\n\n  return { exists: true, value: current };\n};\n\n/** Gets the deep nested property value in an object */\nexport const getNested = (obj: unknown, ...args: string[]): unknown => nestedData(obj, ...args).value;\n\n/** Converts object to property descriptor map */\nconst getConfigurations = <M extends Record<string | number, unknown>>(properties: M) =>\n  Object.keys(properties).reduce((acc, key) => {\n    const value = properties[key as keyof M];\n\n    acc[key] = {\n      value,\n    };\n\n    return acc;\n  }, {} as PropertyDescriptorMap);\n\n/** Adds properties to existing object */\nexport const addProperties = <O extends NonNullable<unknown>, I extends NonNullable<unknown>, M extends NonNullable<unknown>>(\n  object: O,\n  immutable: I,\n  mutable?: M,\n) => {\n  if (mutable) {\n    Object.assign(object, mutable);\n  }\n  Object.defineProperties(object, getConfigurations(immutable));\n\n  return object as O & M & I;\n};\n\n/** Input validators */\nexport const validators = {\n  /** asserts: input must be string */\n  s(data: unknown, name: string) {\n    if (!isString(data)) throw new SDKTypeError(`${name} must be of type string, current type is ${typeof data}`);\n  },\n\n  /** asserts: string must not be empty */\n  nE(data: unknown, name: string) {\n    this.s(data, name);\n\n    if ((data as string).length === 0) throw new SDKTypeError(`${name} cannot be an empty string`);\n  },\n\n  /** asserts: string must not be blank */\n  nB(data: unknown, name: string) {\n    this.s(data, name);\n\n    if ((data as string).trim().length === 0) throw new SDKTypeError(`${name} cannot be a blank string`);\n  },\n};\n","import type { Client } from './client';\nimport type { Comment, Feed, Post } from './types';\nimport { addProperties } from './utils';\n\ntype PaginationMap = {\n  posts: Post[];\n  comments: Comment[];\n};\n\n/** Pagination props */\nexport interface PaginationProps<T extends keyof PaginationMap> {\n  readonly itemsPerPage: number | null;\n  readonly startIndex: number | null;\n  readonly totalResults: number | null;\n  readonly selfUrl: string | null;\n  readonly previousUrl: string | null;\n  readonly nextUrl: string | null;\n  next(requestOptions?: { signal?: AbortSignal }): Promise<(PaginationMap[T] & PaginationProps<T>) | null>;\n  previous(requestOptions?: { signal?: AbortSignal }): Promise<(PaginationMap[T] & PaginationProps<T>) | null>;\n}\n\nexport class Methods {\n  protected c: Client;\n\n  constructor(client: Client) {\n    this.c = client;\n  }\n\n  /** Adds pagination properties and methods to feed entries array */\n  protected _p<T extends keyof PaginationMap>(type: T, feed: Feed) {\n    const properties: PaginationProps<T> = {\n      itemsPerPage: feed.itemsPerPage,\n      startIndex: feed.startIndex,\n      totalResults: feed.totalResults,\n      selfUrl: feed.selfUrl,\n      previousUrl: feed.previousUrl,\n      nextUrl: feed.nextUrl,\n      previous: async ({ signal } = {}) => {\n        if (properties.previousUrl) {\n          const result = await this.c.req(properties.previousUrl, {\n            signal,\n          });\n          return this._p(type, result);\n        }\n        return null;\n      },\n      next: async ({ signal } = {}) => {\n        if (properties.nextUrl) {\n          const result = await this.c.req(properties.nextUrl, {\n            signal,\n          });\n          return this._p(type, result);\n        }\n        return null;\n      },\n    };\n\n    return addProperties(((type === 'comments' ? feed.comments : feed.posts) ?? []) as PaginationMap[T], properties);\n  }\n}\n","import { NOT_FOUND_ERRORS } from './constants';\nimport { SDKInputNotFoundError } from './errors';\nimport { Methods } from './methods';\n\n/**\n * A class having methods related to Blog\n */\nexport class Blog extends Methods {\n  /**\n   * Retrieve blog information\n   *\n   * @returns The blog info\n   */\n  async get({ signal }: { signal?: AbortSignal } = {}) {\n    const { blog } = await this.c.req('./posts/summary', {\n      params: {\n        // Do not load entries since we only need blog info\n        maxResults: 0,\n      },\n      signal,\n    });\n\n    // Throw an error if feed doesn't contain blog info\n    if (!blog) throw new SDKInputNotFoundError(NOT_FOUND_ERRORS.blog);\n\n    return blog;\n  }\n}\n","import { isString } from '@deox/utils/predicate';\nimport { NOT_FOUND_ERRORS } from './constants';\nimport { SDKInputNotFoundError } from './errors';\nimport { type FetchFeedOptions, fetchFeed } from './request';\n\nconst addSlash = (url: string) => (url.endsWith('/') ? url : `${url}/`);\n\nconst getServiceBase = (id: string) => `https://www.blogger.com/feeds/${id}/`;\n\nconst getDomainBase = (origin: string) => `${addSlash(origin)}feeds/`;\n\n/**\n * An interface representing options for {@link Client} constructor\n */\nexport interface ClientOptions {\n  /** When set to `true`, enables jsonp callbacks */\n  jsonp?: boolean;\n}\n\n/**\n * A class for fetching Blogger feed\n */\nexport class Client {\n  private jsonp: boolean;\n  private base: string;\n\n  private _bU: string | undefined;\n  private _bI: string | undefined;\n\n  /**\n   * Creates an instance of {@link Client}\n   *\n   * @param urlOrId The url or id of the blog\n   * @param options Options\n   */\n  constructor(urlOrId: string | URL, options: ClientOptions = {}) {\n    if (isString(urlOrId) && /^\\d{12,24}$/.test(urlOrId)) {\n      this._bI = urlOrId;\n      this.base = getServiceBase(urlOrId);\n    } else {\n      let url: URL | null = null;\n      if (urlOrId instanceof URL) {\n        url = urlOrId;\n      } else if (typeof urlOrId === 'string') {\n        try {\n          url = new URL(!/^[a-zA-Z][a-zA-Z\\d+\\-.]*:\\/\\//.test(urlOrId) ? `https://${urlOrId}` : urlOrId);\n        } catch (_) {}\n      }\n      if (!url) {\n        throw new Error(\"Argument 'urlOrId' is not a valid blogger blog url or blog id\");\n      }\n      if (!/^https?:$/i.test(url.protocol)) {\n        throw new Error(`Argument 'urlOrId' has unsupported protocol '${url.protocol}'`);\n      }\n\n      this._bU = addSlash(url.origin);\n      this.base = getDomainBase(url.origin);\n    }\n    this.jsonp = options.jsonp === true;\n\n    // Throw an error if jsonp is enabled but current environment is not browser\n    if (this.jsonp && (typeof window !== 'object' || typeof document !== 'object')) {\n      throw new Error(\"options.jsonp is set to true but current environment does't support it, please set it to false to use json\");\n    }\n  }\n\n  private _?: {\n    id: string;\n    url: string;\n    serviceBase: string;\n    domainBase: string;\n  };\n\n  get blog() {\n    return (async () => {\n      const { blog } = await this.req('./posts/summary', { params: { maxResults: 0 } });\n\n      if (!blog) throw new SDKInputNotFoundError(NOT_FOUND_ERRORS.blog);\n\n      this._ ??= {\n        id: blog.id,\n        url: blog.url,\n        serviceBase: getServiceBase(blog.id),\n        domainBase: getDomainBase(blog.url),\n      };\n\n      return this._;\n    })();\n  }\n\n  get id() {\n    return (async () => {\n      this._bI ??= (await this.blog).id;\n      return this._bI;\n    })();\n  }\n\n  get url() {\n    return (async () => {\n      this._bU ??= (await this.blog).url;\n      return this._bU;\n    })();\n  }\n\n  get domainBase() {\n    return (async () => getDomainBase(await this.url))();\n  }\n\n  get serviceBase() {\n    return (async () => getServiceBase(await this.id))();\n  }\n\n  async req(path: string, options?: FetchFeedOptions) {\n    return fetchFeed(path, { baseUrl: this.base, jsonp: this.jsonp, ...options });\n  }\n}\n","import { generateId } from '@deox/utils/generate-id';\nimport { isObject } from '@deox/utils/predicate';\nimport { JSONP_NAMESPACE } from './constants';\nimport { SDKError, SDKRequestError } from './errors';\nimport { parseFeed } from './feed-parser';\n\n/** An interface representing options for {@link RequestURL} */\nexport interface RequestURLOptions {\n  /**\n   * Indicates whether to clear existing search queries\n   */\n  clearParams?: boolean;\n\n  /**\n   * A record of key value which should to added to search queries\n   */\n  params?: Record<string, string | number | boolean | undefined | (string | number | boolean | undefined)[]>;\n}\n\n/** Constructs an `URL` object for endpoints */\nexport class RequestURL extends URL {\n  constructor(url: string | URL, base?: string | URL | undefined, options: RequestURLOptions = {}) {\n    super(url, base);\n    const { searchParams } = this;\n    if (options.clearParams) {\n      searchParams.forEach((_value, key, params) => {\n        params.delete(key);\n      });\n    }\n    const append = (key: string, value: string | number | boolean | undefined) => {\n      if (['string', 'boolean', 'number'].includes(typeof value)) {\n        searchParams.append(key, String(value));\n      }\n    };\n    if (isObject(options.params)) {\n      const queries = options.params;\n      for (const key in queries) {\n        const value = queries[key];\n        if (Array.isArray(value)) {\n          for (const e of value) {\n            append(key, e);\n          }\n        } else {\n          append(key, value);\n        }\n      }\n    }\n  }\n}\n\n/**\n * An interface of parameters which can be used for blogger feed api\n */\nexport interface Params {\n  maxResults?: number;\n  startIndex?: number;\n  orderBy?: 'lastmodified' | 'starttime' | 'published' | 'updated';\n  publishedMin?: Date | string;\n  publishedMax?: Date | string;\n  updatedMin?: Date | string;\n  updatedMax?: Date | string;\n  query?: string;\n}\n\n/**\n * An interface representing options for {@link fetchFeed}\n */\nexport interface FetchFeedOptions {\n  params?: Params;\n  include?: (keyof Params)[];\n  exclude?: (keyof Params)[];\n  baseUrl?: string | URL;\n  jsonp?: boolean;\n  signal?: AbortSignal;\n}\n\n/** A callback function for constructing jsonp url with given callback param */\ntype JSONPGetUrl = (data: { callback: string; id: string }) => string | URL;\n\n/** Pending jsonp requests */\nconst queueJSONP: Record<string, (data: unknown) => void> = {};\n\n/**\n * Fetches JSONP data through callback using script element\n *\n * @param getUrl A callback function for constructing jsonp url with given callback param\n * @param scriptOptions Assign object to script element\n *\n * @returns The data which was sent to the callback\n */\nconst fetchJSONP = async <T = unknown>(getUrl: JSONPGetUrl, scriptOptions?: Record<string, unknown>) => {\n  (window as unknown as Record<string, unknown>)[JSONP_NAMESPACE] ??= queueJSONP;\n\n  const id = `callback_${generateId('xxxxxxxx_xxxx_4xxx_yxxx_xxxxxxxxxxxx')}`;\n  const callback = `window.${JSONP_NAMESPACE}.${id}`;\n  const url = getUrl({ callback, id });\n\n  const script = document.createElement('script');\n  script.async = true;\n  if (scriptOptions) Object.assign(script, scriptOptions);\n  script.src = String(url);\n\n  return new Promise<T>((resolve, reject) => {\n    queueJSONP[id] = (data) => {\n      delete queueJSONP[id];\n      resolve(data as T);\n    };\n    script.onerror = (event) => {\n      delete queueJSONP[id];\n      reject(new SDKError(typeof event === 'string' ? event : `Failed to load script from ${script.src}`));\n    };\n    document.head.appendChild(script);\n  });\n};\n\n/**\n * Fetches JSON using Fetch API\n *\n * @param url The url to fetch\n *\n * @returns The json data\n */\nconst fetchJSON = async <T = unknown>(url: string | URL, { signal }: { signal?: AbortSignal } = {}) => {\n  const response = await fetch(url, {\n    signal,\n  }).catch((error) => {\n    throw new SDKRequestError('Fetch to JSON', String(url), {\n      cause: error,\n    });\n  });\n\n  if (!response.ok) {\n    await response.body?.cancel();\n    throw new SDKRequestError(`Failed to fetch ${response.url} (status: ${response.status})`, response.url);\n  }\n\n  const contentType = response.headers.get('Content-Type')?.includes('application/json');\n  if (!contentType) {\n    await response.body?.cancel();\n    throw new SDKRequestError(`Response was success but Content-Type '${contentType}' is not supported`, response.url);\n  }\n\n  return (await response.json()) as T;\n};\n\n/**\n * Fetches and parses the blogger feed\n *\n * @param path The feed url\n * @param param1 Options\n *\n * @returns The parsed feed data\n */\nexport const fetchFeed = async (path: string | URL, { params, include, exclude, baseUrl, jsonp, signal }: FetchFeedOptions = {}) => {\n  const queries: RequestURLOptions['params'] = {};\n\n  // List of supported search params options and map to valid params\n  const paramsMap: Record<string, string> = {\n    maxResults: 'max-results',\n    startIndex: 'start-index',\n    orderBy: 'orderby',\n    publishedMin: 'published-min',\n    publishedMax: 'published-max',\n    updatedMin: 'updated-min',\n    updatedMax: 'updated-max',\n    sort: 'sort',\n    query: 'q',\n  };\n\n  if (params) {\n    for (const key in params) {\n      const value = params[key as keyof typeof params];\n      if (key in paramsMap) {\n        let shouldAllow = true;\n        if (include) {\n          shouldAllow = (include as string[]).includes(key);\n        }\n        if (exclude) {\n          shouldAllow = !(exclude as string[]).includes(key);\n        }\n        if (shouldAllow) {\n          queries[paramsMap[key]] = value instanceof Date ? value.toISOString() : String(value);\n        }\n      }\n    }\n  }\n\n  // Set alt to json in order to load the json data instead of xml\n  queries.alt = 'json';\n\n  // Set redirect to false\n  queries.redirect = false;\n\n  const endpoint = new RequestURL(path, baseUrl, { params: queries });\n\n  const json = await (jsonp\n    ? fetchJSONP(({ callback }) => new RequestURL(endpoint, undefined, { params: { callback } }))\n    : fetchJSON(endpoint, { signal }));\n\n  // Parse the feed object to feed info\n  return parseFeed(json);\n};\n","import { isArray, isObject, isString } from '@deox/utils/predicate';\nimport type { Author, Blog, Comment, Extended, Feed, Geo, Link, Links, Post, PostCommentInfo } from './types';\nimport { getNested } from './utils';\n\n/** constants */\nconst NULL = null;\n\n/**\n * Gets the links details from link array\n *\n * @param linkArray The link array\n *\n * @returns An object containing link and links\n */\nconst getLinks = (linkArray: unknown) => {\n  const record: Links = {};\n  const array: Link[] = [];\n  let href: string | null = NULL;\n\n  if (isArray(linkArray) && linkArray.length > 0) {\n    for (let i = 0; i < linkArray.length; i += 1) {\n      const link: unknown = linkArray[i];\n\n      const linkRelLike = getNested(link, 'rel');\n      const linkHrefLike = getNested(link, 'href');\n      const linkTypeLike = getNested(link, 'type');\n      const linkTitleLike = getNested(link, 'title');\n\n      if (isString(linkRelLike) && isString(linkHrefLike)) {\n        if (!isArray(record[linkRelLike])) record[linkRelLike] = [];\n        const result = {\n          rel: linkRelLike,\n          href: linkHrefLike,\n          type: isString(linkTypeLike) ? linkTypeLike : NULL,\n          title: isString(linkTitleLike) ? linkTitleLike : NULL,\n        };\n\n        record[linkRelLike]?.push(result);\n        array.push(result);\n\n        if (linkRelLike === 'alternate' && linkTypeLike === 'text/html') href = linkHrefLike;\n      }\n    }\n  }\n\n  return { alternate: href, links: record, array };\n};\n\n/**\n * Gets pagination urls from feed\n *\n * @param feed The feed object\n *\n * @returns An object containing `self`, `previous` and `next` url\n */\nconst getPagination = (feed: unknown) => {\n  const result: {\n    self: string | null;\n    previous: string | null;\n    next: string | null;\n  } = {\n    self: NULL,\n    previous: NULL,\n    next: NULL,\n  };\n  const keys = Object.keys(result) as (keyof typeof result)[];\n\n  const { array } = getLinks(getNested(feed, 'link'));\n\n  for (let i = 0; i < array.length; i += 1) {\n    const { rel, href, type } = array[i];\n    if (type !== 'text/html') {\n      for (const key of keys) {\n        if (rel === key) {\n          result[key] = href;\n        }\n      }\n    }\n  }\n\n  return result;\n};\n\n/**\n * Gets category from category array\n *\n * @param categoryArray The category array\n *\n * @returns An Array of string representing categories\n */\nconst getLabels = (categoryArray: unknown) => {\n  const labels: string[] = [];\n\n  if (isArray(categoryArray) && categoryArray.length > 0) {\n    for (let i = 0; i < categoryArray.length; i += 1) {\n      const category: unknown = categoryArray[i];\n\n      const categoryTermLike = getNested(category, 'term');\n      if (isString(categoryTermLike)) {\n        labels.push(categoryTermLike);\n      }\n    }\n  }\n\n  return labels;\n};\n\n/**\n * Gets Geo details from post entry\n *\n * @param postEntry The post entry object\n *\n * @returns An object containing `box`, `featureName` and `point`\n */\nconst getGeo = (postEntry: unknown): Geo => {\n  const [box, featureName, point] = ['georss$box', 'georss$featurename', 'georss$point'].map((key) => {\n    const valueLike = getNested(postEntry, key, '$t');\n    if (isString(valueLike)) {\n      return valueLike;\n    }\n    return NULL;\n  });\n\n  return { box, featureName, point };\n};\n\n/**\n * Gets comments details from link array of a post entry object\n *\n * @param linkArray The link array\n *\n * @returns An object containing `feed`, `number` and `title`\n */\nconst getPostComments = (linkArray: unknown): PostCommentInfo => {\n  const result: PostCommentInfo = {\n    feed: NULL,\n    number: NULL,\n    title: NULL,\n  };\n\n  const {\n    links: { replies },\n  } = getLinks(linkArray);\n  if (replies) {\n    for (const { title, type, href } of replies) {\n      if (type === 'text/html' && isString(title)) {\n        const numberMatches = title.match(/\\d+/);\n        result.title = title;\n        result.number = numberMatches?.[0] ? Number.parseInt(numberMatches[0], 10) : 0;\n      } else if (type === 'application/atom+xml' && isString(href)) {\n        result.feed = href;\n      }\n    }\n  }\n\n  return result;\n};\n\n/**\n * Gets authors from author array\n *\n * @param authorArray The author array\n *\n * @returns An object containing `name`, `url`, `image` and `public`\n */\nconst getAuthors = (authorArray: unknown) => {\n  const authors: Author[] = [];\n\n  if (isArray(authorArray) && authorArray.length > 0) {\n    for (let i = 0; i < authorArray.length; i += 1) {\n      const author: unknown = authorArray[0];\n      const authorNameLike = getNested(author, 'name', '$t');\n      const authorUriLike = getNested(author, 'uri', '$t');\n      const authorImageLike = getNested(author, 'gd$image', 'src');\n\n      const name = isString(authorNameLike) ? authorNameLike : 'Unknown';\n      const image =\n        isString(authorImageLike) && authorImageLike.trim().toLowerCase() !== 'https://img1.blogblog.com/img/b16-rounded.gif'\n          ? authorImageLike\n          : NULL;\n      const url = isString(authorUriLike) ? authorUriLike : NULL;\n\n      authors.push({ name, url, image, public: url !== NULL });\n    }\n  }\n\n  return authors;\n};\n\n/**\n * Gets extended details from a comment entry object\n *\n * @param commentEntry The comment entry object\n *\n * @returns An object containing `class`, `time`, `removed`\n */\nconst getExtended = (commentEntry: unknown): Extended => {\n  const result: Extended = {\n    class: NULL,\n    time: NULL,\n    removed: false,\n  };\n\n  const extendedArray = getNested(commentEntry, 'gd$extendedProperty');\n\n  if (isObject(commentEntry) && isArray(extendedArray) && extendedArray.length > 0) {\n    for (let i = 0; i < extendedArray.length; i += 1) {\n      const extended = (extendedArray[i] || {}) as Record<string, unknown>;\n      const { name, value } = extended;\n      if (isString(name) && isString(value)) {\n        const data: {\n          [key: string]: ['class' | 'time' | 'removed', string | boolean];\n        } = {\n          'blogger.itemClass': ['class', value],\n          'blogger.displayTime': ['time', value],\n          'blogger.contentRemoved': ['removed', value === 'true'],\n        };\n        const dataArray = data[name];\n        if (isArray(dataArray)) {\n          const [key, val] = dataArray;\n          if (key in result) {\n            result[key] = val as never;\n          }\n        }\n      }\n    }\n  }\n\n  return result;\n};\n\n/**\n * Gets thumbnail urls from a post entry object\n *\n * @param postEntry The post entry object\n *\n * @returns An Array having 2 elements.\n * Element at index 0 will be thumbnail url or null from post entry.\n * Element at index 1 will be thumbnail url or null from post content otherwise post entry\n */\nconst getThumbnail = (postEntry: unknown) => {\n  const postContentLike = getNested(postEntry, 'content', '$t');\n  const postSummaryLike = getNested(postEntry, 'summary', '$t');\n  const postMediaThumbnailLike = getNested(postEntry, 'media$thumbnail', 'url');\n\n  let content: string | null = NULL;\n  if (isString(postContentLike)) {\n    content = postContentLike;\n  } else if (isString(postSummaryLike)) {\n    content = postSummaryLike;\n  }\n\n  const thumb: string | null = isString(postMediaThumbnailLike) ? postMediaThumbnailLike : NULL;\n\n  const result = [thumb, thumb] as [string | null, string | null];\n\n  if (thumb !== NULL) {\n    return result;\n  }\n\n  const matches = content ? /<img +(.*?)src=([\"\"])([^\"\"]+?)([\"\"])(.*?) *\\/?>/i.exec(content) : NULL;\n\n  if (matches?.[3]) {\n    result[1] = matches[3];\n  }\n\n  return result;\n};\n\n/**\n * Gets items per page number from feed object\n *\n * @param feedObject The feed object\n *\n * @returns The items per page number or `null`\n */\nconst getItemsPerPage = (feedObject: unknown): number | null => {\n  const resultString = getNested(feedObject, 'openSearch$itemsPerPage', '$t');\n\n  if (isString(resultString)) {\n    return Number(resultString);\n  }\n\n  return NULL;\n};\n\n/**\n * Gets start index number from feed object\n *\n * @param feedObject The feed object\n *\n * @returns The start index or `null`\n */\nconst getStartIndex = (feedObject: unknown): number | null => {\n  const resultString = getNested(feedObject, 'openSearch$startIndex', '$t');\n\n  if (isString(resultString)) {\n    return Number(resultString);\n  }\n\n  return NULL;\n};\n\n/**\n * Gets total result number from feed object\n *\n * @param feedObject The feed object\n *\n * @returns The total result or `null`\n */\nconst getTotalResult = (feedObject: unknown): number | null => {\n  const resultString = getNested(feedObject, 'openSearch$totalResults', '$t');\n\n  if (isString(resultString)) {\n    return Number(resultString);\n  }\n\n  return NULL;\n};\n\n/**\n * Gets blog details from feed object\n *\n * @param feedObject The feed object\n *\n * @returns The {@link Blog} if available otherwise `null`\n */\nconst getBlog = (feedObject: unknown): Blog | null => {\n  const feedIdLike = getNested(feedObject, 'id', '$t');\n  const feedTitleLike = getNested(feedObject, 'title', '$t');\n  const feedSubtitleLike = getNested(feedObject, 'subtitle', '$t');\n  const feedUpdatedLike = getNested(feedObject, 'updated', '$t');\n  const feedLinkLike = getNested(feedObject, 'link');\n  const { alternate, links } = getLinks(feedLinkLike);\n\n  if (isObject(feedObject) && isString(feedIdLike) && isString(feedTitleLike) && isString(feedUpdatedLike) && isString(alternate)) {\n    const feedCategoryLike = getNested(feedObject, 'category');\n\n    const blog = {\n      id: feedIdLike.replace(/^.*blog-(\\d+).*$/, '$1'),\n      title: feedTitleLike,\n      subtitle: isString(feedSubtitleLike) ? feedSubtitleLike : NULL,\n      labels: getLabels(feedCategoryLike),\n      url: alternate,\n      links,\n      updated: feedUpdatedLike,\n      author: getAuthors(getNested(feedObject, 'author'))[0],\n    };\n\n    return blog;\n  }\n\n  return NULL;\n};\n\n/**\n * Gets post details from post entry object\n *\n * @param postEntry The post entry object\n *\n * @returns The {@link Post} if available otherwise `null`\n */\nconst getPost = (postEntry: unknown): Post | null => {\n  const postIdLike = getNested(postEntry, 'id', '$t');\n  const postTitleLike = getNested(postEntry, 'title', '$t');\n  const postPublishedLike = getNested(postEntry, 'published', '$t');\n  const postUpdatedLike = getNested(postEntry, 'updated', '$t');\n  const postSummaryLike = getNested(postEntry, 'summary', '$t');\n  const postContentLike = getNested(postEntry, 'content', '$t');\n  const postLinkLike = getNested(postEntry, 'link');\n  const { alternate, links } = getLinks(postLinkLike);\n\n  if (\n    isObject(postEntry) &&\n    isString(alternate) &&\n    isString(postIdLike) &&\n    isString(postTitleLike) &&\n    isString(postPublishedLike) &&\n    isString(postUpdatedLike)\n  ) {\n    const [thumbnail, thumbnailAlt] = getThumbnail(postEntry);\n\n    const post: Post = {\n      id: postIdLike.replace(/^.*(?:page|post)-(\\d+)$/, '$1'),\n      title: postTitleLike,\n      published: postPublishedLike,\n      updated: postUpdatedLike,\n      labels: getLabels(getNested(postEntry, 'category')),\n      url: alternate,\n      links,\n      author: getAuthors(getNested(postEntry, 'author'))[0],\n      thumbnail,\n      thumbnailAlt,\n      summary: isString(postSummaryLike) ? postSummaryLike : NULL,\n      content: isString(postContentLike) ? postContentLike : NULL,\n      comments: getPostComments(postLinkLike),\n      geo: getGeo(postEntry),\n    };\n\n    return post;\n  }\n\n  return NULL;\n};\n\n/**\n * Gets comment details from comment entry object\n *\n * @param commentEntry The comment entry object\n *\n * @returns The {@link Comment} if available otherwise `null`\n */\nconst getComment = (commentEntry: unknown): Comment | null => {\n  const commentIdLike = getNested(commentEntry, 'id', '$t');\n  const commentTitleLike = getNested(commentEntry, 'title', '$t');\n  const commentPublishedLike = getNested(commentEntry, 'published', '$t');\n  const commentUpdatedLike = getNested(commentEntry, 'updated', '$t');\n  const commentInReplyToLike = getNested(commentEntry, 'thr$in-reply-to');\n  const commentInReplyToHrefLike = getNested(commentInReplyToLike, 'href');\n  const commentInReplyToRefLike = getNested(commentInReplyToLike, 'ref');\n  const commentSummaryLike = getNested(commentEntry, 'summary', '$t');\n  const commentContentLike = getNested(commentEntry, 'content', '$t');\n  const commentLinkLike = getNested(commentEntry, 'link');\n  const { alternate, links } = getLinks(commentLinkLike);\n\n  if (\n    isObject(commentEntry) &&\n    isString(alternate) &&\n    isString(commentIdLike) &&\n    isString(commentTitleLike) &&\n    isString(commentPublishedLike) &&\n    isString(commentUpdatedLike) &&\n    isString(commentInReplyToHrefLike) &&\n    isString(commentInReplyToRefLike)\n  ) {\n    const inReplyToMatches = links.related?.[0].href.match(/\\/feeds\\/(.*)\\/comments\\/[^/]+\\/(\\d+)/);\n\n    const comment: Comment = {\n      title: commentTitleLike,\n      published: commentPublishedLike,\n      updated: commentUpdatedLike,\n      url: alternate,\n      links,\n      author: getAuthors(getNested(commentEntry, 'author'))[0],\n      summary: isString(commentSummaryLike) ? commentSummaryLike : NULL,\n      content: isString(commentContentLike) ? commentContentLike : NULL,\n      extended: getExtended(commentEntry),\n      id: commentIdLike.replace(/^.*(?:page|post)-(\\d+)$/, '$1'),\n      post: {\n        id: commentInReplyToRefLike.replace(/^.*(?:page|post)-(\\d+)$/, '$1'),\n        url: commentInReplyToHrefLike.split('?')[0],\n      },\n      inReplyTo: inReplyToMatches?.[2] ?? NULL,\n    };\n\n    return comment;\n  }\n\n  return NULL;\n};\n\n/**\n * Gets the posts and comments from entry array\n *\n * @param entryArray The array of entry object\n *\n * @returns An object containing `posts` and `comments`\n */\nconst getEntries = (entryArray: unknown) => {\n  let posts: Post[] | null = NULL;\n  let comments: Comment[] | null = NULL;\n\n  if (isArray(entryArray)) {\n    posts = [];\n    comments = [];\n\n    if (entryArray.length > 0) {\n      for (let i = 0; i < entryArray.length; i += 1) {\n        const post: unknown = entryArray[i];\n        if (isObject(post)) {\n          if ('thr$in-reply-to' in post) {\n            const commentLike = getComment(post);\n            if (commentLike) {\n              comments.push(commentLike);\n            }\n          } else {\n            const postLike = getPost(post);\n            if (postLike) {\n              posts.push(postLike);\n            }\n          }\n        }\n      }\n    }\n  }\n\n  return { posts, comments };\n};\n\n/**\n * Gets all possible information from entry object and feed object\n *\n * @param entryArray The entry array\n * @param feed The feed object\n *\n * @returns An object\n */\nconst getFeedFromEntry = (entryArray: unknown, feedObject?: unknown) => {\n  const { posts, comments } = getEntries(entryArray);\n\n  const pagination = getPagination(feedObject);\n\n  const feed: Feed = {\n    blog: getBlog(feedObject),\n    links: getLinks(getNested(feedObject, 'link')).links,\n    posts,\n    comments,\n    itemsPerPage: getItemsPerPage(feedObject),\n    startIndex: getStartIndex(feedObject),\n    totalResults: getTotalResult(feedObject),\n    selfUrl: pagination.self,\n    previousUrl: pagination.previous,\n    nextUrl: pagination.next,\n  };\n\n  return feed;\n};\n\n/**\n * Get entry array from input\n *\n * @param input The input\n *\n * if input is an object add it to an array\n * else if input is an array use it\n * otherwise null\n *\n * @returns Array of entry object\n */\nconst getEntryArray = (input: unknown) => {\n  if (isArray(input)) {\n    return input as unknown[];\n  }\n  if (isObject(input)) {\n    return [input];\n  }\n  return NULL;\n};\n\n/**\n * Get the information from Blogger feed json object\n *\n * @param input A feed object\n *\n * Possible inputs:\n *\n * ```ts\n * type Input =\n *   | { feed: { entry?: object | unknown[] } }\n *   | { entry?: object | unknown[] }\n * ```\n *\n * @returns An object containing information from feed\n */\nexport const parseFeed = (input: unknown) => {\n  const inputFeedLike = getNested(input, 'feed');\n\n  // Check if input.feed is an object\n  if (isObject(inputFeedLike)) {\n    const inputFeedEntryLike = getNested(inputFeedLike, 'entry');\n    return getFeedFromEntry(getEntryArray(inputFeedEntryLike), inputFeedLike);\n  }\n\n  const inputEntryLike = getNested(input, 'entry');\n  return getFeedFromEntry(getEntryArray(inputEntryLike));\n};\n","import { isUndefined } from '@deox/utils/predicate';\nimport { NOT_FOUND_ERRORS } from './constants';\nimport { SDKInputNotFoundError } from './errors';\nimport { Methods } from './methods';\nimport { validators } from './utils';\n\n/** Options for {@link Comments.list} */\nexport type CommentsListOptions = {\n  maxResults?: number;\n  startIndex?: number;\n  orderBy?: 'published' | 'updated';\n  publishedMin?: Date | string;\n  publishedMax?: Date | string;\n  updatedMin?: Date | string;\n  updatedMax?: Date | string;\n  summary?: boolean;\n  postId?: string;\n};\n\n/** Options for {@link Comments.get} */\nexport type CommentsGetOptions = {\n  summary?: boolean;\n};\n\n/**\n * A class having methods related to Comments\n */\nexport class Comments extends Methods {\n  /**\n   * Retrieves all the comments of the blog or a post\n   *\n   * @param options Options for filters\n   *\n   * @returns On success, an Array of Comment\n   */\n  async list(options: CommentsListOptions = {}, { signal }: { signal?: AbortSignal } = {}) {\n    const { postId } = options;\n\n    // validate post_id if provided\n    if (!isUndefined(postId)) validators.nB(postId, 'options.postId');\n\n    const result = await this.c.req(`./${postId ? `${encodeURI(postId)}/` : ''}comments/${options.summary === true ? 'summary' : 'default'}`, {\n      params: options,\n      exclude: ['query'],\n      signal,\n    });\n\n    // Make sure to filter once again if post_id is provided,\n    if (postId && result.comments) {\n      result.comments = result.comments.filter((c) => c.post.id === postId);\n    }\n\n    return this._p('comments', result);\n  }\n\n  /**\n   * Retrieves a comment\n   *\n   * @param postId The id of the post\n   * @param commentId The id of the comment\n   * @param options Options\n   *\n   * @returns On success, a Comment\n   */\n  async get(postId: string, commentId: string, options: CommentsGetOptions = {}, { signal }: { signal?: AbortSignal } = {}) {\n    validators.nB(postId, \"Argument 'postId'\");\n    validators.nB(commentId, \"Argument 'commentId'\");\n\n    const { comments } = await this.c.req(\n      `./${encodeURI(postId)}/comments/${options.summary === true ? 'summary' : 'default'}/${encodeURI(commentId)}`,\n      {\n        // We need to use blogger service base url since comments by id through domain is not available\n        baseUrl: await this.c.serviceBase,\n        exclude: ['query'],\n        signal,\n      },\n    );\n\n    const comment = comments?.find((c) => c.id === commentId);\n\n    if (!comment) throw new SDKInputNotFoundError(NOT_FOUND_ERRORS.comment);\n\n    return comment;\n  }\n}\n","import { NOT_FOUND_ERRORS } from './constants';\nimport { SDKInputNotFoundError } from './errors';\nimport { Methods } from './methods';\nimport { validators } from './utils';\n\n/** Options for {@link Pages.list} */\nexport type PagesListOptions = {\n  maxResults?: number;\n  startIndex?: number;\n  orderBy?: 'published' | 'updated';\n  publishedMin?: Date | string;\n  publishedMax?: Date | string;\n  updatedMin?: Date | string;\n  updatedMax?: Date | string;\n  summary?: boolean;\n};\n\n/** Options for {@link Pages.get} */\nexport type PagesGetOptions = { summary?: boolean };\n\n/**\n * A class having methods related to Pages\n */\nexport class Pages extends Methods {\n  /**\n   * Retrieves all the pages of the blog\n   *\n   * @param options Options for filters\n   *\n   * @returns On success, an Array of Post\n   */\n  async list(options: PagesListOptions = {}, { signal }: { signal?: AbortSignal } = {}) {\n    const result = await this.c.req(`./pages/${options.summary === true ? 'summary' : 'default'}`, {\n      params: options,\n      exclude: ['query'],\n      signal,\n    });\n\n    return this._p('posts', result);\n  }\n\n  /**\n   * Retrieves a page\n   *\n   * @param pageId The id of the page\n   * @param options Options for filters\n   *\n   * @returns On success, a Post\n   */\n  async get(pageId: string, options: PagesGetOptions = {}, { signal }: { signal?: AbortSignal } = {}) {\n    validators.nB(pageId, \"Argument 'pageId'\");\n\n    const { posts } = await this.c.req(`./pages/${options.summary === true ? 'summary' : 'default'}/${encodeURI(pageId)}`, {\n      exclude: ['query'],\n      signal,\n    });\n\n    const page = posts?.find((p) => p.id === pageId);\n\n    // Throw an error if the page was not found\n    if (!page) throw new SDKInputNotFoundError(NOT_FOUND_ERRORS.page);\n\n    return page;\n  }\n}\n","import { isUndefined } from '@deox/utils/predicate';\nimport { NOT_FOUND_ERRORS } from './constants';\nimport { SDKInputNotFoundError } from './errors';\nimport { Methods } from './methods';\nimport { validators } from './utils';\n\n/** Options for {@link Posts.list} */\nexport type PostsListOptions = {\n  maxResults?: number;\n  startIndex?: number;\n  orderBy?: 'published' | 'updated';\n  publishedMin?: Date | string;\n  publishedMax?: Date | string;\n  updatedMin?: Date | string;\n  updatedMax?: Date | string;\n  label?: string;\n  summary?: boolean;\n};\n\n/** Options for {@link Posts.get} */\nexport type PostsGetOptions = { summary?: boolean };\n\n/** Options for {@link Posts.query} */\nexport type PostsQueryOptions = Omit<PostsListOptions, 'label'>;\n\nexport class Posts extends Methods {\n  /**\n   * Retrieves all the posts of the blog\n   *\n   * @param options Options for filters\n   *\n   * @returns On success, an Array of Post\n   */\n  async list(options: PostsListOptions = {}, { signal }: { signal?: AbortSignal } = {}) {\n    const { label } = options;\n\n    // validate label if provided\n    if (!isUndefined(label)) validators.nB(label, 'options.label');\n\n    const result = await this.c.req(`./posts/${options.summary === true ? 'summary' : 'default'}${label ? `/-/${encodeURI(label)}` : ''}`, {\n      params: options,\n      exclude: ['query'],\n      signal,\n    });\n\n    return this._p('posts', result);\n  }\n\n  /**\n   * Retrieves a post\n   *\n   * @param postId The id of the post\n   * @param options Options\n   *\n   * @returns On success, a Post\n   */\n  async get(postId: string, options: PostsGetOptions = {}, { signal }: { signal?: AbortSignal } = {}) {\n    validators.nB(postId, \"Argument 'postId'\");\n\n    const { posts } = await this.c.req(`./posts/${options.summary === true ? 'summary' : 'default'}/${encodeURIComponent(postId)}`, {\n      exclude: ['query'],\n      signal,\n    });\n\n    const post = posts?.find((p) => p.id === postId);\n\n    // Throw an error if the post was not found\n    if (!post) throw new SDKInputNotFoundError(NOT_FOUND_ERRORS.post);\n\n    return post;\n  }\n\n  /**\n   * Retrieves all the posts with query\n   *\n   * @param query The query\n   * @param options Options for filters\n   *\n   * @returns On success, an Array of Post\n   */\n  async query(query: string, options: PostsQueryOptions = {}, { signal }: { signal?: AbortSignal } = {}) {\n    validators.nB(query, \"Argument 'query'\");\n\n    const result = await this.c.req(`./posts/${options.summary === true ? 'summary' : 'default'}`, {\n      params: {\n        ...options,\n        query,\n      },\n      signal,\n    });\n\n    return this._p('posts', result);\n  }\n}\n","import { Blog } from './blog';\nimport { Client } from './client';\nimport { Comments } from './comments';\nimport { SDKError, SDKInputNotFoundError, SDKRequestError, SDKTypeError } from './errors';\nimport { parseFeed } from './feed-parser';\nimport { Pages } from './pages';\nimport { Posts } from './posts';\n\n/**\n * An interface representing options for {@link BloggerFeed}\n */\nexport interface BloggerFeedOptions {\n  /**\n   * When set to `true`, enables jsonp callbacks, useful when running in browser environments to prevent cors issues.\n   *\n   * **Warning**: Set it to `true` if and only if you are running it in browser\n   * because it loads javascript by appending script element to document.\n   *\n   * @default false\n   */\n  jsonp?: boolean;\n}\n\nexport class BloggerFeed {\n  static readonly SDKError = SDKError;\n  static readonly SDKInputNotFoundError = SDKInputNotFoundError;\n  static readonly SDKRequestError = SDKRequestError;\n  static readonly SDKTypeError = SDKTypeError;\n  static readonly parseFeed = parseFeed;\n\n  readonly posts: Posts;\n  readonly pages: Pages;\n  readonly comments: Comments;\n  readonly blog: Blog;\n\n  /**\n   * Creates an instance of {@link BloggerFeed}\n   *\n   * @param urlOrId The url or id of the blog\n   * @param options Options\n   */\n  constructor(urlOrId: string | URL, options: BloggerFeedOptions = {}) {\n    const client = new Client(urlOrId, options);\n    this.posts = new Posts(client);\n    this.pages = new Pages(client);\n    this.comments = new Comments(client);\n    this.blog = new Blog(client);\n  }\n}\n"]}