import ky from 'ky' ; import { LABEL } from '../constants' ; import { loadZip } from './loadZip' ; const api = ky . create ( { credentials : 'same-origin' , cache : 'no-store' , retry : 1 , } ) ; param { string } illustId export const fetchPages = async ( illustId ) => { try { const { body , error , message , } = await api . get ( `/ajax/illust/${ illustId }/pages` , { cache : 'force-cache' } ) . json < Pixiv . ResponseData < Pixiv . Pages > > ( ) ; if ( error ) throw new Error ( message ) ; return body ; } catch ( error ) { console . error ( `${ LABEL }: failed fetchPages` , error ) ; return null ; } } ; param { string } illustId export const fetchUgoira = async ( illustId ) => { try { const { body , error , message , } = await api . get ( `/ajax/illust/${ illustId }/ugoira_meta` , { cache : 'force-cache' } ) . json < Pixiv . ResponseData < Pixiv . Ugoira > > ( ) ; if ( error ) throw new Error ( message ) ; return loadZip ( body ) ; } catch ( error ) { console . error ( `${ LABEL }: failed fetchUgoira` , error ) ; return null ; } } ; param { string } illustId export const fetchIllust = async ( illustId ) => { try { const { body , error , message } = await api . get ( `/ajax/illust/${ illustId }` ) . json < Pixiv . ResponseData < Pixiv . Illust > > ( ) ; if ( error ) throw new Error ( message ) ; return body ; } catch ( error ) { console . error ( `${ LABEL }: failed fetchIllust` , error ) ; return null ; } } ; param { string } userId export const fetchUser = async ( userId ) => { try { const { body , error , message } = await api . get ( `/ajax/user/${ userId }?full=1` ) . json < Pixiv . ResponseData < Pixiv . User > > ( ) ; if ( error ) throw new Error ( message ) ; return body ; } catch ( error ) { console . error ( `${ LABEL }: failed fetchUser` , error ) ; return null ; } } ; param { string } userId export const fetchRelatedIllusts = async ( userId ) => { try { const { body , error , message } = await api . get ( `/ajax/user/${ userId }/profile/top` ) . json < Pixiv . ResponseData < Pixiv . Works > > ( ) ; if ( error ) throw new Error ( message ) ; return mergeWorks ( body ) ; } catch ( error ) { console . error ( `${ LABEL }: failed fetchRelatedIllusts` , error ) ; return null ; } } ; const mergeWorks = ( { illusts , manga } ) : Pixiv . RelatedIllusts => { const data = { ... illusts , ... manga } ; return Object . values ( data ) . reverse ( ) ; } ; param { 'illust' } type param { string } illust_id export const fetchBookmarkForm = async ( illustId ) => { try { const data = await api . get ( '/bookmark_add.php' , { searchParams : { type : 'illust' , illust_id : illustId } , } ) . text ( ) ; return parseFormHTML ( data ) ; } catch ( error ) { console . error ( `${ LABEL }: failed fetchBookmarkForm` , error ) ; return null ; } } ; const parseFormHTML = ( html ) => { const doc = new DOMParser ( ) . parseFromString ( html , 'text/html' ) ; const form = doc . querySelector < HTMLFormElement > ( 'form[action^="bookmark_add.php"]' ) ! ; const data = new FormData ( form ) ; const script = doc . querySelector ( '.tag-cloud-container + script' ) ! ; const userTags = parseUserTagList ( script . innerHTML ) ; const res = { comment : '' , tags : '' , restrict : false , userTags , } ; for ( const [ name , value ] of data . entries ( ) ) { if ( name === 'comment' ) { res . comment = value as string ; } else if ( name === 'tag' ) { res . tags = value as string ; } else if ( name === 'restrict' ) { res . restrict = ! ! Number ( value ) ; } } return res ; } ; const parseUserTagList = ( text ) : Pixiv . UserTag [ ] => { const parsedText = JSON . parse ( text . slice ( 21 , - 1 ) ) ; const userTags = JSON . parse ( parsedText ) ; return Object . entries ( userTags ) . map ( ( [ name , value ] ) => ( { ... value , name , } ) ) ; } ; param { string } illsut_id export const likeBy = async ( illustId ) => { const { token } = await fetchGlobal ( ) ; const { body , error , message } = await api . post ( '/ajax/illusts/like' , { headers : { 'x-csrf-token' : token } , json : { illust_id : illustId } , } ) . json < Pixiv . ResponseData < Pixiv . LikeData > > ( ) ; if ( error ) throw new Error ( message ) ; return body ; } ; param { string } illust_id param { number } restrict param { stirng } comment param { string [ ] } tags export const bookmarkBy = async ( illustId , { restrict = false , comment = '' , tags = [ ] } ) => { const { token } = await fetchGlobal ( ) ; const { body , error , message } = await api . post ( '/ajax/illusts/bookmarks/add' , { headers : { 'x-csrf-token' : token } , json : { illust_id : illustId , restrict : restrict ? 1 : 0 , comment , tags , } , } ) . json < Pixiv . ResponseData < Pixiv . BookmarkValue > > ( ) ; if ( error ) throw new Error ( message ) ; return body ; } ; param { 'add' } mode param { 'user' } type param { string } user_id param { 0 | 1 } restrict param { 'json' } format param { string } tt export const followUser = async ( userId , restrict ) => { const { token , userId : myId } = await fetchGlobal ( ) ; if ( myId === userId ) throw new Error ( `This user is yourself` ) ; const searchParams = new URLSearchParams ( ) ; searchParams . append ( 'mode' , 'add' ) ; searchParams . append ( 'type' , 'user' ) ; searchParams . append ( 'user_id' , userId ) ; searchParams . append ( 'tag' , '' ) ; searchParams . append ( 'restrict' , restrict ? '1' : '0' ) ; searchParams . append ( 'format' , 'json' ) ; return await api . post ( '/bookmark_add.php' , { headers : { 'x-csrf-token' : token } , body : searchParams , } ) . json < never > ( ) ; } ; declare var pixiv ; declare var globalInitData ; const savedGlobal = { token : '' , userId : '' } ; export const fetchGlobal = async ( ) => { if ( savedGlobal . token . length ) return savedGlobal ; if ( typeof pixiv !== 'undefined' ) { savedGlobal . token = pixiv . context . token ; savedGlobal . userId = pixiv . user . id ; return savedGlobal ; } if ( typeof globalInitData !== 'undefined' ) { savedGlobal . token = globalInitData . token ; savedGlobal . userId = globalInitData . userData . id ; return savedGlobal ; } const data = await api . get ( location . href ) . text ( ) ; const parsedData = parseGlobal ( data ) ; savedGlobal . token = parsedData . token ; savedGlobal . userId = parsedData . userId ; return savedGlobal ; } ; const parseGlobal = ( html ) => { const doc = new DOMParser ( ) . parseFromString ( html , 'text/html' ) ; const meta = doc . querySelector < HTMLMetaElement > ( '#meta-global-data' ) ! ; const { token , userData } = JSON . parse ( meta . content ) ; const userId = userData . id ; return { token , userId } ; } ;