{"version":3,"file":"index.common-CYj0n0aU.cjs","names":["count","id: CallbackId","R18SiteNotation: { readonly [K in R18Site]: string }","BigGenreNotation: { readonly [K in BigGenre]: string }","GenreNotation: { readonly [K in Genre]: string }","params: TParams","api: NarouNovel","count","n: number | string","date: string","params: Partial<RankingParams>","api: NarouNovel"],"sources":["../src/narou-search-results.ts","../src/narou.ts","../src/util/jsonp.ts","../src/narou-jsonp.ts","../src/params.ts","../src/search-builder.ts","../src/util/date.ts","../src/ranking.ts","../src/ranking-history.ts","../src/search-builder-r18.ts","../src/user-search.ts"],"sourcesContent":["import type {\n  BooleanNumber as BooleanNumber,\n  Genre,\n  R18Site,\n  SearchParams,\n  Fields,\n  BigGenre,\n  R18Fields,\n  OptionalFields,\n  UserFields,\n  UserSearchParams,\n} from \"./params.js\";\n\n/**\n * なろう小説API検索結果\n */\nexport default class NarouSearchResults<T, TKey extends keyof T> {\n  /**\n   * 検索結果数\n   */\n  allcount: number;\n  /**\n   * 結果表示上限数\n   */\n  limit: number;\n  /**\n   * 結果表示開始数\n   */\n  start: number;\n  /**\n   * 結果表示の現在ページ(=start/limit)\n   */\n  page: number;\n  /**\n   * 今回取得できた検索結果の数\n   */\n  length: number;\n  /**\n   * 検索結果\n   */\n  values: readonly Pick<T, TKey>[];\n\n  /**\n   * @constractor\n   * @private\n   */\n  constructor(\n    [header, ...result]: [{ allcount: number }, ...Pick<T, TKey>[]],\n    params: SearchParams | UserSearchParams\n  ) {\n    const count = header.allcount;\n    const limit = params.lim ?? 20;\n    const start = params.st ?? 0;\n\n    this.allcount = count;\n    this.limit = limit;\n    this.start = start;\n    this.page = start / limit;\n    this.length = result.length;\n    this.values = result;\n  }\n}\n\n/**\n * 小説情報\n * @see https://dev.syosetu.com/man/api/#output\n * @see https://dev.syosetu.com/xman/api/#output\n */\nexport interface NarouSearchResult {\n  /** 小説名 */\n  title: string;\n  /** Nコード */\n  ncode: string;\n  /** 作者のユーザID(数値) */\n  userid: number;\n  /** 作者名 */\n  writer: string;\n  /** 小説のあらすじ */\n  story: string;\n  /** 掲載サイト */\n  nocgenre: R18Site;\n  /** 大ジャンル */\n  biggenre: BigGenre;\n  /** ジャンル */\n  genre: Genre;\n  /** キーワード */\n  keyword: string;\n  /** 初回掲載日 YYYY-MM-DD HH:MM:SSの形式 */\n  general_firstup: string;\n  /** 最終掲載日 YYYY-MM-DD HH:MM:SSの形式 */\n  general_lastup: string;\n  /** 連載の場合は1、短編の場合は2 */\n  novel_type: NovelType;\n  /** 連載の場合は1、短編の場合は2 */\n  noveltype: NovelType;\n  /** 短編小説と完結済小説は0となっています。連載中は1です。 */\n  end: End;\n  /** 全掲載話数です。短編の場合は1です。 */\n  general_all_no: number;\n  /** 小説文字数です。スペースや改行は文字数としてカウントしません。 */\n  length: number;\n  /** 読了時間(分単位)です。読了時間は小説文字数÷500を切り上げした数値です。 */\n  time: number;\n  /** 長期連載中は1、それ以外は0です。 */\n  isstop: BooleanNumber;\n  /** 登録必須キーワードに「R15」が含まれる場合は1、それ以外は0です。 */\n  isr15: BooleanNumber;\n  /** 登録必須キーワードに「ボーイズラブ」が含まれる場合は1、それ以外は0です。 */\n  isbl: BooleanNumber;\n  /** 登録必須キーワードに「ガールズラブ」が含まれる場合は1、それ以外は0です。 */\n  isgl: BooleanNumber;\n  /** 登録必須キーワードに「残酷な描写あり」が含まれる場合は1、それ以外は0です。 */\n  iszankoku: BooleanNumber;\n  /** 登録必須キーワードに「異世界転生」が含まれる場合は1、それ以外は0です。 */\n  istensei: BooleanNumber;\n  /** 登録必須キーワードに「異世界転移」が含まれる場合は1、それ以外は0です。 */\n  istenni: BooleanNumber;\n  /** 総合得点(=(ブックマーク数×2)+評価点) */\n  global_point: number;\n  /**\n   * 日間ポイント\n   * ランキング集計時点から過去24時間以内で新たに登録されたブックマークや評価が対象\n   */\n  daily_point: number;\n  /**\n   * 週間ポイント\n   * ランキング集計時点から過去7日以内で新たに登録されたブックマークや評価が対象\n   */\n  weekly_point: number;\n  /**\n   * 月間ポイント\n   * ランキング集計時点から過去30日以内で新たに登録されたブックマークや評価が対象\n   */\n  monthly_point: number;\n  /**\n   * 四半期ポイント\n   * ランキング集計時点から過去90日以内で新たに登録されたブックマークや評価が対象\n   */\n  quarter_point: number;\n  /**\n   * 年間ポイント\n   * ランキング集計時点から過去365日以内で新たに登録されたブックマークや評価が対象\n   */\n  yearly_point: number;\n  /** ブックマーク数 */\n  fav_novel_cnt: number;\n  /** 感想数 */\n  impression_cnt: number;\n  /** レビュー数 */\n  review_cnt: number;\n  /** 評価ポイント */\n  all_point: number;\n  /** 評価者数 */\n  all_hyoka_cnt: number;\n  /** 挿絵の数 */\n  sasie_cnt: number;\n  /**\n   * 会話率\n   * @see https://dev.syosetu.com/man/kaiwa/\n   */\n  kaiwaritu: number;\n  /**\n   * 小説の更新日時\n   */\n  novelupdated_at: string;\n  /**\n   * 最終更新日時\n   * システム用で小説更新時とは関係ありません\n   */\n  updated_at: string;\n  /** 週間ユニークユーザー数 */\n  weekly_unique: number;\n}\n\n/**\n * ユーザ情報\n * @see https://dev.syosetu.com/man/userapi/#output\n */\nexport interface UserSearchResult {\n  /** ユーザID */\n  userid: number;\n  /** ユーザ名 */\n  name: string;\n  /** ユーザ名のフリガナ */\n  yomikata: string;\n  /**\n   * ユーザ名のフリガナの頭文字\n   * ひらがな以外の場合はnullまたは空文字となります。\n   */\n  name1st: string;\n  /** 小説投稿数 */\n  novel_cnt: number;\n  /** レビュー投稿数 */\n  review_cnt: number;\n  /**\n   * 小説累計文字数\n   * スペースや改行は文字数としてカウントしません。\n   */\n  novel_length: number;\n  /**\n   * 総合評価ポイントの合計\n   * 投稿済小説でそれぞれ獲得した総合評価ポイントの合計です。\n   */\n  sum_global_point: number;\n}\n\n/**\n * noveltype/novel_typeの値ヘルパー\n */\nexport const NovelType = {\n  /** 連載 */\n  Rensai: 1,\n  /** 短編 */\n  Tanpen: 2,\n} as const;\nexport type NovelType = typeof NovelType[keyof typeof NovelType];\n\n/**\n * endの値ヘルパー\n */\nexport const End = {\n  /** 短編小説と完結済小説 */\n  KanketsuOrTanpen: 0,\n  /** 連載中 */\n  Rensai: 1,\n} as const;\nexport type End = typeof End[keyof typeof End];\n\nexport type SearchResultFields<T extends Fields> = {\n  [K in keyof typeof Fields]: typeof Fields[K] extends T ? K : never;\n}[keyof typeof Fields];\n\nexport type SearchResultOptionalFields<T extends OptionalFields> = {\n  [K in keyof typeof OptionalFields]: typeof OptionalFields[K] extends T\n  ? K\n  : never;\n}[keyof typeof OptionalFields];\n\nexport type SearchResultR18Fields<T extends R18Fields> = {\n  [K in keyof typeof R18Fields]: typeof R18Fields[K] extends T ? K : never;\n}[keyof typeof R18Fields];\n\nexport type UserSearchResultFields<T extends UserFields> = {\n  [K in keyof typeof UserFields]: typeof UserFields[K] extends T ? K : never;\n}[keyof typeof UserFields];\n\nexport type PickedNarouSearchResult<T extends keyof NarouSearchResult> = Pick<\n  NarouSearchResult,\n  T\n>;\n","import type { NarouRankingResult } from \"./narou-ranking-results.js\";\nimport NarouSearchResults from \"./narou-search-results.js\";\nimport type {\n  NarouSearchResult,\n  UserSearchResult,\n} from \"./narou-search-results.js\";\nimport type {\n  RankingHistoryParams,\n  RankingParams,\n  SearchParams,\n  UserSearchParams,\n} from \"./params.js\";\nimport type { RankingHistoryRawResult } from \"./ranking-history.js\";\n\n/**\n * なろう小説APIへのリクエストパラメータ\n */\nexport type NarouParams =\n  | SearchParams\n  | RankingParams\n  | RankingHistoryParams\n  | UserSearchParams;\n\n/**\n * なろう小説APIへのリクエストオプション\n */\nexport interface ExecuteOptions {\n  /**\n   * fetch関数のオプション\n   */\n  fetchOptions?: RequestInit;\n}\n\n/**\n * なろう小説APIへのリクエストを実行する\n * @class NarouNovel\n * @private\n */\nexport default abstract class NarouNovel {\n  /**\n   * なろうAPIへのAPIリクエストを実行する\n   * @param params クエリパラメータ\n   * @param endpoint APIエンドポイント\n   * @returns 実行結果\n   */\n  protected abstract execute<T>(\n    params: NarouParams,\n    endpoint: string,\n    options?: ExecuteOptions\n  ): Promise<T>;\n\n  /**\n   * APIへの検索リクエストを実行する\n   * @param params クエリパラメータ\n   * @param endpoint APIエンドポイント\n   * @returns 検索結果\n   */\n  protected async executeSearch<T extends keyof NarouSearchResult>(\n    params: SearchParams,\n    endpoint = \"https://api.syosetu.com/novelapi/api/\",\n    options?: ExecuteOptions\n  ): Promise<NarouSearchResults<NarouSearchResult, T>> {\n    return new NarouSearchResults(\n      await this.execute(params, endpoint, options),\n      params\n    );\n  }\n\n  /**\n   * 小説APIへの検索リクエストを実行する\n   * @param params クエリパラメータ\n   * @returns 検索結果\n   * @see https://dev.syosetu.com/man/api/\n   */\n  async executeNovel<T extends keyof NarouSearchResult>(\n    params: SearchParams,\n    options?: ExecuteOptions\n  ): Promise<NarouSearchResults<NarouSearchResult, T>> {\n    return await this.executeSearch(\n      params,\n      \"https://api.syosetu.com/novelapi/api/\",\n      options\n    );\n  }\n\n  /**\n   * R18小説APIへの検索リクエストを実行する\n   * @param params クエリパラメータ\n   * @returns 検索結果\n   * @see https://dev.syosetu.com/xman/api/\n   */\n  async executeNovel18<T extends keyof NarouSearchResult>(\n    params: SearchParams,\n    options?: ExecuteOptions\n  ): Promise<NarouSearchResults<NarouSearchResult, T>> {\n    return await this.executeSearch(\n      params,\n      \"https://api.syosetu.com/novel18api/api/\",\n      options\n    );\n  }\n\n  /**\n   * ランキングAPIへのリクエストを実行する\n   * @param params クエリパラメータ\n   * @returns ランキング結果\n   * @see https://dev.syosetu.com/man/rankapi/\n   */\n  async executeRanking(\n    params: RankingParams,\n    options?: ExecuteOptions\n  ): Promise<NarouRankingResult[]> {\n    return await this.execute(\n      params,\n      \"https://api.syosetu.com/rank/rankget/\",\n      options\n    );\n  }\n\n  /**\n   * 殿堂入りAPiへのリクエストを実行する\n   * @param params クエリパラメータ\n   * @param options 実行オプション\n   * @returns ランキング履歴結果\n   * @see https://dev.syosetu.com/man/rankinapi/\n   */\n  async executeRankingHistory(\n    params: RankingHistoryParams,\n    options?: ExecuteOptions\n  ): Promise<RankingHistoryRawResult[]> {\n    return await this.execute(\n      params,\n      \"https://api.syosetu.com/rank/rankin/\",\n      options\n    );\n  }\n\n  /**\n   * ユーザー検索APIへのリクエストを実行する\n   * @param params クエリパラメータ\n   * @returns 検索結果\n   * @see https://dev.syosetu.com/man/userapi/\n   */\n  async executeUserSearch<T extends keyof UserSearchResult>(\n    params: UserSearchParams,\n    options?: ExecuteOptions\n  ): Promise<NarouSearchResults<UserSearchResult, T>> {\n    return new NarouSearchResults<UserSearchResult, T>(\n      await this.execute(\n        params,\n        \"https://api.syosetu.com/userapi/api/\",\n        options\n      ),\n      params\n    );\n  }\n}\n","/**\n * MIT license\n */\n\n// Callback index.\nlet count = 0;\n\ntype CallbackId<Prefix extends string = string> = `${Prefix}${number}`;\n\ndeclare global {\n  interface Window {\n    // eslint-disable-next-line @typescript-eslint/no-explicit-any\n    [key: CallbackId]: (data: any) => void;\n  }\n}\n\n/**\n * JSONP呼び出しのオプション設定\n */\nexport type JsonpOption = {\n  /**\n   * コールバック関数名のプレフィックス\n   * @default \"__jp\"\n   */\n  prefix?: string;\n  \n  /**\n   * コールバック関数名を指定するURLパラメータ名\n   * @default \"callback\"\n   */\n  param?: string;\n  \n  /**\n   * タイムアウト時間（ミリ秒）\n   * @default 15000\n   */\n  timeout?: number;\n};\n\nconst noop = function () { };\n\n/**\n * JSONPリクエストを実行してデータを取得します。\n * \n * @param url - リクエスト先のURL\n * @param options - JSONP呼び出しのオプション設定\n * @returns JSONPリクエストの結果をPromiseで返します\n * @throws {Error} タイムアウトが発生した場合、\"Timeout\"メッセージのエラーをスローします\n * \n * @example\n * ```typescript\n * // 基本的な使用方法\n * const data = await jsonp<ResponseType>('https://example.com/api');\n * \n * // オプション指定\n * const data = await jsonp<ResponseType>('https://example.com/api', {\n *   prefix: 'customPrefix',\n *   param: 'callbackParam',\n *   timeout: 10000\n * });\n * ```\n */\nexport function jsonp<T>(\n  url: string,\n  { prefix = \"__jp\", param = \"callback\", timeout = 15000 }: JsonpOption = {}\n): Promise<T> {\n  return new Promise(function (resolve, reject) {\n    // 最初のscriptタグを取得し、そのタグの直前に新しいscriptタグを挿入するための参照を取得\n    // これにより、ページの構造を大きく変えることなくscriptを追加できる\n    const targetChild = document.getElementsByTagName(\"script\").item(0);\n    const target = targetChild?.parentNode ?? document.head;\n\n    // ユニークなコールバック関数名を生成\n    const id: CallbackId = `${prefix}${count++}`;\n    \n    // リソース解放用の関数を定義\n    // スクリプトタグの削除、コールバック関数のクリーンアップ、タイマーのクリアを行う\n    const cleanup = function () {\n      // Remove the script tag.\n      if (script && script.parentNode) {\n        script.parentNode.removeChild(script);\n      }\n\n      // コールバック関数を空の関数に置き換えてメモリリークを防止\n      window[id] = noop;\n\n      if (timer) {\n        clearTimeout(timer);\n      }\n    };\n\n    // タイムアウト処理の設定\n    // 指定された時間内にレスポンスがない場合はエラーとして処理\n    const timer =\n      timeout > 0\n        ? setTimeout(() => {\n          cleanup();\n          reject(new Error(\"Timeout\"));\n        }, timeout)\n        : undefined;\n\n    // サーバーからのレスポンスを処理するコールバック関数\n    const callback = (data: T) => {\n      cleanup();\n      resolve(data);\n    };\n    \n    // グローバルスコープにコールバック関数を登録\n    // これによりJSONPのレスポンスから関数が呼び出せるようになる\n    window[id] = callback;\n\n    // JSONPリクエスト用のscriptタグを作成\n    const script = document.createElement(\"script\");\n    const urlObj = new URL(url);\n    \n    // URLにコールバック関数名をパラメータとして追加\n    urlObj.searchParams.set(param, id);\n    script.setAttribute(\"src\", urlObj.toString());\n    \n    // DOMにscriptタグを挿入し、リクエストを開始\n    target.insertBefore(script, targetChild);\n  });\n}\n","import NarouNovel from \"./narou.js\";\nimport type { NarouParams, ExecuteOptions } from \"./narou.js\";\nimport { jsonp } from \"./util/jsonp.js\";\n\n/**\n * なろう小説APIへのリクエストを実行する\n */\nexport default class NarouNovelJsonp extends NarouNovel {\n  protected async execute<T>(\n    params: NarouParams,\n    endpoint: string,\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\n    _options?: ExecuteOptions\n  ): Promise<T> {\n    const query = { ...params, out: \"jsonp\" };\n    query.gzip = 0;\n\n    const url = new URL(endpoint);\n\n    Object.entries(query).forEach(([key, value]) => {\n      if (value !== undefined) {\n        url.searchParams.append(key, value.toString());\n      }\n    });\n\n    return await jsonp(url.toString());\n  }\n}\n","import type {\n  NarouSearchResult,\n  UserSearchResult,\n} from \"./narou-search-results.js\";\nimport type { Join } from \"./util/type.js\";\n\nexport const RankingType = {\n  Daily: \"d\",\n  Weekly: \"w\",\n  Monthly: \"m\",\n  Quarterly: \"q\",\n} as const;\nexport type RankingType = (typeof RankingType)[keyof typeof RankingType];\n\n/**\n * すべてのAPIで共通のクエリパラメータ\n */\nexport interface ParamsBase {\n  /**\n   * gzip圧縮してgzipファイルとして返します。\n   * gzip圧縮レベルを1～5で指定できます。\n   * 転送量上限を減らすためにも推奨\n   */\n  gzip?: GzipLevel;\n  /**\n   * 出力形式を指定\n   * 本ライブラリはJSONとJSONPのみ対応\n   */\n  out?: \"json\" | \"jsonp\";\n}\n\n/**\n * 検索APIで共通のクエリパラメータ\n */\nexport interface ParamsBaseWithOrder<TOrder extends string> extends ParamsBase {\n  /**\n   * 出力する項目を個別に指定できます。未指定時は全項目出力されます。\n   * 転送量軽減のため、このパラメータの使用が推奨されます。\n   */\n  of?: string;\n  /**\n   * 最大出力数を指定できます。指定しない場合は20件になります。\n   */\n  lim?: number;\n  /**\t表示開始位置の指定です。 */\n  st?: number;\n  /** 出力順序を指定できます。 */\n  order?: TOrder;\n}\n\n/**\n * メソッドにパラメータを指定する際のヘルパー。\n * @see https://dev.syosetu.com/man/api/\n * @see https://dev.syosetu.com/xman/atom/\n */\nexport interface SearchParams extends ParamsBaseWithOrder<Order> {\n  word?: string;\n  notword?: string;\n  title?: BooleanNumber;\n  ex?: BooleanNumber;\n  keyword?: BooleanNumber;\n  wname?: BooleanNumber;\n\n  biggenre?: Join<BigGenre> | BigGenre;\n  notbiggenre?: Join<BigGenre> | BigGenre;\n  genre?: Join<Genre> | Genre;\n  notgenre?: Join<Genre> | Genre;\n  userid?: Join<number> | number;\n\n  nocgenre?: Join<R18Site> | R18Site;\n  notnocgenre?: Join<R18Site> | R18Site;\n  xid?: Join<number> | number;\n\n  isr15?: BooleanNumber;\n  isbl?: BooleanNumber;\n  isgl?: BooleanNumber;\n  iszankoku?: BooleanNumber;\n  istensei?: BooleanNumber;\n  istenni?: BooleanNumber;\n  istt?: BooleanNumber;\n\n  notr15?: BooleanNumber;\n  notbl?: BooleanNumber;\n  notgl?: BooleanNumber;\n  notzankoku?: BooleanNumber;\n  nottensei?: BooleanNumber;\n  nottenni?: BooleanNumber;\n\n  minlen?: number;\n  maxlen?: number;\n  length?: number | Join<number | \"\">;\n\n  kaiwaritu?: number | string;\n  sasie?: number | string;\n\n  mintime?: number;\n  maxtime?: number;\n  time?: number | string;\n\n  ncode?: string | Join<string>;\n\n  type?: NovelTypeParam;\n\n  buntai?: BuntaiParam | Join<BuntaiParam>;\n\n  stop?: StopParam;\n\n  ispickup?: typeof BooleanNumber.True;\n  lastup?: string;\n  lastupdate?: string;\n\n  opt?: Join<OptionalFields>;\n}\n\nexport interface RankingParams extends ParamsBase {\n  rtype: `${string}-${RankingType}`;\n}\n\nexport interface RankingHistoryParams extends ParamsBase {\n  ncode: string;\n}\n\n/**\n * ユーザー検索パラメータ\n */\nexport interface UserSearchParams extends ParamsBaseWithOrder<UserOrder> {\n  /** 単語を指定できます。半角または全角スペースで区切るとAND抽出になります。部分一致でHITします。検索の対象はユーザ名とユーザ名のフリガナです。 */\n  word?: string;\n  /** 含みたくない単語を指定できます。スペースで区切ることにより含ませない単語を増やせます。部分一致で除外されます。除外の対象はユーザ名とユーザ名のフリガナです。 */\n  notword?: string;\n  /** ユーザIDで抽出可能。 */\n  userid?: number;\n  /** 抽出するユーザのユーザ名のフリガナの頭文字を指定できます。頭文字はユーザ名のフリガナをひらがなに変換し、最初の1文字が「ぁ」～「ん」の場合に対象となります。 */\n  name1st?: string;\n  /** 抽出するユーザの小説投稿数の下限を指定できます。小説投稿件数が指定された数値以上のユーザを抽出します。 */\n  minnovel?: number;\n  /** 抽出するユーザの小説投稿数の上限を指定できます。小説投稿件数が指定された数値以下のユーザを抽出します。 */\n  maxnovel?: number;\n  /** 抽出するユーザのレビュー投稿数の下限を指定できます。レビュー投稿件数が指定された数値以上のユーザを抽出します。 */\n  minreview?: number;\n  /** 抽出するユーザのレビュー投稿数の上限を指定できます。レビュー投稿件数が指定された数値以下のユーザを抽出します。 */\n  maxreview?: number;\n}\n\nexport const BooleanNumber = {\n  True: 1,\n  False: 0,\n} as const;\nexport type BooleanNumber = (typeof BooleanNumber)[keyof typeof BooleanNumber];\n\nexport type SearchResultFieldNames = keyof NarouSearchResult;\n\n/**\n * なろう小説APIのofパラメータに指定できる出力する項目\n * @see https://dev.syosetu.com/man/api/#output\n */\nexport const Fields = {\n  /** 小説名 */\n  title: \"t\",\n  /** Nコード */\n  ncode: \"n\",\n  /** 作者のユーザID(数値) */\n  userid: \"u\",\n  /** 作者名 */\n  writer: \"w\",\n  /** 小説のあらすじ */\n  story: \"s\",\n  /** 大ジャンル */\n  biggenre: \"bg\",\n  /** ジャンル */\n  genre: \"g\",\n  /** キーワード */\n  keyword: \"k\",\n  /** 初回掲載日 */\n  general_firstup: \"gf\",\n  /** 最終掲載日 */\n  general_lastup: \"gl\",\n  /** 連載の場合は1、短編の場合は2 */\n  noveltype: \"nt\",\n  /** 短編小説と完結済小説は0となっています。連載中は1です。 */\n  end: \"e\",\n  /** 全掲載部分数 */\n  general_all_no: \"ga\",\n  /** 小説文字数 */\n  length: \"l\",\n  /** 読了時間(分単位) */\n  time: \"ti\",\n  /** 長期連載停止中 */\n  isstop: \"i\",\n  /** 登録必須キーワードに「R15」が含まれる場合は1、それ以外は0です。 */\n  isr15: \"isr\",\n  /** 登録必須キーワードに「ボーイズラブ」が含まれる場合は1、それ以外は0です。 */\n  isbl: \"ibl\",\n  /** 登録必須キーワードに「ガールズラブ」が含まれる場合は1、それ以外は0です。 */\n  isgl: \"igl\",\n  /** 登録必須キーワードに「残酷な描写あり」が含まれる場合は1、それ以外は0です。 */\n  iszankoku: \"izk\",\n  /** 登録必須キーワードに「異世界転生」が含まれる場合は1、それ以外は0です。 */\n  istensei: \"its\",\n  /** 登録必須キーワードに「異世界転移」が含まれる場合は1、それ以外は0です。 */\n  istenni: \"iti\",\n  /** 総合評価ポイント */\n  global_point: \"gp\",\n  /** 日間ポイント */\n  daily_point: \"dp\",\n  /** 週間ポイント */\n  weekly_point: \"wp\",\n  /** 月間ポイント */\n  monthly_point: \"mp\",\n  /** 四半期ポイント */\n  quarter_point: \"qp\",\n  /** 年間ポイント */\n  yearly_point: \"yp\",\n  /** ブックマーク数 */\n  fav_novel_cnt: \"f\",\n  /** 感想数 */\n  impression_cnt: \"imp\",\n  /** レビュー数 */\n  review_cnt: \"r\",\n  /** 評価ポイント */\n  all_point: \"a\",\n  /** 評価者数 */\n  all_hyoka_cnt: \"ah\",\n  /** 挿絵の数 */\n  sasie_cnt: \"sa\",\n  /** 会話率 */\n  kaiwaritu: \"ka\",\n  /** 小説の更新日時 */\n  novelupdated_at: \"nu\",\n  /**\n   * 最終更新日時\n   * システム用で小説更新時とは関係ありません\n   */\n  updated_at: \"ua\",\n} as const;\n\nexport type Fields = (typeof Fields)[keyof Omit<\n  NarouSearchResult,\n  \"novel_type\" | \"weekly_unique\" | \"nocgenre\"\n>];\n\n/**\n * なろうR18小説APIのofパラメータに指定できる出力する項目\n * @see https://dev.syosetu.com/xman/api/#output\n */\nexport const R18Fields = {\n  /** 小説名 */\n  title: \"t\",\n  /** Nコード */\n  ncode: \"n\",\n  /** 作者のユーザID(数値) */\n  userid: \"u\",\n  /** 作者名 */\n  writer: \"w\",\n  /** 小説のあらすじ */\n  story: \"s\",\n  /** 掲載サイト */\n  nocgenre: \"ng\",\n  /** キーワード */\n  keyword: \"k\",\n  /** 初回掲載日 */\n  general_firstup: \"gf\",\n  /** 最終掲載日 */\n  general_lastup: \"gl\",\n  /** 連載の場合は1、短編の場合は2 */\n  noveltype: \"nt\",\n  /** 短編小説と完結済小説は0となっています。連載中は1です。 */\n  end: \"e\",\n  /** 全掲載部分数 */\n  general_all_no: \"ga\",\n  /** 小説文字数 */\n  length: \"l\",\n  /** 読了時間(分単位) */\n  time: \"ti\",\n  /** 長期連載停止中 */\n  isstop: \"i\",\n  /** 登録必須キーワードに「ボーイズラブ」が含まれる場合は1、それ以外は0です。 */\n  isbl: \"ibl\",\n  /** 登録必須キーワードに「ガールズラブ」が含まれる場合は1、それ以外は0です。 */\n  isgl: \"igl\",\n  /** 登録必須キーワードに「残酷な描写あり」が含まれる場合は1、それ以外は0です。 */\n  iszankoku: \"izk\",\n  /** 登録必須キーワードに「異世界転生」が含まれる場合は1、それ以外は0です。 */\n  istensei: \"its\",\n  /** 登録必須キーワードに「異世界転移」が含まれる場合は1、それ以外は0です。 */\n  istenni: \"iti\",\n  /** 総合評価ポイント */\n  global_point: \"gp\",\n  /** 日間ポイント */\n  daily_point: \"dp\",\n  /** 週間ポイント */\n  weekly_point: \"wp\",\n  /** 月間ポイント */\n  monthly_point: \"mp\",\n  /** 四半期ポイント */\n  quarter_point: \"qp\",\n  /** 年間ポイント */\n  yearly_point: \"yp\",\n  /** R18ブックマーク数 */\n  fav_novel_cnt: \"f\",\n  /** 感想数 */\n  impression_cnt: \"imp\",\n  /** レビュー数 */\n  review_cnt: \"r\",\n  /** 評価ポイント */\n  all_point: \"a\",\n  /** 評価者数 */\n  all_hyoka_cnt: \"ah\",\n  /** 挿絵の数 */\n  sasie_cnt: \"sa\",\n  /** 会話率 */\n  kaiwaritu: \"ka\",\n  /** 小説の更新日時 */\n  novelupdated_at: \"nu\",\n  /**\n   * 最終更新日時\n   * システム用で小説更新時とは関係ありません\n   */\n  updated_at: \"ua\",\n} as const;\n\nexport type R18Fields = (typeof R18Fields)[keyof Omit<\n  NarouSearchResult,\n  \"novel_type\" | \"weekly_unique\" | \"biggenre\" | \"genre\" | \"isr15\"\n>];\n\n/**\n * オプション項目\n */\nexport const OptionalFields = {\n  /**\n   * 週間ユニークユーザ[項目名:weekly_unique]が追加されます。\n   * 週間ユニークユーザは前週の日曜日から土曜日分のユニークの合計です。\n   * 毎週火曜日早朝に更新されます。\n   */\n  weekly_unique: \"weekly\",\n} as const;\n\nexport type OptionalFields = (typeof OptionalFields)[keyof Pick<\n  NarouSearchResult,\n  \"weekly_unique\"\n>];\n\n/**\n * ユーザ検索APIのofパラメータに指定できる出力する項目\n * @see https://dev.syosetu.com/man/userapi/#output\n */\nexport const UserFields = {\n  /** ユーザID */\n  userid: \"u\",\n  /** ユーザ名 */\n  name: \"n\",\n  /** ユーザ名のフリガナ */\n  yomikata: \"y\",\n  /** ユーザ名のフリガナの頭文字 */\n  name1st: \"1\",\n  /** 小説投稿数 */\n  novel_cnt: \"nc\",\n  /** レビュー投稿数 */\n  review_cnt: \"rc\",\n  /** 小説累計文字数 */\n  novel_length: \"nl\",\n  /** 総合評価ポイントの合計 */\n  sum_global_point: \"sg\",\n} as const;\nexport type UserFields = (typeof UserFields)[keyof UserSearchResult];\n\n/**\n * 出力順序\n */\nexport const Order = {\n  /** ブックマーク数の多い順 */\n  FavoriteNovelCount: \"favnovelcnt\",\n  /** レビュー数の多い順 */\n  ReviewCount: \"reviewcnt\",\n  /** 総合ポイントの高い順 */\n  HyokaDesc: \"hyoka\",\n  /** 総合ポイントの低い順 */\n  HyokaAsc: \"hyokaasc\",\n  /** 感想の多い順 */\n  ImpressionCount: \"impressioncnt\",\n  /** 評価者数の多い順 */\n  HyokaCountDesc: \"hyokacnt\",\n  /** 評価者数の少ない順 */\n  HyokaCountAsc: \"hyokacntasc\",\n  /** 週間ユニークユーザの多い順 */\n  Weekly: \"weekly\",\n  /** 小説本文の文字数が多い順 */\n  LengthDesc: \"lengthdesc\",\n  /** 小説本文の文字数が少ない順 */\n  LengthAsc: \"lengthasc\",\n  /** Nコードが新しい順 */\n  NCodeDesc: \"ncodedesc\",\n  /** 新着更新順 */\n  New: \"new\",\n  /** 古い順 */\n  Old: \"old\",\n  /** 日間ポイントの高い順 */\n  DailyPoint: \"dailypoint\",\n  /** 週間ポイントの高い順 */\n  WeeklyPoint: \"weeklypoint\",\n  /** 月間ポイントの高い順 */\n  MonthlyPoint: \"monthlypoint\",\n  /** 四半期ポイントの高い順 */\n  QuarterPoint: \"quarterpoint\",\n  /** 年間ポイントの高い順 */\n  YearlyPoint: \"yearlypoint\",\n  /** 初回掲載順 */\n  GeneralFirstUp: \"generalfirstup\",\n} as const;\n\nexport type Order = (typeof Order)[keyof typeof Order];\n\n/** R18掲載サイト */\nexport const R18Site = {\n  /** ノクターンノベルズ(男性向け) */\n  Nocturne: 1,\n  /** ムーンライトノベルズ(女性向け) */\n  MoonLight: 2,\n  /** ムーンライトノベルズ(BL) */\n  MoonLightBL: 3,\n  /** ミッドナイトノベルズ(大人向け) */\n  Midnight: 4,\n} as const;\n\nexport type R18Site = (typeof R18Site)[keyof typeof R18Site];\n\n/** R18掲載サイト表記ヘルパー */\nexport const R18SiteNotation: { readonly [K in R18Site]: string } = {\n  [R18Site.Nocturne]: \"ノクターンノベルズ(男性向け)\",\n  [R18Site.MoonLight]: \"ムーンライトノベルズ(女性向け)\",\n  [R18Site.MoonLightBL]: \"ムーンライトノベルズ(BL)\",\n  [R18Site.Midnight]: \"ミッドナイトノベルズ(大人向け)\",\n} as const;\n\n/** 大ジャンル */\nexport const BigGenre = {\n  /** 恋愛 */\n  Renai: 1,\n  /** ファンタジー */\n  Fantasy: 2,\n  /** 文芸 */\n  Bungei: 3,\n  /** SF */\n  Sf: 4,\n  /** その他 */\n  Sonota: 99,\n  /** ノンジャンル */\n  NonGenre: 98,\n} as const;\n\nexport type BigGenre = (typeof BigGenre)[keyof typeof BigGenre];\n\n/** 大ジャンル表記ヘルパー */\nexport const BigGenreNotation: { readonly [K in BigGenre]: string } = {\n  [BigGenre.Renai]: \"恋愛\",\n  [BigGenre.Fantasy]: \"ファンタジー\",\n  [BigGenre.Bungei]: \"文芸\",\n  [BigGenre.Sf]: \"SF\",\n  [BigGenre.Sonota]: \"その他\",\n  [BigGenre.NonGenre]: \"ノンジャンル\",\n} as const;\n\n/** ジャンル */\nexport const Genre = {\n  /** 異世界〔恋愛〕*/\n  RenaiIsekai: 101,\n  /** 現実世界〔恋愛〕*/\n  RenaiGenjitsusekai: 102,\n  /** ハイファンタジー〔ファンタジー〕*/\n  FantasyHigh: 201,\n  /** ローファンタジー〔ファンタジー〕*/\n  FantasyLow: 202,\n  /** 純文学〔文芸〕*/\n  BungeiJyunbungei: 301,\n  /** ヒューマンドラマ〔文芸〕*/\n  BungeiHumanDrama: 302,\n  /** 歴史〔文芸〕*/\n  BungeiHistory: 303,\n  /** 推理〔文芸〕*/\n  BungeiSuiri: 304,\n  /** ホラー〔文芸〕*/\n  BungeiHorror: 305,\n  /** アクション〔文芸〕*/\n  BungeiAction: 306,\n  /** コメディー〔文芸〕*/\n  BungeiComedy: 307,\n  /** VRゲーム〔SF〕*/\n  SfVrgame: 401,\n  /** 宇宙〔SF〕*/\n  SfSpace: 402,\n  /** 空想科学〔SF〕*/\n  SfKuusoukagaku: 403,\n  /** パニック〔SF〕*/\n  SfPanic: 404,\n  /** 童話〔その他〕*/\n  SonotaDouwa: 9901,\n  /** 詩〔その他〕*/\n  SonotaShi: 9902,\n  /** エッセイ〔その他〕*/\n  SonotaEssei: 9903,\n  /** リプレイ〔その他〕*/\n  SonotaReplay: 9904,\n  /** その他〔その他〕 */\n  SonotaSonota: 9999,\n  /** ノンジャンル〔ノンジャンル〕*/\n  NonGenre: 9801,\n} as const;\nexport type Genre = (typeof Genre)[keyof typeof Genre];\n\n/** ジャンル表記ヘルパー */\nexport const GenreNotation: { readonly [K in Genre]: string } = {\n  [Genre.RenaiIsekai]: \"異世界〔恋愛〕\",\n  [Genre.RenaiGenjitsusekai]: \"現実世界〔恋愛〕\",\n  [Genre.FantasyHigh]: \"ハイファンタジー〔ファンタジー〕\",\n  [Genre.FantasyLow]: \"ローファンタジー〔ファンタジー〕\",\n  [Genre.BungeiJyunbungei]: \"純文学〔文芸〕\",\n  [Genre.BungeiHumanDrama]: \"ヒューマンドラマ〔文芸〕\",\n  [Genre.BungeiHistory]: \"歴史〔文芸〕\",\n  [Genre.BungeiSuiri]: \"推理〔文芸〕\",\n  [Genre.BungeiHorror]: \"ホラー〔文芸〕\",\n  [Genre.BungeiAction]: \"アクション〔文芸〕\",\n  [Genre.BungeiComedy]: \"コメディー〔文芸〕\",\n  [Genre.SfVrgame]: \"VRゲーム〔SF〕\",\n  [Genre.SfSpace]: \"宇宙〔SF〕\",\n  [Genre.SfKuusoukagaku]: \"空想科学〔SF〕\",\n  [Genre.SfPanic]: \"パニック〔SF〕\",\n  [Genre.SonotaDouwa]: \"童話〔その他〕\",\n  [Genre.SonotaShi]: \"詩〔その他〕\",\n  [Genre.SonotaEssei]: \"エッセイ〔その他〕\",\n  [Genre.SonotaReplay]: \"リプレイ〔その他〕\",\n  [Genre.SonotaSonota]: \"その他〔その他〕\",\n  [Genre.NonGenre]: \"ノンジャンル〔ノンジャンル〕\",\n} as const;\n\n/** 文体指定 */\nexport const BuntaiParam = {\n  /** 字下げされておらず、連続改行が多い作品 */\n  NoJisageKaigyouOoi: 1,\n  /** 字下げされていないが、改行数は平均な作品 */\n  NoJisageKaigyoHutsuu: 2,\n  /** 字下げが適切だが、連続改行が多い作品 */\n  JisageKaigyoOoi: 4,\n  /** 字下げが適切でかつ改行数も平均な作品 */\n  JisageKaigyoHutsuu: 6,\n} as const;\n\nexport type BuntaiParam = (typeof BuntaiParam)[keyof typeof BuntaiParam];\n\n/** 連載停止中指定 */\nexport const StopParam = {\n  /** 長期連載停止中を除きます */\n  NoStopping: 1,\n  /** 長期連載停止中のみ取得します */\n  Stopping: 2,\n} as const;\n\nexport type StopParam = (typeof StopParam)[keyof typeof StopParam];\n\n/** 小説タイプ指定 */\nexport const NovelTypeParam = {\n  /** 短編 */\n  Short: \"t\",\n  /** 連載中 */\n  RensaiNow: \"r\",\n  /** 完結済連載小説 */\n  RensaiEnd: \"er\",\n  /** すべての連載小説(連載中および完結済) */\n  Rensai: \"re\",\n  /** 短編と完結済連載小説 */\n  ShortAndRensai: \"ter\",\n} as const;\nexport type NovelTypeParam =\n  (typeof NovelTypeParam)[keyof typeof NovelTypeParam];\n\n/** 日付指定パラメータ */\nexport const DateParam = {\n  ThisWeek: \"thisweek\",\n  LastWeek: \"lastweek\",\n  SevenDays: \"sevenday\",\n  ThisMonth: \"thismonth\",\n  LastMonth: \"lastmonth\",\n};\nexport type DateParam = (typeof DateParam)[keyof typeof DateParam];\n\nexport const UserOrder = {\n  /** ユーザIDの新しい順 */\n  New: \"new\",\n  /** 小説投稿数の多い順 */\n  NovelCount: \"novelcnt\",\n  /** レビュー投稿数の多い順 */\n  ReviewCount: \"reviewcnt\",\n  /** 小説累計文字数の多い順 */\n  NovelLength: \"novellength\",\n  /** 総合評価ポイントの合計の多い順 */\n  SumGlobalPoint: \"sumglobalpoint\",\n  /** ユーザIDの古い順 */\n  Old: \"old\",\n} as const;\nexport type UserOrder = (typeof UserOrder)[keyof typeof UserOrder];\n\nexport type GzipLevel = 0 | 1 | 2 | 3 | 4 | 5;\n","import type NarouNovel from \"./narou.js\";\nimport type { ExecuteOptions } from \"./narou.js\";\nimport type {\n  NarouSearchResult,\n  SearchResultFields,\n  SearchResultOptionalFields,\n} from \"./narou-search-results.js\";\nimport type NarouSearchResults from \"./narou-search-results.js\";\nimport type {\n  BigGenre,\n  SearchResultFieldNames,\n  Genre,\n  SearchParams,\n  Fields,\n  Order,\n  BuntaiParam,\n  NovelTypeParam,\n  GzipLevel,\n  OptionalFields,\n  ParamsBaseWithOrder,\n  DateParam,\n} from \"./params.js\";\nimport { BooleanNumber, StopParam } from \"./params.js\";\nimport type { Join } from \"./util/type.js\";\n\nexport type DefaultSearchResultFields = keyof Omit<\n  NarouSearchResult,\n  \"weekly_unique\" | \"noveltype\" | \"nocgenre\" | \"xid\"\n>;\n\nexport abstract class SearchBuilderBase<\n  TParams extends ParamsBaseWithOrder<TOrder>,\n  TOrder extends string,\n> {\n  /**\n   * constructor\n   * @private\n   * @param params クエリパラメータ\n   * @param api NarouNovel インスタンス\n   */\n  constructor(\n    protected params: TParams = {} as TParams,\n    protected api: NarouNovel\n  ) { }\n\n  /**\n   * 配列から重複を除去する\n   * @protected\n   * @static\n   * @param array 配列\n   * @returns 重複を除去した配列\n   */\n  protected static distinct<T>(array: readonly T[]): T[] {\n    return Array.from(new Set(array));\n  }\n\n  /**\n   * 配列をハイフン区切りの文字列に変換する\n   * @protected\n   * @static\n   * @param n 文字列または数値の配列、あるいは単一の文字列または数値\n   * @returns ハイフン区切りの文字列\n   */\n  protected static array2string<T extends string | number>(\n    n: T | readonly T[]\n  ): Join<T> {\n    if (Array.isArray(n)) {\n      return this.distinct(n).join(\"-\") as Join<T>;\n    } else {\n      return n.toString() as Join<T>;\n    }\n  }\n\n  /**\n   * 取得件数を指定する (lim)\n   * @param num 取得件数 (1-500)\n   * @return {this}\n   */\n  limit(num: number): this {\n    this.set({ lim: num } as TParams);\n    return this;\n  }\n\n  /**\n   * 取得開始位置を指定する (st)\n   * @param num 取得開始位置 (1-)\n   * @return {this}\n   */\n  start(num: number): this {\n    this.set({ st: num } as TParams);\n    return this;\n  }\n\n  /**\n   * ページ番号と1ページあたりの件数で取得範囲を指定する\n   * @param no ページ番号 (0-)\n   * @param count 1ページあたりの件数 (デフォルト: 20)\n   * @return {this}\n   */\n  page(no: number, count = 20): this {\n    return this.limit(count).start(no * count);\n  }\n\n  /**\n   * 出力順序を指定する (order)\n   * 指定しない場合は新着順となります。\n   * @param {TOrder} order 出力順序\n   * @return {this}\n   */\n  order(order: TOrder): this {\n    this.set({ order: order } as TParams);\n    return this;\n  }\n\n  /**\n   * gzip圧縮レベルを指定する (gzip)\n   *\n   * 転送量上限を減らすためにも推奨\n   * @param {GzipLevel} level gzip圧縮レベル(1～5)\n   * @return {this}\n   */\n  gzip(level: GzipLevel): this {\n    this.set({ gzip: level } as TParams);\n    return this;\n  }\n\n  /**\n   * クエリパラメータをセットする\n   * @protected\n   * @param obj セットするパラメータ\n   * @return {this}\n   */\n  protected set(obj: TParams): this {\n    this.params = { ...this.params, ...obj };\n    return this;\n  }\n\n  /**\n   * クエリパラメータを削除する\n   * @protected\n   * @param key 削除するパラメータのキー\n   * @returns {this}\n   */\n  protected unset(key: keyof TParams): this {\n    delete this.params[key];\n    return this;\n  }\n}\n\nexport abstract class NovelSearchBuilderBase<\n  T extends SearchResultFieldNames,\n> extends SearchBuilderBase<SearchParams, Order> {\n  /**\n   * 検索語を指定します (word)。\n   * 半角または全角スペースで区切るとAND抽出になります。部分一致でHITします。\n   * @param word 検索語\n   * @return {this}\n   */\n  word(word: string): this {\n    this.set({ word: word });\n    return this;\n  }\n\n  /**\n   * 除外したい単語を指定します (notword)。\n   * スペースで区切ることにより除外する単語を増やせます。部分一致で除外されます。\n   * @param word 除外語\n   * @return {this}\n   */\n  notWord(word: string): this {\n    this.set({ notword: word });\n    return this;\n  }\n\n  /**\n   * 検索対象を作品名に限定するかどうかを指定します (title)。\n   * @param bool trueの場合、作品名を検索対象とする (デフォルト: true)\n   * @return {this}\n   */\n  byTitle(bool = true): this {\n    this.set({ title: bool ? BooleanNumber.True : BooleanNumber.False });\n    return this;\n  }\n\n  /**\n   * 検索対象をあらすじに限定するかどうかを指定します (ex)。\n   * @param bool trueの場合、あらすじを検索対象とする (デフォルト: true)\n   * @return {this}\n   */\n  byOutline(bool = true): this {\n    this.set({ ex: bool ? BooleanNumber.True : BooleanNumber.False });\n    return this;\n  }\n\n  /**\n   * 検索対象をキーワードに限定するかどうかを指定します (keyword)。\n   * @param bool trueの場合、キーワードを検索対象とする (デフォルト: true)\n   * @return {this}\n   */\n  byKeyword(bool = true): this {\n    this.set({ keyword: bool ? BooleanNumber.True : BooleanNumber.False });\n    return this;\n  }\n\n  /**\n   * 検索対象を作者名に限定するかどうかを指定します (wname)。\n   * @param bool trueの場合、作者名を検索対象とする (デフォルト: true)\n   * @return {this}\n   */\n  byAuthor(bool = true): this {\n    this.set({ wname: bool ? BooleanNumber.True : BooleanNumber.False });\n    return this;\n  }\n\n  /**\n   * ボーイズラブ作品を抽出または除外します (isbl/notbl)。\n   * @param bool trueの場合、ボーイズラブ作品を抽出する (デフォルト: true)。falseの場合、除外する。\n   * @return {this}\n   */\n  isBL(bool = true): this {\n    if (bool) {\n      this.set({ isbl: BooleanNumber.True });\n    } else {\n      this.set({ notbl: BooleanNumber.True });\n    }\n    return this;\n  }\n\n  /**\n   * ガールズラブ作品を抽出または除外します (isgl/notgl)。\n   * @param bool trueの場合、ガールズラブ作品を抽出する (デフォルト: true)。falseの場合、除外する。\n   * @return {this}\n   */\n  isGL(bool = true): this {\n    if (bool) {\n      this.set({ isgl: BooleanNumber.True });\n    } else {\n      this.set({ notgl: BooleanNumber.True });\n    }\n    return this;\n  }\n\n  /**\n   * 残酷な描写あり作品を抽出または除外します (iszankoku/notzankoku)。\n   * @param bool trueの場合、残酷な描写あり作品を抽出する (デフォルト: true)。falseの場合、除外する。\n   * @return {this}\n   */\n  isZankoku(bool = true): this {\n    if (bool) {\n      this.set({ iszankoku: BooleanNumber.True });\n    } else {\n      this.set({ notzankoku: BooleanNumber.True });\n    }\n    return this;\n  }\n\n  /**\n   * 異世界転生作品を抽出または除外します (istensei/nottensei)。\n   * @param bool trueの場合、異世界転生作品を抽出する (デフォルト: true)。falseの場合、除外する。\n   * @return {this}\n   */\n  isTensei(bool = true): this {\n    if (bool) {\n      this.set({ istensei: BooleanNumber.True });\n    } else {\n      this.set({ nottensei: BooleanNumber.True });\n    }\n    return this;\n  }\n\n  /**\n   * 異世界転移作品を抽出または除外します (istenni/nottenni)。\n   * @param bool trueの場合、異世界転移作品を抽出する (デフォルト: true)。falseの場合、除外する。\n   * @return {this}\n   */\n  isTenni(bool = true): this {\n    if (bool) {\n      this.set({ istenni: BooleanNumber.True });\n    } else {\n      this.set({ nottenni: BooleanNumber.True });\n    }\n    return this;\n  }\n\n  /**\n   * 異世界転生または異世界転移作品を抽出します (istt)。\n   * @return {this}\n   */\n  isTT(): this {\n    this.set({ istt: BooleanNumber.True });\n    return this;\n  }\n\n  /**\n   * 抽出する作品の文字数を指定します (length)。\n   * 範囲指定する場合は、最小文字数と最大文字数をハイフン(-)記号で区切ってください。\n   * @param length 文字数、または[最小文字数, 最大文字数]\n   * @return {this}\n   */\n  length(length: number | readonly number[]): this {\n    this.set({ length: NovelSearchBuilderBase.array2string(length) });\n    return this;\n  }\n\n  /**\n   * 抽出する作品の会話率を%単位で指定します (kaiwaritu)。\n   * @param num 会話率(%)\n   * @return {this}\n   */\n  kaiwaritu(num: number): this;\n  /**\n   * 抽出する作品の会話率を%単位で範囲指定します (kaiwaritu)。\n   * @param min 最低会話率(%)\n   * @param max 最高会話率(%)\n   * @return {this}\n   */\n  kaiwaritu(min: number, max: number): this;\n\n  kaiwaritu(min: number, max?: number): this {\n    let n: number | string;\n    if (max != null) {\n      n = `${min}-${max}`;\n    } else {\n      n = min;\n    }\n    this.set({ kaiwaritu: n });\n    return this;\n  }\n\n  /**\n   * 抽出する作品の挿絵数を指定します (sasie)。\n   * @param num 挿絵数、または[最小挿絵数, 最大挿絵数]\n   * @return {this}\n   */\n  sasie(num: number | readonly number[]): this {\n    this.set({ sasie: NovelSearchBuilderBase.array2string(num) });\n    return this;\n  }\n\n  /**\n   * 抽出する作品の予想読了時間を分単位で指定します (time)。\n   * @param num 読了時間(分)、または[最小読了時間, 最大読了時間]\n   * @return {this}\n   */\n  time(num: number | readonly number[]): this {\n    this.set({ time: NovelSearchBuilderBase.array2string(num) });\n    return this;\n  }\n\n  /**\n   * Nコードを指定して取得します (ncode)。\n   * @param ncodes Nコード、またはNコードの配列\n   * @return {this}\n   */\n  ncode(ncodes: string | readonly string[]): this {\n    this.set({ ncode: NovelSearchBuilderBase.array2string(ncodes) });\n    return this;\n  }\n\n  /**\n   * 抽出する小説タイプを指定します (type)。\n   * @param type 小説タイプ (t: 短編, r: 連載中, er: 完結済連載小説, ter: 短編と完結済連載小説, re: 連載中と完結済連載小説)\n   * @return {this}\n   */\n  type(type: NovelTypeParam): this {\n    this.set({ type });\n    return this;\n  }\n\n  /**\n   * 抽出する作品の文体を指定します (buntai)。\n   * 複数指定する場合はハイフン(-)で区切ってください。\n   * @param buntai 文体コード、または文体コードの配列\n   * @return {this}\n   */\n  buntai(buntai: BuntaiParam | readonly BuntaiParam[]): this {\n    this.set({ buntai: NovelSearchBuilderBase.array2string(buntai) });\n    return this;\n  }\n\n  /**\n   * 連載停止中作品に関する指定をします (stop)。\n   * @param bool trueの場合、長期連載停止中のみ取得する (デフォルト: true)。falseの場合、長期連載停止中を除外する。\n   * @return {this}\n   */\n  isStop(bool = true): this {\n    this.set({ stop: bool ? StopParam.Stopping : StopParam.NoStopping });\n    return this;\n  }\n\n  /**\n   * ピックアップ作品のみを取得します (ispickup)。\n   * @return {this}\n   */\n  isPickup(): this {\n    this.set({ ispickup: BooleanNumber.True });\n    return this;\n  }\n\n  /**\n   * 最終更新日時を指定します (lastup)。\n   * @param date 最終更新日時 (YYYYMMDDhhmmss形式またはUNIXタイムスタンプ)\n   * @return {this}\n   */\n  lastUpdate(date: DateParam): this;\n  /**\n   * 最終更新日時の範囲を指定します (lastup)。\n   * @param from 開始日時 (UNIXタイムスタンプ)\n   * @param to 終了日時 (UNIXタイムスタンプ)\n   * @return {this}\n   */\n  lastUpdate(from: number, to: number): this;\n  /**\n   * 最終更新日時の範囲を指定します (lastup)。\n   * @param from 開始日時 (Dateオブジェクト)\n   * @param to 終了日時 (Dateオブジェクト)\n   * @return {this}\n   */\n  lastUpdate(from: Date, to: Date): this;\n\n  lastUpdate(x: string | number | Date, y?: number | Date): this {\n    let date: string;\n    if (typeof x == \"string\") {\n      date = x;\n    } else if (x instanceof Date && y instanceof Date) {\n      date = `${Math.floor(x.getTime() / 1000)}-${Math.floor(\n        y.getTime() / 1000\n      )}`;\n    } else {\n      date = `${x}-${y}`;\n    }\n\n    this.set({ lastup: date });\n    return this;\n  }\n\n  /**\n   * 作品の更新日時を指定します (lastupdate)。\n   * @param date 作品の更新日時 (YYYYMMDDhhmmss形式またはUNIXタイムスタンプ)\n   * @return {this}\n   */\n  lastNovelUpdate(date: DateParam): this;\n  /**\n   * 作品の更新日時の範囲を指定します (lastupdate)。\n   * @param from 開始日時 (UNIXタイムスタンプ)\n   * @param to 終了日時 (UNIXタイムスタンプ)\n   * @return {this}\n   */\n  lastNovelUpdate(from: number, to: number): this;\n  /**\n   * 作品の更新日時の範囲を指定します (lastupdate)。\n   * @param from 開始日時 (Dateオブジェクト)\n   * @param to 終了日時 (Dateオブジェクト)\n   * @return {this}\n   */\n  lastNovelUpdate(from: Date, to: Date): this;\n\n  lastNovelUpdate(x: string | number | Date, y?: number | Date): this {\n    let date: string;\n    if (typeof x == \"string\") {\n      date = x;\n    } else if (x instanceof Date && y instanceof Date) {\n      date = `${Math.floor(x.getTime() / 1000)}-${Math.floor(\n        y.getTime() / 1000\n      )}`;\n    } else {\n      date = `${x}-${y}`;\n    }\n\n    this.set({ lastupdate: date });\n    return this;\n  }\n\n  /**\n   * なろう小説APIへの検索リクエストを実行する\n   * @param options 実行オプション\n   * @returns {Promise<NarouSearchResults>} 検索結果\n   */\n  execute(\n    options?: ExecuteOptions\n  ): Promise<NarouSearchResults<NarouSearchResult, T>> {\n    return this.api.executeNovel(this.params, options);\n  }\n}\n\n/**\n * 検索ヘルパー\n * @class SearchBuilder\n */\nexport default class SearchBuilder<\n  T extends keyof NarouSearchResult = DefaultSearchResultFields,\n  TOpt extends keyof NarouSearchResult = never,\n> extends NovelSearchBuilderBase<T | TOpt> {\n  /**\n   * 大ジャンルを指定して取得します (biggenre)。\n   * 複数指定する場合はハイフン(-)で区切ってください。\n   * @param genre 大ジャンルコード、または大ジャンルコードの配列\n   * @return {this}\n   */\n  bigGenre(genre: BigGenre | readonly BigGenre[]): this {\n    this.set({ biggenre: SearchBuilder.array2string(genre) });\n    return this;\n  }\n\n  /**\n   * 除外したい大ジャンルを指定します (notbiggenre)。\n   * 複数指定する場合はハイフン(-)で区切ってください。\n   * @param genre 除外する大ジャンルコード、または大ジャンルコードの配列\n   * @return {this}\n   */\n  notBigGenre(genre: BigGenre | readonly BigGenre[]): this {\n    this.set({ notbiggenre: SearchBuilder.array2string(genre) });\n    return this;\n  }\n\n  /**\n   * ジャンルを指定して取得します (genre)。\n   * 複数指定する場合はハイフン(-)で区切ってください。\n   * @param genre ジャンルコード、またはジャンルコードの配列\n   * @return {this}\n   */\n  genre(genre: Genre | readonly Genre[]): this {\n    this.set({ genre: SearchBuilder.array2string(genre) });\n    return this;\n  }\n\n  /**\n   * 除外したいジャンルを指定します (notgenre)。\n   * 複数指定する場合はハイフン(-)で区切ってください。\n   * @param genre 除外するジャンルコード、またはジャンルコードの配列\n   * @return {this}\n   */\n  notGenre(genre: Genre | readonly Genre[]): this {\n    this.set({ notgenre: SearchBuilder.array2string(genre) });\n    return this;\n  }\n\n  /**\n   * ユーザIDを指定して取得します (userid)。\n   * 複数指定する場合はハイフン(-)で区切ってください。\n   * @param ids ユーザID、またはユーザIDの配列\n   * @return {this}\n   */\n  userId(ids: number | readonly number[]): this {\n    this.set({ userid: SearchBuilder.array2string(ids) });\n    return this;\n  }\n\n  /**\n   * R15作品を抽出または除外します (isr15/notr15)。\n   * @param bool trueの場合、R15作品を抽出する (デフォルト: true)。falseの場合、除外する。\n   * @return {this}\n   */\n  isR15(bool = true): this {\n    if (bool) {\n      this.set({ isr15: 1 });\n    } else {\n      this.set({ notr15: 1 });\n    }\n    return this;\n  }\n\n  /**\n   * 出力する項目を個別に指定します (of)。\n   * 未指定時は全項目出力されます。転送量軽減のため、このパラメータの使用が推奨されます。\n   * 複数項目を出力する場合はハイフン(-)記号で区切ってください。\n   * @param fields 出力するフィールド名、またはフィールド名の配列\n   * @return {SearchBuilder<SearchResultFields<TFields>, TOpt>} 型が更新されたビルダー\n   */\n  fields<TFields extends Fields>(\n    fields: TFields | readonly TFields[]\n  ): SearchBuilder<SearchResultFields<TFields>, TOpt> {\n    this.set({ of: SearchBuilder.array2string(fields) });\n    // eslint-disable-next-line @typescript-eslint/no-explicit-any\n    return this as any;\n  }\n\n  /**\n   * 出力オプション項目を指定します (opt)。\n   * 複数項目を出力する場合はハイフン(-)記号で区切ってください。\n   * @param option 出力するオプションフィールド名、またはオプションフィールド名の配列\n   * @return {SearchBuilder<T, SearchResultOptionalFields<TFields>>} 型が更新されたビルダー\n   */\n  opt<TFields extends OptionalFields>(\n    option: TFields | readonly TFields[]\n  ): SearchBuilder<T, SearchResultOptionalFields<TFields>> {\n    this.set({ opt: SearchBuilder.array2string(option) });\n    // eslint-disable-next-line @typescript-eslint/no-explicit-any\n    return this as any;\n  }\n}\n","// 日付関連のユーティリティ関数\n\n/**\n * 文字列の日付（yyyyMMdd形式）をDateオブジェクトに変換する\n * @param dateStr yyyyMMdd形式の日付文字列\n * @returns Dateオブジェクト\n */\nexport function parseDate(dateStr: string): Date {\n  const year = parseInt(dateStr.substring(0, 4), 10);\n  const month = parseInt(dateStr.substring(4, 6), 10) - 1; // JavaScriptの月は0から始まる\n  const day = parseInt(dateStr.substring(6, 8), 10);\n\n  return new Date(year, month, day, 0, 0, 0, 0);\n}\n\n/**\n * 日付をyyyyMMdd形式の文字列に変換する\n * @param date 日付\n * @returns yyyyMMdd形式の文字列\n */\nexport function formatDate(date: Date): string {\n  const year = date.getFullYear();\n  const month = String(date.getMonth() + 1).padStart(2, '0');\n  const day = String(date.getDate()).padStart(2, '0');\n  return `${year}${month}${day}`;\n}\n\n/**\n * 指定された日数を加算した新しい日付を返す\n * @param date 元の日付\n * @param days 加算する日数\n * @returns 新しい日付\n */\nexport function addDays(date: Date, days: number): Date {\n  const result = new Date(date);\n  result.setDate(result.getDate() + days);\n  return result;\n}","import type { NarouRankingResult, RankingResult } from \"./narou-ranking-results.js\";\nimport SearchBuilder from \"./search-builder.js\";\nimport type { DefaultSearchResultFields } from \"./search-builder.js\";\nimport type {\n  GzipLevel,\n  OptionalFields,\n} from \"./params.js\";\nimport {\n  RankingParams,\n  RankingType,\n  Fields,\n} from \"./params.js\";\nimport type NarouNovel from \"./narou.js\";\nimport type { ExecuteOptions } from \"./narou.js\";\nimport type { SearchResultFields } from \"./narou-search-results.js\";\nimport { addDays, formatDate } from \"./util/date.js\";\n\n/**\n * なろう小説ランキングAPIのヘルパークラス。\n *\n * ランキング種別や日付を指定してランキングデータを取得します。\n * また、取得したランキングデータに含まれるNコードを元に、\n * なろう小説APIを利用して詳細な小説情報を取得することも可能です。\n *\n * @class RankingBuilder\n * @see https://dev.syosetu.com/man/rankapi/ なろう小説ランキングAPI仕様\n */\nexport default class RankingBuilder {\n  /**\n   * ランキング集計対象の日付\n   * @protected\n   */\n  protected date$: Date;\n  /**\n   * ランキング種別\n   * @protected\n   */\n  protected type$: RankingType;\n\n  /**\n   * constructor\n   * @param params - 初期クエリパラメータ\n   * @param api - API実行クラスのインスタンス\n   * @private\n   */\n  constructor(\n    protected params: Partial<RankingParams> = {},\n    protected api: NarouNovel\n  ) {\n    /**\n     * クエリパラメータ\n     * @protected\n     */\n    this.date$ = addDays(new Date(), -1);\n    this.type$ = RankingType.Daily;\n  }\n\n  /**\n   * ランキング集計対象の日付を指定します。\n   *\n   * - 日間: 任意の日付\n   * - 週間: 火曜日の日付\n   * - 月間・四半期: 1日の日付\n   *\n   * @param date 集計対象の日付\n   * @returns {RankingBuilder} this\n   * @see https://dev.syosetu.com/man/rankapi/\n   */\n  date(date: Date) {\n    this.date$ = date;\n    return this;\n  }\n\n  /**\n   * ランキング種別を指定します。\n   * @param type ランキング種別\n   * @returns {RankingBuilder} this\n   * @see https://dev.syosetu.com/man/rankapi/\n   */\n  type(type: RankingType) {\n    this.type$ = type;\n    return this;\n  }\n\n  /**\n   * gzip圧縮する。\n   *\n   * 転送量上限を減らすためにも推奨\n   * @param {GzipLevel} level gzip圧縮レベル(1～5)\n   * @return {RankingBuilder} this\n   */\n  gzip(level: GzipLevel) {\n    this.set({ gzip: level });\n    return this;\n  }\n\n  /**\n   * クエリパラメータを内部的にセットします。\n   * @param obj - セットするパラメータオブジェクト\n   * @returns {RankingBuilder} this\n   * @private\n   */\n  protected set(obj: Partial<RankingParams>) {\n    Object.assign(this.params, obj);\n    return this;\n  }\n\n  /**\n   * 設定されたパラメータに基づき、なろう小説ランキングAPIへのリクエストを実行します。\n   *\n   * 返される結果には、Nコード、ポイント、順位が含まれます。\n   * @param options 実行オプション\n   * @returns {Promise<NarouRankingResult[]>} ランキング結果の配列\n   * @see https://dev.syosetu.com/man/rankapi/#output\n   */\n  execute(options?: ExecuteOptions): Promise<NarouRankingResult[]> {\n    const date = formatDate(this.date$);\n    this.set({ rtype: `${date}-${this.type$}` });\n    return this.api.executeRanking(this.params as RankingParams, options);\n  }\n\n  /**\n   * ランキングAPIを実行し、取得したNコードを元になろう小説APIで詳細情報を取得して結合します。\n   */\n  async executeWithFields(\n    fields?: never[] | undefined,\n    opt?: never[] | undefined,\n    options?: ExecuteOptions\n  ): Promise<RankingResult<DefaultSearchResultFields>[]>;\n  /**\n   * ランキングAPIを実行し、取得したNコードを元になろう小説APIで詳細情報を取得して結合します。\n   *\n   * @template TFields - 取得する小説情報のフィールド型\n   * @param fields - 取得するフィールドの配列\n   * @returns {Promise<RankingResult<SearchResultFields<TFields>>[]>} 詳細情報を含むランキング結果の配列\n   */\n  async executeWithFields<TFields extends Fields>(\n    fields: TFields | TFields[],\n    opt?: never | never[],\n    options?: ExecuteOptions\n  ): Promise<RankingResult<SearchResultFields<TFields>>[]>;\n  /**\n   * ランキングAPIを実行し、取得したNコードを元になろう小説APIで詳細情報を取得して結合します。\n   *\n   * @param opt - オプショナルな取得フィールド (`weekly` など)\n   * @returns {Promise<RankingResult<DefaultSearchResultFields | \"weekly_unique\">[]>} 詳細情報を含むランキング結果の配列\n   */\n  async executeWithFields(\n    fields: never[],\n    opt: OptionalFields | OptionalFields[],\n    options?: ExecuteOptions\n  ): Promise<RankingResult<DefaultSearchResultFields | \"weekly_unique\">[]>;\n  /**\n   * ランキングAPIを実行し、取得したNコードを元になろう小説APIで詳細情報を取得して結合します。\n   *\n   * @template TFields - 取得する小説情報のフィールド型\n   * @param fields - 取得するフィールドの配列\n   * @param opt - オプショナルな取得フィールド (`weekly` など)\n   * @returns {Promise<RankingResult<SearchResultFields<TFields> | \"weekly_unique\">[]>} 詳細情報を含むランキング結果の配列\n   */\n  async executeWithFields<TFields extends Fields>(\n    fields: TFields | TFields[],\n    opt: OptionalFields | OptionalFields[],\n    options?: ExecuteOptions\n  ): Promise<RankingResult<SearchResultFields<TFields> | \"weekly_unique\">[]>;\n  /**\n   * ランキングAPIを実行し、取得したNコードを元になろう小説APIで詳細情報を取得して結合します。\n   *\n   * @template TFields - 取得する小説情報のフィールド型\n   * @template TOpt - オプショナルな取得フィールドの型\n   * @param fields - 取得するフィールドの配列 (省略時はデフォルトフィールド)\n   * @param opt - オプショナルな取得フィールド (`weekly` など)\n   * @returns {Promise<RankingResult<SearchResultFields<TFields>>[]>} 詳細情報を含むランキング結果の配列\n   */\n  async executeWithFields<\n    TFields extends Fields,\n    TOpt extends OptionalFields | undefined = undefined\n  >(\n    fields: TFields | TFields[] = [],\n    opt?: TOpt,\n    options?: ExecuteOptions\n  ): Promise<RankingResult<SearchResultFields<TFields>>[]> {\n    const ranking = await this.execute(options);\n    const fields$ = Array.isArray(fields)\n      ? fields.length == 0\n        ? []\n        : ([...fields, Fields.ncode] as const)\n      : ([fields, Fields.ncode] as const);\n\n    const rankingNcodes = ranking.map(({ ncode }) => ncode);\n    const builder = new SearchBuilder({}, this.api);\n    builder.fields(fields$);\n    if (opt) {\n      builder.opt(opt);\n    }\n    builder.ncode(rankingNcodes);\n    builder.limit(ranking.length);\n    const result = await builder.execute(options);\n\n    return ranking.map<\n      RankingResult<\n        | SearchResultFields<TFields>\n        | (TOpt extends \"weekly\" ? \"weekly_unique\" : never)\n      >\n    >((r) => ({\n      ...r,\n      // eslint-disable-next-line @typescript-eslint/no-explicit-any\n      ...(result.values.find((novel) => novel.ncode == r.ncode) as any),\n    }));\n  }\n}\n","import type { RankingType } from \"./params.js\";\nimport { parseDate } from \"./util/date.js\";\n\nexport interface RankingHistoryRawResult {\n  rtype: `${string}-${RankingType}`;\n  pt: number;\n  rank: number;\n}\n\nexport interface RankingHistoryResult {\n  type: RankingType;\n  date: Date;\n  pt: number;\n  rank: number;\n}\n\n/**\n * 生のランキング履歴エントリを構造化された形式にフォーマットします。\n * \n * @param rankin - フォーマットする生のランキング履歴データ\n * @returns 日付とタイプが解析されたフォーマット済みランキング履歴\n * \n * @example\n * const rawData = { rtype: \"20230101-daily\", pt: 500, rank: 10 };\n * const formattedData = formatRankingHistory(rawData);\n * // 返り値: { type: \"daily\", date: [Dateオブジェクト], pt: 500, rank: 10 }\n */\nexport function formatRankingHistory(\n  rankin: RankingHistoryRawResult\n): RankingHistoryResult {\n  const { rtype, pt, rank } = rankin;\n  const [_date, _type] = rtype.split(\"-\");\n  const date = parseDate(_date);\n  const type = _type as RankingType;\n\n  return { type, date, pt, rank };\n}\n","import { NovelSearchBuilderBase } from \"./search-builder.js\";\nimport type { ExecuteOptions } from \"./narou.js\";\nimport type NarouSearchResults from \"./narou-search-results.js\";\nimport type {\n  NarouSearchResult,\n  SearchResultR18Fields,\n  SearchResultOptionalFields,\n} from \"./narou-search-results.js\";\nimport type {\n  R18Site,\n  SearchResultFieldNames,\n  R18Fields,\n  OptionalFields,\n} from \"./params.js\";\n\nexport type DefaultR18SearchResultFields = keyof Omit<\n  NarouSearchResult,\n  \"weekly_unique\" | \"noveltype\" | \"biggenre\" | \"genre\" | \"isr15\" | \"id\"\n>;\n\n/**\n * 18禁API検索ヘルパー\n * @class SearchBuilderR18\n */\nexport default class SearchBuilderR18<\n  T extends SearchResultFieldNames = DefaultR18SearchResultFields,\n  TOpt extends keyof NarouSearchResult = never\n> extends NovelSearchBuilderBase<T | TOpt> {\n  /**\n   * なろう小説APIへの検索リクエストを実行する\n   * @override\n   * @param options 実行オプション\n   * @returns {Promise<NarouSearchResults>} 検索結果\n   */\n  execute(\n    options?: ExecuteOptions\n  ): Promise<NarouSearchResults<NarouSearchResult, T | TOpt>> {\n    return this.api.executeNovel18(this.params, options);\n  }\n\n  /**\n   * 抽出するR18サイトを指定します (nocgenre)。\n   * @param sites R18サイトコード、またはR18サイトコードの配列 (1: ノクターンノベルズ, 2: ムーンライトノベルズ(男性向け), 3: ムーンライトノベルズ(BL), 4: ミッドナイトノベルズ)\n   * @return {this}\n   */\n  r18Site(sites: R18Site | readonly R18Site[]) {\n    this.set({ nocgenre: NovelSearchBuilderBase.array2string(sites) });\n    return this;\n  }\n\n  /**\n   * X-IDを指定して取得します (xid)。\n   * @param ids X-ID、またはX-IDの配列\n   * @return {this}\n   */\n  xid(ids: number | readonly number[]) {\n    this.set({ xid: NovelSearchBuilderBase.array2string(ids) });\n    return this;\n  }\n\n  /**\n   * 出力する項目を個別に指定します (of)。\n   * 未指定時は全項目出力されます。転送量軽減のため、このパラメータの使用が推奨されます。\n   * @param fields 出力するR18フィールド名、またはR18フィールド名の配列\n   * @return {SearchBuilderR18<SearchResultR18Fields<R18Fields>>} 型が更新されたビルダー\n   */\n  fields<TFields extends R18Fields>(\n    fields: TFields | readonly TFields[]\n  ): SearchBuilderR18<SearchResultR18Fields<R18Fields>> {\n    this.set({ of: NovelSearchBuilderBase.array2string(fields) });\n    // eslint-disable-next-line @typescript-eslint/no-explicit-any\n    return this as any;\n  }\n\n  /**\n   * 出力オプション項目を指定します (opt)。\n   * @param option 出力するオプションフィールド名、またはオプションフィールド名の配列\n   * @return {SearchBuilderR18<T, SearchResultOptionalFields<TFields>>} 型が更新されたビルダー\n   */\n  opt<TFields extends OptionalFields>(\n    option: TFields | readonly TFields[]\n  ): SearchBuilderR18<T, SearchResultOptionalFields<TFields>> {\n    this.set({ opt: NovelSearchBuilderBase.array2string(option) });\n    // eslint-disable-next-line @typescript-eslint/no-explicit-any\n    return this as any;\n  }\n}\n","import NarouSearchResults from \"./narou-search-results.js\";\nimport type {\n  UserSearchResult,\n  UserSearchResultFields,\n} from \"./narou-search-results.js\";\nimport type { UserFields, UserOrder, UserSearchParams } from \"./params.js\";\nimport { SearchBuilderBase } from \"./search-builder.js\";\nimport type { ExecuteOptions } from \"./narou.js\";\n\n/**\n * なろうユーザ検索API\n * @class UserSearch\n */\nexport default class UserSearchBuilder<\n  TField extends keyof UserSearchResult = keyof UserSearchResult\n> extends SearchBuilderBase<UserSearchParams, UserOrder> {\n  /**\n   * 単語を指定できます。\n   * 半角または全角スペースで区切るとAND抽出になります。\n   * 部分一致でHITします。検索の対象はユーザ名とユーザ名のフリガナです。\n   */\n  word(word: string) {\n    this.set({ word });\n    return this;\n  }\n\n  /**\n   * 含みたくない単語を指定できます。\n   * スペースで区切ることにより含ませない単語を増やせます。部分一致で除外されます。\n   * 除外の対象はユーザ名とユーザ名のフリガナです。\n   */\n  notWord(notword: string) {\n    this.set({ notword });\n    return this;\n  }\n\n  /**\n   * ユーザIDで抽出可能。\n   */\n  userId(userid: number) {\n    this.set({ userid });\n    return this;\n  }\n\n  /**\n   * 抽出するユーザのユーザ名のフリガナの頭文字を指定できます。\n   * 頭文字はユーザ名のフリガナをひらがなに変換し、最初の1文字が「ぁ」～「ん」の場合に対象となります。\n   * 「ぱ」や「ば」等の半濁音や濁音は清音として扱われます。\n   * 漢字や英数字が頭文字のユーザは対象外です。\n   */\n  name1st(name1st: string) {\n    this.set({ name1st });\n    return this;\n  }\n\n  /**\n   * 抽出するユーザの小説投稿数の下限を指定できます。\n   * 小説投稿件数が指定された数値以上のユーザを抽出します。\n   */\n  minNovel(minnovel: number) {\n    this.set({ minnovel });\n    return this;\n  }\n\n  /**\n   * 抽出するユーザの小説投稿数の上限を指定できます。\n   * 小説投稿件数が指定された数値以下のユーザを抽出します。\n   */\n  maxNovel(maxnovel: number) {\n    this.set({ maxnovel });\n    return this;\n  }\n\n  /**\n   * 抽出するユーザのレビュー投稿数の下限を指定できます。\n   * レビュー投稿件数が指定された数値以上のユーザを抽出します。\n   */\n  minReview(minreview: number) {\n    this.set({ minreview });\n    return this;\n  }\n\n  /**\n   * 抽出するユーザのレビュー投稿数の上限を指定できます。\n   * レビュー投稿件数が指定された数値以下のユーザを抽出します。\n   */\n  maxReview(maxreview: number) {\n    this.set({ maxreview });\n    return this;\n  }\n\n  /**\n   * 出力する項目を個別に指定できます。未指定時は全項目出力されます。転送量軽減のため、このパラメータの使用が推奨されます。\n   * @return {SearchBuilder} this\n   */\n  fields<TFields extends UserFields>(\n    fields: TFields | readonly TFields[]\n  ): UserSearchBuilder<UserSearchResultFields<TFields>> {\n    this.set({ of: UserSearchBuilder.array2string(fields) });\n    // eslint-disable-next-line @typescript-eslint/no-explicit-any\n    return this as any;\n  }\n\n  /**\n   * なろう小説APIへのリクエストを実行する\n   * @param options 実行オプション\n   * @returns ランキング\n   */\n  execute(\n    options?: ExecuteOptions\n  ): Promise<NarouSearchResults<UserSearchResult, TField>> {\n    return this.api.executeUserSearch(\n      this.params as UserSearchParams,\n      options\n    );\n  }\n}\n"],"mappings":"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"}