- English
- 简体中文
A library for PicaComic http web api
npm install --save @l2studio/picacomic-api # or pnpm i @l2studio/picacomic-apiCurrently the API documentation for version 0.2.x. See also old documentation.
The v0.2.x is a breaking update, but more specific to type definitions. and code refactoring and optimization.
import { PicaComicAPI } from '@l2studio/picacomic-api' class PicaComicAPI { public readonly fetch: Got public readonly appOptions?: Partial<PicaComicOptions> public readonly reauthorizationTokenCallback?: (self: this) => string | undefined | Promise<string | undefined> constructor (options?: PicaComicAPIOptions) }interface PicaComicOptions { api: string apiKey: string signatureKey: string accept: string channel: '1' | '2' | '3' version: string uuid: string platform: string buildVersion: string userAgent: string imageQuality: 'original' | 'low' | 'medium' | 'high' } interface PicaComicAPIOptions { // Got instance or options (optional) // See: https://github.com/sindresorhus/got/tree/v11 fetch?: Got | ExtendOptions // PicaComic app client options (optional) // See above: PicaComicOptions appOptions?: Partial<PicaComicOptions> // Callback function used to re-authenticate and return a new token when the token is invalid. (optional) // Example: // async reauthorizationTokenCallback (self) { // console.log('Token invalid, re-authenticate...') // const response = await self.signIn({ // email : 'your picacomic account email', // password: 'your picacomic account password' // }) // return response.data.token // } reauthorizationTokenCallback?: (self: PicaComicAPI) => string | undefined | Promise<string | undefined> }class PicaComicError extends Error { readonly code: number readonly error: string readonly message: string readonly detail?: string }/** * Register a PicaComic account with the given payload. * * @param payload - RegisterPayload { * name - Nickname (2 - 50 characters) * email - Email (Allow: [0-9 a-z . _]) * password - Password (Greater than 8 characters) * question1 - Security Question 1 * question2 - 2 * question3 - 3 * answer1 - Security question 1 answer * answer2 - 2 answer * answer3 - 3 answer * birthday - Birthday ('YYYY-MM-DD' | Date | Milliseconds) Need to be 18 years or older * gender - Gender ('m' | 'f' | 'bot') * } * @return BaseResponse<undefined> */ PicaComicAPI.register(payload: RegisterPayload): Promise<BaseResponse<undefined>>/** * Sign in to the PicaComic account with the given payload. * * @param payload - SignInPayload { * email - Your PicaComic account email * password - password * } * @return SignInResponse */ PicaComicAPI.signIn(payload: SignInPayload): Promise<SignInResponse>/** * Punch in to the PicaComic account with the given payload. * * @param payload - AuthorizationPayload { token - Access token } * @return PunchInResponse */ PicaComicAPI.punchIn(payload: AuthorizationPayload): Promise<PunchInResponse>/** * Fetch user profile using the given payload. * * @param payload - AuthorizationPayload { token - Access token } * @return UserProfileResponse */ PicaComicAPI.fetchUserProfile(payload: AuthorizationPayload): Promise<UserProfileResponse>/** * Fetch user favourite comics using the given payload. * * @param payload - AuthorizationPayload & UserFavouritePayload { * token - Access token * page - Page number (optional) * sort - Sorting type (optional) * } * @return UserFavouriteResponse */ PicaComicAPI.fetchUserFavourite(payload: AuthorizationPayload & UserFavouritePayload): Promise<UserFavouriteResponse>/** * Fetch all categories using the given payload. * * @param payload - AuthorizationPayload { token - Access token } * @return CategoriesResponse */ PicaComicAPI.fetchCategories(payload: AuthorizationPayload): Promise<CategoriesResponse>/** * Fetch comics using the given payload. * * @param payload - AuthorizationPayload & ComicsPayload { * token - Access token * category - Specify category name (e.g.: 'Cosplay') * page - Page number (optional) * sort - Sorting type (optional) * } * @return ComicsResponse */ PicaComicAPI.fetchComics(payload: AuthorizationPayload & ComicsPayload): Promise<ComicsResponse>/** * Fetch comic detail using the given payload. * * @param payload - AuthorizationPayload & ComicDetailPayload { * token - Access token * comicId - Specify comic id * } * @return ComicDetailResponse */ PicaComicAPI.fetchComicDetail(payload: AuthorizationPayload & ComicDetailPayload): Promise<ComicDetailResponse>/** * Fetch comic episodes using the given payload. * * @param payload - AuthorizationPayload & ComicEpisodesPayload { * token - Access token * comicId - Specify comic id * page - Page number (optional) * } * @return ComicEpisodesResponse */ PicaComicAPI.fetchComicEpisodes(payload: AuthorizationPayload & ComicEpisodesPayload): Promise<ComicEpisodesResponse>/** * Fetch pages of the specified comic episode using the given payload. * * @param payload - AuthorizationPayload & ComicEpisodePagesPayload { * token - Access token * comicId - Specify comic id * order - Specify episode order of the comic * page - Page number (optional) * } * @return ComicEpisodePagesResponse */ PicaComicAPI.fetchComicEpisodePages(payload: AuthorizationPayload & ComicEpisodePagesPayload): Promise<ComicEpisodePagesResponse>/** * Fetch comic comments using the given payload. * * @param payload - AuthorizationPayload & ComicCommentsPayload { * token - Access token * comicId - Specify comic id * page - Page number (optional) * } * @return ComicCommentsResponse */ PicaComicAPI.fetchComicComments(payload: AuthorizationPayload & ComicCommentsPayload): Promise<ComicComments>/** * Search comics using the given payload. * * @param payload - AuthorizationPayload & SearchComicsPayload { * token - Access token * keyword - Keyword * categories - Specify category name array (e.g.: ['Cosplay']) (optional) * page - Page number (optional) * sort - Sorting type (optional) * } * @return SearchComicsResponse */ PicaComicAPI.searchComics(payload: AuthorizationPayload & SearchComicsPayload): Promise<Comics>/** * Switch the comic as like or unlike using the given payload. * * @param payload - AuthorizationPayload & ComicIdPayload { * toke - Access token * comicId - Specify comic id * } * @return SwitchComicLikeResponse */ PicaComicAPI.switchComicLike(payload: AuthorizationPayload & ComicIdPayload): Promise<SwitchComicLikeResponse>/** * Switch the comic as favourite or un_favourite using the given payload. * * @param payload - AuthorizationPayload & ComicIdPayload { * toke - Access token * comicId - Specify comic id * } * @return SwitchComicFavouriteResponse */ PicaComicAPI.switchComicFavourite(payload: AuthorizationPayload & ComicIdPayload): Promise<SwitchComicFavouriteResponse>/** * Set the slogan of the user profile with the given payload. * * @param payload - AuthorizationPayload & UserProfileSloganPayload { * toke - Access token * slogan - Slogan (Cannot be blank) * } * @return BaseResponse<undefined> */ PicaComicAPI.setUserProfileSlogan(payload: AuthorizationPayload & UserProfileSloganPayload): Promise<BaseResponse<undefined>>/** * Stringify the given image media data into image url. * * @param payload - ImageMediaPayload = ImageMedia | { * path - Path name * fileServer - File server (Optional) * } * @return string */ PicaComicAPI.stringifyImageUrl(payload: ImageMediaPayload): string/** * Create an image request from the given image media data. * * @param payload - ImageMediaPayload = ImageMedia | { * path - Path name * fileServer - File server (Optional) * } * @return Request (Got request) */ PicaComicAPI.createImageRequest(payload: ImageMediaPayload): got.Request/** * Create an image request and as buffer from the given image media data. * * @param payload - ImageMediaPayload = ImageMedia | { * path - Path name * fileServer - File server (Optional) * } * @return Buffer */ PicaComicAPI.createImageRequestAsBuffer(payload: ImageMediaPayload): Promise<Buffer>The client is just a wrapper for a single account operation, and does not need to handle the problem of token invalidation by itself.
Note: The client is similar to the API, but does not provide
registerandsignInmethods. Thepayloadparameters of other methods do not need to provide thetokenaccess token property.
import { PicaComicClient } from '@l2studio/picacomic-api' export class PicaComicClient { public readonly email: string public readonly password: string public readonly api: PicaComicAPI public readonly onTokenIssued?: (token: string) => void | Promise<void> public token: string constructor (options: PicaComicClientOptions) }interface PicaComicClientOptions extends Omit<PicaComicAPIOptions, 'reauthorizationTokenCallback'> { /// Extende PicaComicAPIOptions options /// See above fetch?: Got | ExtendOptions appOptions?: Partial<PicaComicOptions> /// // Owned options email: string // PicaComic account email password: string // PicaComic account password token?: string // PicaComic account access token (Optional) // Callback function for re-authenticate and consuming a new token when the token is invalid. (Optional) // Example: // onTokenIssued (token) { // console.log('New token:', token) // fs.writeFileSync('token.txt', token) // } onTokenIssued?: (token: string) => void | Promise<void> }When the token expires, it will re-login and renew the token and persistence. No need to provide token every time.
import { PicaComicClient } from '@l2studio/picacomic-api' import path from 'path' import fs from 'fs' const tokenFile = path.join(__dirname, '.token') // Persistent token const picacomic = new PicaComicClient({ email : 'your picacomic email', password: 'your picacomic password', token: fs.existsSync(tokenFile) ? fs.readFileSync(tokenFile, 'utf8') : undefined, onTokenIssued (token) { console.log('New token:', token) fs.writeFileSync(tokenFile, token) // Update persistent token } }) ;(async () => { const response = await picacomic.fetchComics({ category: 'Cosplay' }) console.log(response) })()See also Got agent.
Please configure the fetch property of PicaComicAPIOptions or PicaComicClientOptions.
Example using tunnel:
import { PicaComicClient } from '@l2studio/picacomic-api' import tunnel from 'tunnel' const picacomic = new PicaComicClient({ fetch: { agent: { https: tunnel.httpsOverHttp({ // Your http proxy server host and port proxy: { host: '127.0.0.1', port: 10809 } }) as any } }, ...other })Apache-2.0