@inpageedit/core 0.13.0-alpha.0 → 0.13.0-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../../src/models/MemoryStorage.ts","../../src/models/WikiPage/index.ts","../../src/models/WikiTitle/index.ts"],"sourcesContent":["export class MemoryStorage implements Storage {\n private values: Record<string, string> = {}\n get length(): number {\n return Object.keys(this.values).length\n }\n clear(): void {\n this.values = {}\n }\n getItem(key: string): string | null {\n return this.values[key] ?? null\n }\n setItem(key: string, value: string): void {\n this.values[key] = typeof value === 'string' ? value : String(value)\n }\n removeItem(key: string): void {\n delete this.values[key]\n }\n key(index: number): string | null {\n const keys = Object.keys(this.values)\n return keys[index] ?? null\n }\n}\nexport const useMemoryStorage = () => {\n // handle storage.foo = 'bar' case\n return new Proxy(new MemoryStorage(), {\n set(target, prop, value) {\n if (typeof prop === 'string') {\n target.setItem(prop, value)\n }\n return true\n },\n get(target, prop) {\n if (typeof prop === 'string' && !(prop in target)) {\n return target.getItem(prop)\n }\n return Reflect.get(target, prop)\n },\n })\n}\n","import type { PageInfo } from './types/PageInfo'\nimport { PageParseData } from './types/PageParseData'\nimport { WatchlistAction } from './types/WatchlistAction'\nimport { MediaWikiApi, MwApiParams, MwApiResponse, FexiosFinalContext } from 'wiki-saikou/browser'\n\nexport interface WikiPageEditPayload {\n text?: string\n prependtext?: string\n appendtext?: string\n summary?: string\n watchlist?: WatchlistAction\n section?: number | 'new' | undefined\n}\n\nexport interface IWikiPage {\n pageInfo: PageInfo\n parse(params?: MwApiParams): Promise<FexiosFinalContext<MwApiResponse<{ parse: PageParseData }>>>\n preview(\n text: string,\n params?: MwApiParams\n ): Promise<FexiosFinalContext<MwApiResponse<{ parse: PageParseData }>>>\n edit(\n payload: WikiPageEditPayload,\n params?: MwApiParams\n ): Promise<FexiosFinalContext<MwApiResponse<{ success: boolean }>>>\n createOnly(\n payload: { text: string } & Pick<WikiPageEditPayload, 'summary' | 'watchlist'>,\n params?: MwApiParams\n ): Promise<FexiosFinalContext<MwApiResponse<{ success: boolean }>>>\n delete(\n reason?: string,\n params?: MwApiParams\n ): Promise<\n FexiosFinalContext<\n MwApiResponse<{\n delete: {\n title: string\n reason: string\n logid: boolean\n }\n }>\n >\n >\n moveTo(\n title: string,\n reason?: string,\n params?: Partial<\n MwApiParams & {\n movetalk: boolean\n movesubpages: boolean\n }\n >\n ): Promise<FexiosFinalContext<MwApiResponse<{ success: boolean }>>>\n userCan(action: keyof PageInfo['actions']): boolean\n userCanEdit(): boolean\n reloadSelfInfo(): Promise<this>\n // sugar getters (instance level)\n readonly pageid: PageInfo['pageid']\n readonly title: PageInfo['title']\n readonly ns: PageInfo['ns']\n readonly contentmodel: PageInfo['contentmodel']\n readonly fullurl: PageInfo['fullurl']\n readonly canonicalurl: PageInfo['canonicalurl']\n readonly editurl: PageInfo['editurl']\n readonly revisions: NonNullable<PageInfo['revisions']>\n readonly lastrevid: PageInfo['lastrevid']\n readonly templates: NonNullable<PageInfo['templates']>\n readonly images: NonNullable<PageInfo['images']>\n}\n\nexport interface WikiPageConstructor {\n // Constructor\n new (pageInfo: Partial<PageInfo>, loaded?: boolean): IWikiPage\n // Static members\n newFromApi(payload: MwApiParams): Promise<IWikiPage>\n newBlankPage(init?: Partial<PageInfo>): IWikiPage\n /**\n * Create a new WikiPage instance from any kind of identifier\n * priority: revid > pageid > title\n */\n newFromAnyKind(payload: {\n title?: string\n pageid?: number\n revid?: number\n }): Promise<IWikiPage | null>\n newBatchFromApi(\n params: MwApiParams & {\n titles?: string[]\n pageids?: number[]\n revids?: number[]\n }\n ): Promise<IWikiPage[]>\n}\n\nexport function createWikiPageModel(api: MediaWikiApi): WikiPageConstructor {\n class WikiPage implements IWikiPage {\n private static readonly api = api\n readonly api = api\n public pageInfo: PageInfo\n static readonly DEFAULT_QUERY_PARAMS: MwApiParams = {\n action: 'query',\n prop: 'info|templates|transcludedin|images|pageimages|revisions',\n inprop: 'protection|url|varianttitles',\n intestactions: 'edit|move|delete',\n tllimit: 'max',\n tilimit: 'max',\n imlimit: 'max',\n piprop: 'thumbnail|name|original',\n pithumbsize: '200',\n pilimit: 'max',\n rvprop: 'ids|timestamp|flags|comment|user|content',\n rvslots: 'main',\n }\n static readonly DEFAULT_PAGE_INFO: PageInfo = {\n pageid: 0,\n ns: 0,\n title: '',\n contentmodel: 'wikitext',\n pagelanguage: '',\n pagelanguagehtmlcode: '',\n pagelanguagedir: 'ltr',\n touched: new Date().toISOString(),\n lastrevid: 0,\n length: 0,\n protection: [],\n restrictiontypes: [],\n fullurl: '',\n canonicalurl: '',\n editurl: '',\n varianttitles: {},\n actions: {\n edit: true,\n move: false,\n delete: false,\n },\n revisions: [],\n templates: [],\n images: [],\n }\n\n constructor(\n pageInfo: Partial<PageInfo>,\n public _loaded = true\n ) {\n // Handle modern MW content model slots\n pageInfo.revisions?.forEach((rev) => {\n // @ts-ignore\n if (typeof rev?.slots?.main === 'object') {\n Object.assign(rev, (rev as any).slots.main)\n }\n })\n this.pageInfo = {\n ...WikiPage.DEFAULT_PAGE_INFO,\n ...pageInfo,\n }\n }\n\n // Utils\n static async newFromApi(payload: MwApiParams) {\n const { data } = await this.api.get<{\n query: {\n pages: PageInfo[]\n }\n }>({\n ...WikiPage.DEFAULT_QUERY_PARAMS,\n ...payload,\n })\n const info = data?.query?.pages?.[0]\n if (!info || !info.title) {\n throw new Error('Invalid page info', { cause: data })\n }\n return new WikiPage(info, true)\n }\n static newBlankPage(init: Partial<PageInfo> = {}) {\n return new WikiPage(init, false)\n }\n static async newFromAnyKind(payload: { title?: string; pageId?: number; revisionId?: number }) {\n const { title, pageId, revisionId } = payload || {}\n if (revisionId) {\n return this.newFromApi({ revids: parseInt(revisionId.toString(), 10) })\n } else if (pageId) {\n return this.newFromApi({ pageids: parseInt(pageId.toString(), 10) })\n } else if (title) {\n return this.newFromApi({ titles: title.toString() })\n }\n return null\n }\n static async newBatchFromApi(\n params: MwApiParams & {\n titles?: string[]\n pageids?: number[]\n revids?: number[]\n }\n ) {\n const { titles, pageids, revids, ...rest } = params || {}\n const { data } = await this.api.post<{\n query: {\n pages: PageInfo[]\n }\n }>({\n ...WikiPage.DEFAULT_QUERY_PARAMS,\n titles: titles?.join('|') ?? undefined,\n pageids: pageids?.join('|') ?? undefined,\n revids: revids?.join('|') ?? undefined,\n ...rest,\n })\n return data?.query?.pages?.map((page) => new WikiPage(page, true)) || []\n }\n\n // Page actions\n async parse(params?: MwApiParams) {\n return this.api.post({\n action: 'parse',\n page: this.pageInfo.title,\n prop: 'text|langlinks|categories|links|templates|images|externallinks|sections|revid|displaytitle|iwlinks|properties|parsewarnings',\n ...params,\n })\n }\n async preview(text: string, params?: MwApiParams) {\n return this.parse({\n action: 'parse',\n page: undefined,\n title: this.title,\n text,\n pst: 1,\n preview: 1,\n disableeditsection: 1,\n disablelimitreport: 1,\n ...params,\n })\n }\n async edit(payload: WikiPageEditPayload, params?: MwApiParams) {\n const {\n text,\n prependtext,\n appendtext,\n summary = '',\n watchlist = WatchlistAction.preferences,\n section,\n } = payload\n return this.api.postWithEditToken({\n action: 'edit',\n title: this.title,\n starttimestamp: this.pageInfo.touched,\n basetimestamp: this.revisions[0]?.timestamp,\n text,\n prependtext,\n appendtext,\n summary,\n watchlist,\n section,\n ...params,\n })\n }\n async createOnly(\n payload: { text: string; summary?: string; watchlist?: WatchlistAction },\n params?: MwApiParams\n ) {\n return this.edit(payload, { createonly: 1, ...params })\n }\n async delete(reason?: string, params?: MwApiParams & { deletetalk?: boolean }) {\n return this.api.postWithEditToken<{\n delete: {\n title: string\n reason: string\n logid: boolean\n }\n }>({\n action: 'delete',\n title: this.pageInfo.title || undefined,\n pageid: this.pageInfo.pageid || undefined,\n reason,\n deletetalk: params?.deletetalk,\n ...params,\n })\n }\n async moveTo(\n title: string,\n reason?: string,\n params?: Partial<\n MwApiParams & {\n movetalk: boolean\n movesubpages: boolean\n }\n >\n ) {\n return this.api.postWithEditToken({\n action: 'move',\n from: this.pageInfo.title,\n to: title,\n reason,\n movetalk: 1,\n movesubpages: 1,\n ...params,\n })\n }\n\n // === utilities ===\n\n userCan(action: keyof PageInfo['actions']) {\n const val = this.pageInfo?.actions?.[action]\n return !!val\n }\n userCanEdit() {\n return this.userCan('edit')\n }\n async reloadSelfInfo() {\n const page = await WikiPage.newFromApi({\n pageids: this.pageInfo.pageid,\n titles: this.pageInfo.title,\n })\n const revisions = (this.pageInfo.revisions || [])\n .concat(page.revisions || [])\n .sort((a, b) => a.revid - b.revid)\n .reduce(\n (acc, cur) => {\n if (!acc.find((rev) => rev.revid === cur.revid)) acc.push(cur)\n return acc\n },\n [] as Required<PageInfo>['revisions']\n )\n this.pageInfo = page.pageInfo\n this.pageInfo.revisions = revisions\n this._loaded = true\n return this\n }\n\n // === sugar getters ===\n get pageid() {\n return this.pageInfo.pageid\n }\n get title() {\n return this.pageInfo.title\n }\n get ns() {\n return this.pageInfo.ns\n }\n get contentmodel() {\n return this.pageInfo.contentmodel\n }\n get fullurl() {\n return this.pageInfo.fullurl\n }\n get canonicalurl() {\n return this.pageInfo.canonicalurl\n }\n get editurl() {\n return this.pageInfo.editurl\n }\n get revisions() {\n return this.pageInfo.revisions || []\n }\n get lastrevid() {\n return this.pageInfo.lastrevid\n }\n get templates() {\n return this.pageInfo.templates || []\n }\n get images() {\n return this.pageInfo.images || []\n }\n }\n\n return WikiPage as WikiPageConstructor\n}\n\n// re-export types\nexport * from './types/PageInfo'\nexport * from './types/PageParseData'\nexport * from './types/WatchlistAction'\n","import { WikiSiteInfo } from '@/types/WikiMetadata'\n\n// 使用 WeakMap 避免内存泄漏\nconst caches = new WeakMap<WikiSiteInfo, WikiTitleConstructor>()\n\n// 命名空间查找索引\ninterface NamespaceIndex {\n byName: Map<string, number>\n byCanonical: Map<string, number>\n byAlias: Map<string, number>\n byNormalized: Map<string, number> // 标准化索引:全小写+下划线格式\n}\n\n// 特殊页面别名索引\ninterface SpecialPageIndex {\n byRealName: Map<string, string> // realname -> realname\n byAlias: Map<string, string> // alias -> realname\n byNormalized: Map<string, string> // normalized -> realname\n}\n\nexport interface IWikiTitle {\n /**\n * Get db key without namespace prefix\n * e.g. \"template:hello world\" -> \"Hello_world\"\n */\n getMainDBKey(): string\n\n /**\n * Get page name without namespace prefix\n * e.g. \"template:hello world\" -> \"Hello world\"\n */\n getMainText(): string\n\n /**\n * Get db key with namespace prefix\n * e.g. \"template:hello world\" -> \"Template:Hello_world\"\n */\n getPrefixedDBKey(): string\n\n /**\n * Get page name with namespace prefix\n * e.g. \"template:hello world\" -> \"Template:Hello world\"\n */\n getPrefixedText(): string\n\n // Shortcuts\n toText: () => string\n toString: () => string\n\n /**\n * Get namespace ID\n * e.g. \"template:hello world\" -> 10\n */\n getNamespaceId(): number\n\n /**\n * Get namespace text\n * e.g. \"template:hello world\" -> \"Template\"\n */\n getNamespaceText(): string\n\n /**\n * Get namespace db key\n * e.g. \"template talk:hello world\" -> \"Template_talk\"\n */\n getNamespaceDBKey(): string\n\n /**\n * Get subject page\n * If current page is subject page, return itself\n * e.g. \"template talk:hello world\" -> new WikiTitle(\"Template:Hello world\")\n */\n getSubjectPage(): IWikiTitle\n\n /**\n * Get talk page\n * If current page is talk page, return itself\n * If current page cannot have talk page, return null\n * e.g. \"template:hello world\" -> new WikiTitle(\"Template talk:Hello world\")\n */\n getTalkPage(): IWikiTitle | null\n\n /**\n * Get URL of the page\n * e.g. \"template:hello world\" -> \"https://example.com/wiki/Template:Hello_world\"\n */\n getURL(params?: Record<string, string> | URLSearchParams): URL\n\n /**\n * Reset current title with given title string\n */\n setTitle(title: string): IWikiTitle\n\n /**\n * Set main title, keep current ns, update dbkey\n */\n setMainText(mainTitle: string): IWikiTitle\n\n /**\n * Set namespace by text\n */\n setNamespaceText(namespaceText: string): IWikiTitle\n\n /**\n * Set namespace by ID\n */\n setNamespaceId(namespaceId: number): IWikiTitle\n\n /**\n * Check if the title is equal to another title\n */\n equals(other: IWikiTitle | string): boolean\n\n /**\n * Check if the title is specific special page\n * e.g. \"Special:Diff\" is \"差异\" or \"diff\" -> true\n */\n isSpecial(alia: string): boolean\n\n newTitle(title: string, namespace?: number): IWikiTitle\n}\n\nexport interface WikiTitleConstructor {\n new (title: string, namespace?: number): IWikiTitle\n create(title: string, namespace?: number): IWikiTitle\n}\n\n// 工具函数\nconst titleUtils = {\n toDBKey: (text: string): string => text.replace(/ /g, '_'),\n toNormalText: (text: string): string => text.replace(/_/g, ' '),\n ensureCase: (text: string, caseType: string): string => {\n if (caseType === 'first-letter') {\n return text.charAt(0).toUpperCase() + text.slice(1)\n } else {\n return text\n }\n },\n}\n\n// 特殊页面工具函数\nconst specialPageUtils = {\n /**\n * 标准化特殊页面名称:转换为全小写\n */\n normalizeSpecialPageName: (name: string): string => {\n return name.toLowerCase()\n },\n\n /**\n * 构建特殊页面别名索引\n */\n buildSpecialPageIndex: (metadata: WikiSiteInfo): SpecialPageIndex => {\n const byRealName = new Map<string, string>()\n const byAlias = new Map<string, string>()\n const byNormalized = new Map<string, string>()\n\n for (const specialPage of metadata.specialpagealiases) {\n const realName = specialPage.realname\n byRealName.set(realName, realName)\n\n // 添加标准化索引\n const normalizedRealName = specialPageUtils.normalizeSpecialPageName(realName)\n byNormalized.set(normalizedRealName, realName)\n\n // 处理别名\n for (const alias of specialPage.aliases) {\n byAlias.set(alias, realName)\n\n // 添加标准化的别名索引\n const normalizedAlias = specialPageUtils.normalizeSpecialPageName(alias)\n byNormalized.set(normalizedAlias, realName)\n }\n }\n\n return { byRealName, byAlias, byNormalized }\n },\n\n /**\n * 查找特殊页面的真实名称\n */\n findSpecialPageRealName: (name: string, index: SpecialPageIndex): string | null => {\n // 提取主部分(忽略子页面)\n const mainPart = name.split('/')[0]\n\n // 首先尝试原始输入(精确匹配)\n let result = index.byRealName.get(mainPart) ?? index.byAlias.get(mainPart)\n if (result !== undefined) {\n return result\n }\n\n // 标准化输入并查找\n const normalized = specialPageUtils.normalizeSpecialPageName(mainPart)\n return index.byNormalized.get(normalized) ?? null\n },\n}\n\n// 命名空间工具函数\nconst namespaceUtils = {\n /**\n * 标准化命名空间文本:转换为全小写+下划线格式\n */\n normalizeNamespaceText: (text: string): string => {\n return text\n .replace(/[_\\s]+/g, '_') // 将空格和下划线统一为下划线\n .toLowerCase()\n .replace(/^_+|_+$/g, '') // 移除首尾下划线\n },\n\n buildIndex: (metadata: WikiSiteInfo): NamespaceIndex => {\n const byName = new Map<string, number>()\n const byCanonical = new Map<string, number>()\n const byAlias = new Map<string, number>()\n const byNormalized = new Map<string, number>()\n\n // 构建命名空间索引\n for (const [id, ns] of Object.entries(metadata.namespaces)) {\n const nsId = parseInt(id)\n byName.set(ns.name, nsId)\n byCanonical.set(ns.canonical ?? '', nsId)\n\n // 添加标准化索引\n const normalizedName = namespaceUtils.normalizeNamespaceText(ns.name)\n const normalizedCanonical = namespaceUtils.normalizeNamespaceText(ns.canonical ?? '')\n byNormalized.set(normalizedName, nsId)\n byNormalized.set(normalizedCanonical, nsId)\n }\n\n // 构建别名索引\n for (const alias of metadata.namespacealiases) {\n byAlias.set(alias.alias, alias.id)\n\n // 添加标准化的别名索引\n const normalizedAlias = namespaceUtils.normalizeNamespaceText(alias.alias)\n byNormalized.set(normalizedAlias, alias.id)\n }\n\n return { byName, byCanonical, byAlias, byNormalized }\n },\n\n findNamespaceId: (namespaceText: string, index: NamespaceIndex): number | null => {\n // 首先尝试原始输入(精确匹配)\n let result =\n index.byName.get(namespaceText) ??\n index.byCanonical.get(namespaceText) ??\n index.byAlias.get(namespaceText)\n if (result !== undefined) {\n return result\n }\n\n // 标准化输入并查找\n const normalized = namespaceUtils.normalizeNamespaceText(namespaceText)\n return index.byNormalized.get(normalized) ?? null\n },\n\n isTalkPage: (ns: number): boolean => ns % 2 === 1 && ns > 0,\n\n getDefaultNamespaceInfo: (ns: number) => ({\n id: ns,\n name: '',\n canonical: '',\n case: 'first-letter' as const,\n content: false,\n nonincludable: false,\n subpages: false,\n }),\n}\n\nexport function createWikiTitleModel(metadata: WikiSiteInfo): WikiTitleConstructor {\n const exists = caches.get(metadata)\n if (exists) {\n return exists\n }\n\n // 预建命名空间索引\n const namespaceIndex = namespaceUtils.buildIndex(metadata)\n // 预建特殊页面索引\n const specialPageIndex = specialPageUtils.buildSpecialPageIndex(metadata)\n\n class WikiTitle implements IWikiTitle {\n static readonly _meta = metadata\n static readonly _namespaceIndex = namespaceIndex\n static readonly _specialPageIndex = specialPageIndex\n\n /** 缓存的 main title,不包含命名空间前缀,大小写和空格状态不确定 */\n #title: string\n /** 缓存的 namespace ID */\n #ns: number\n\n constructor(title: string, namespace?: number) {\n this.#title = title || ''\n this.#ns = namespace ?? 0\n\n // 只有在没有显式命名空间参数时才解析标题中的命名空间前缀\n if (namespace === void 0) {\n this.fixNSByTitle()\n } else {\n // 如果显式传入了命名空间,移除标题中的命名空间前缀\n this.stripNamespaceFromTitle()\n }\n\n if (this.getMainText() === '') {\n throw new Error('Invalid title')\n }\n }\n\n static create(title: string, namespace?: number): WikiTitle {\n return new WikiTitle(title, namespace)\n }\n newTitle = WikiTitle.create.bind(WikiTitle)\n\n private fixNSByTitle(): void {\n const colonIndex = this.#title.indexOf(':')\n if (colonIndex === -1) {\n return // 没有命名空间前缀\n }\n\n if (colonIndex === 0) {\n // 只有冒号,将冒号后的部分作为标题\n this.#title = this.#title.substring(1)\n return\n }\n\n const potentialNamespace = this.#title.substring(0, colonIndex)\n const mainTitle = this.#title.substring(colonIndex + 1)\n\n // 查找匹配的命名空间\n const namespaceId = namespaceUtils.findNamespaceId(\n potentialNamespace,\n WikiTitle._namespaceIndex\n )\n if (namespaceId !== null) {\n this.#title = mainTitle\n this.#ns = namespaceId\n }\n }\n\n private stripNamespaceFromTitle(): void {\n const colonIndex = this.#title.indexOf(':')\n if (colonIndex === -1) {\n return // 没有命名空间前缀,不需要处理\n }\n\n if (colonIndex === 0) {\n // 只有冒号,将冒号后的部分作为标题\n this.#title = this.#title.substring(1)\n return\n }\n\n const potentialNamespace = this.#title.substring(0, colonIndex)\n const mainTitle = this.#title.substring(colonIndex + 1)\n\n // 查找匹配的命名空间,如果找到则移除前缀\n const namespaceId = namespaceUtils.findNamespaceId(\n potentialNamespace,\n WikiTitle._namespaceIndex\n )\n if (namespaceId !== null) {\n // 移除命名空间前缀,只保留主标题\n this.#title = mainTitle\n }\n }\n\n private getNamespaceInfo() {\n return (\n WikiTitle._meta.namespaces[this.#ns] ?? namespaceUtils.getDefaultNamespaceInfo(this.#ns)\n )\n }\n\n getMainDBKey(): string {\n const nsInfo = this.getNamespaceInfo()\n\n // 如果是特殊页面,将主部分替换为真实名称,保留子页面部分\n if (this.#ns === -1) {\n const realName = specialPageUtils.findSpecialPageRealName(\n this.#title,\n WikiTitle._specialPageIndex\n )\n if (realName) {\n // 构建包含子页面的完整标题\n const subPage = this.#title.includes('/')\n ? this.#title.substring(this.#title.indexOf('/'))\n : ''\n const fullTitle = realName + subPage\n return titleUtils.ensureCase(titleUtils.toDBKey(fullTitle), nsInfo.case)\n }\n }\n\n return titleUtils.ensureCase(titleUtils.toDBKey(this.#title), nsInfo.case)\n }\n\n getMainText(): string {\n const nsInfo = this.getNamespaceInfo()\n\n // 如果是特殊页面,将主部分替换为真实名称,保留子页面部分\n if (this.#ns === -1) {\n const realName = specialPageUtils.findSpecialPageRealName(\n this.#title,\n WikiTitle._specialPageIndex\n )\n if (realName) {\n // 构建包含子页面的完整标题\n const subPage = this.#title.includes('/')\n ? this.#title.substring(this.#title.indexOf('/'))\n : ''\n const fullTitle = realName + subPage\n return titleUtils.ensureCase(titleUtils.toNormalText(fullTitle), nsInfo.case)\n }\n }\n\n return titleUtils.ensureCase(titleUtils.toNormalText(this.#title), nsInfo.case)\n }\n\n private getMainRootText(): string {\n return this.getMainText().split('/')[0]\n }\n\n getPrefixedDBKey(): string {\n if (this.#ns === 0) {\n return this.getMainDBKey()\n }\n return `${this.getNamespaceDBKey()}:${this.getMainDBKey()}`\n }\n\n getPrefixedText(): string {\n if (this.#ns === 0) {\n return this.getMainText()\n }\n return `${this.getNamespaceText()}:${this.getMainText()}`\n }\n\n // aliases\n toText = this.getPrefixedText.bind(this)\n toString = this.getPrefixedDBKey.bind(this)\n\n getNamespaceId(): number {\n return this.#ns\n }\n\n getNamespaceText(): string {\n return this.getNamespaceInfo().name ?? ''\n }\n getNamespaceDBKey(): string {\n const nsInfo = this.getNamespaceInfo()\n return titleUtils.ensureCase(titleUtils.toDBKey(this.getNamespaceText()), nsInfo.case)\n }\n\n getSubjectPage(): IWikiTitle {\n if (namespaceUtils.isTalkPage(this.#ns)) {\n const subjectNs = this.#ns - 1\n return new WikiTitle(this.#title, subjectNs)\n }\n return this\n }\n\n getTalkPage(): IWikiTitle | null {\n if (namespaceUtils.isTalkPage(this.#ns)) {\n return this\n }\n\n // 特殊页面和媒体页面没有讨论页\n if (this.#ns < 0) {\n return null\n }\n\n const talkNs = this.#ns + 1\n const talkNsInfo = WikiTitle._meta.namespaces[talkNs.toString()]\n if (!talkNsInfo) {\n return null\n }\n\n return new WikiTitle(this.#title, talkNs)\n }\n\n getURL(params?: Record<string, string> | URLSearchParams): URL {\n const articlePath = WikiTitle._meta.general.articlepath\n const prefixedDbKey = this.getPrefixedDBKey()\n\n // 替换 $1 占位符为页面标题,冒号不进行编码\n const path = articlePath.replace('$1', prefixedDbKey)\n const url = new URL(path, location.origin)\n\n if (params) {\n const searchParams =\n params instanceof URLSearchParams ? params : new URLSearchParams(params)\n\n searchParams.forEach((value, key) => {\n url.searchParams.set(key, value)\n })\n }\n\n return url\n }\n\n /**\n * 设置标题,重置当前实例的 dbkey 和 ns\n * @param title 新的标题字符串\n */\n setTitle(title: string): this {\n this.#title = title\n this.#ns = 0\n this.fixNSByTitle()\n return this\n }\n\n setMainText(text: string): this {\n this.#title = text\n return this\n }\n\n setNamespaceText(namespaceText: string): this {\n const namespaceId = namespaceUtils.findNamespaceId(namespaceText, WikiTitle._namespaceIndex)\n if (namespaceId !== null) {\n this.#ns = namespaceId\n }\n return this\n }\n\n setNamespaceId(namespaceId: number): this {\n this.#ns = namespaceId\n return this\n }\n\n equals(other: IWikiTitle | string): boolean {\n if (typeof other === 'string') {\n other = new WikiTitle(other)\n }\n return this.getPrefixedDBKey() === other.getPrefixedDBKey()\n }\n\n isSpecial(alia: string): boolean {\n // 如果不是特殊页面命名空间,直接返回 false\n if (this.#ns !== -1) {\n return false\n }\n const targetTitle = new WikiTitle(alia, -1)\n return this.getMainRootText() === targetTitle.getMainRootText()\n }\n\n toJSON(): Record<string, any> {\n return {\n ns: this.#ns,\n text: this.getMainText(),\n title: this.getPrefixedText(),\n url: this.getURL().toString(),\n isSpecial: this.#ns < 0,\n }\n }\n }\n\n caches.set(metadata, WikiTitle)\n return WikiTitle\n}\n"],"names":["MemoryStorage","key","value","index","useMemoryStorage","target","prop","createWikiPageModel","api","WikiPage","pageInfo","_loaded","rev","payload","data","info","init","title","pageId","revisionId","params","titles","pageids","revids","rest","page","text","prependtext","appendtext","summary","watchlist","WatchlistAction","section","reason","action","revisions","b","acc","cur","caches","titleUtils","caseType","specialPageUtils","name","metadata","byRealName","byAlias","byNormalized","specialPage","realName","normalizedRealName","alias","normalizedAlias","mainPart","result","normalized","namespaceUtils","byName","byCanonical","id","ns","nsId","normalizedName","normalizedCanonical","namespaceText","createWikiTitleModel","exists","namespaceIndex","specialPageIndex","WikiTitle","namespace","#title","#ns","colonIndex","potentialNamespace","mainTitle","namespaceId","nsInfo","subPage","fullTitle","subjectNs","talkNs","articlePath","prefixedDbKey","path","url","other","alia","targetTitle"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sources":["../../src/models/MemoryStorage.ts","../../src/models/WikiPage/index.ts","../../src/models/WikiTitle/index.ts"],"sourcesContent":["export class MemoryStorage implements Storage {\r\n private values: Record<string, string> = {}\r\n get length(): number {\r\n return Object.keys(this.values).length\r\n }\r\n clear(): void {\r\n this.values = {}\r\n }\r\n getItem(key: string): string | null {\r\n return this.values[key] ?? null\r\n }\r\n setItem(key: string, value: string): void {\r\n this.values[key] = typeof value === 'string' ? value : String(value)\r\n }\r\n removeItem(key: string): void {\r\n delete this.values[key]\r\n }\r\n key(index: number): string | null {\r\n const keys = Object.keys(this.values)\r\n return keys[index] ?? null\r\n }\r\n}\r\nexport const useMemoryStorage = () => {\r\n // handle storage.foo = 'bar' case\r\n return new Proxy(new MemoryStorage(), {\r\n set(target, prop, value) {\r\n if (typeof prop === 'string') {\r\n target.setItem(prop, value)\r\n }\r\n return true\r\n },\r\n get(target, prop) {\r\n if (typeof prop === 'string' && !(prop in target)) {\r\n return target.getItem(prop)\r\n }\r\n return Reflect.get(target, prop)\r\n },\r\n })\r\n}\r\n","import type { PageInfo } from './types/PageInfo'\nimport { PageParseData } from './types/PageParseData'\nimport { WatchlistAction } from './types/WatchlistAction'\nimport { MediaWikiApi, MwApiParams, MwApiResponse, FexiosFinalContext } from 'wiki-saikou/browser'\n\nexport interface WikiPageEditPayload {\n text?: string\n prependtext?: string\n appendtext?: string\n summary?: string\n watchlist?: WatchlistAction\n section?: number | 'new' | undefined\n}\n\nexport interface IWikiPage {\n pageInfo: PageInfo\n parse(params?: MwApiParams): Promise<FexiosFinalContext<MwApiResponse<{ parse: PageParseData }>>>\n preview(\n text: string,\n params?: MwApiParams\n ): Promise<FexiosFinalContext<MwApiResponse<{ parse: PageParseData }>>>\n edit(\n payload: WikiPageEditPayload,\n params?: MwApiParams\n ): Promise<FexiosFinalContext<MwApiResponse<{ success: boolean }>>>\n createOnly(\n payload: { text: string } & Pick<WikiPageEditPayload, 'summary' | 'watchlist'>,\n params?: MwApiParams\n ): Promise<FexiosFinalContext<MwApiResponse<{ success: boolean }>>>\n delete(\n reason?: string,\n params?: MwApiParams\n ): Promise<\n FexiosFinalContext<\n MwApiResponse<{\n delete: {\n title: string\n reason: string\n logid: boolean\n }\n }>\n >\n >\n moveTo(\n title: string,\n reason?: string,\n params?: Partial<\n MwApiParams & {\n movetalk: boolean\n movesubpages: boolean\n }\n >\n ): Promise<FexiosFinalContext<MwApiResponse<{ success: boolean }>>>\n userCan(action: keyof PageInfo['actions']): boolean\n userCanEdit(): boolean\n reloadSelfInfo(): Promise<this>\n // sugar getters (instance level)\n readonly pageid: PageInfo['pageid']\n readonly title: PageInfo['title']\n readonly ns: PageInfo['ns']\n readonly contentmodel: PageInfo['contentmodel']\n readonly fullurl: PageInfo['fullurl']\n readonly canonicalurl: PageInfo['canonicalurl']\n readonly editurl: PageInfo['editurl']\n readonly revisions: NonNullable<PageInfo['revisions']>\n readonly lastrevid: PageInfo['lastrevid']\n readonly templates: NonNullable<PageInfo['templates']>\n readonly images: NonNullable<PageInfo['images']>\n}\n\nexport interface WikiPageConstructor {\n // Constructor\n new (pageInfo: Partial<PageInfo>, loaded?: boolean): IWikiPage\n // Static members\n newFromApi(payload: MwApiParams): Promise<IWikiPage>\n newBlankPage(init?: Partial<PageInfo>): IWikiPage\n /**\n * Create a new WikiPage instance from any kind of identifier\n * priority: revid > pageid > title\n */\n newFromAnyKind(payload: {\n title?: string\n pageid?: number\n revid?: number\n }): Promise<IWikiPage | null>\n newBatchFromApi(\n params: MwApiParams & {\n titles?: string[]\n pageids?: number[]\n revids?: number[]\n }\n ): Promise<IWikiPage[]>\n}\n\nexport function createWikiPageModel(api: MediaWikiApi): WikiPageConstructor {\n class WikiPage implements IWikiPage {\n private static readonly api = api\n readonly api = api\n public pageInfo: PageInfo\n static readonly DEFAULT_QUERY_PARAMS: MwApiParams = {\n action: 'query',\n prop: 'info|templates|transcludedin|images|pageimages|revisions',\n inprop: 'protection|url|varianttitles',\n intestactions: 'edit|move|delete',\n tllimit: 'max',\n tilimit: 'max',\n imlimit: 'max',\n piprop: 'thumbnail|name|original',\n pithumbsize: '200',\n pilimit: 'max',\n rvprop: 'ids|timestamp|flags|comment|user|content',\n rvslots: 'main',\n }\n static readonly DEFAULT_PAGE_INFO: PageInfo = {\n pageid: 0,\n ns: 0,\n title: '',\n contentmodel: 'wikitext',\n pagelanguage: '',\n pagelanguagehtmlcode: '',\n pagelanguagedir: 'ltr',\n touched: new Date().toISOString(),\n lastrevid: 0,\n length: 0,\n protection: [],\n restrictiontypes: [],\n fullurl: '',\n canonicalurl: '',\n editurl: '',\n varianttitles: {},\n actions: {\n edit: true,\n move: false,\n delete: false,\n },\n revisions: [],\n templates: [],\n images: [],\n }\n\n constructor(\n pageInfo: Partial<PageInfo>,\n public _loaded = true\n ) {\n // Handle modern MW content model slots\n pageInfo.revisions?.forEach((rev) => {\n // @ts-ignore\n if (typeof rev?.slots?.main === 'object') {\n Object.assign(rev, (rev as any).slots.main)\n }\n })\n this.pageInfo = {\n ...WikiPage.DEFAULT_PAGE_INFO,\n ...pageInfo,\n }\n }\n\n // Utils\n static async newFromApi(payload: MwApiParams) {\n const { data } = await this.api.get<{\n query: {\n pages: PageInfo[]\n }\n }>({\n ...WikiPage.DEFAULT_QUERY_PARAMS,\n ...payload,\n })\n const info = data?.query?.pages?.[0]\n if (!info || !info.title) {\n throw new Error('Invalid page info', { cause: data })\n }\n return new WikiPage(info, true)\n }\n static newBlankPage(init: Partial<PageInfo> = {}) {\n return new WikiPage(init, false)\n }\n static async newFromAnyKind(payload: { title?: string; pageId?: number; revisionId?: number }) {\n const { title, pageId, revisionId } = payload || {}\n if (revisionId) {\n return this.newFromApi({ revids: parseInt(revisionId.toString(), 10) })\n } else if (pageId) {\n return this.newFromApi({ pageids: parseInt(pageId.toString(), 10) })\n } else if (title) {\n return this.newFromApi({ titles: title.toString() })\n }\n return null\n }\n static async newBatchFromApi(\n params: MwApiParams & {\n titles?: string[]\n pageids?: number[]\n revids?: number[]\n }\n ) {\n const { titles, pageids, revids, ...rest } = params || {}\n const { data } = await this.api.post<{\n query: {\n pages: PageInfo[]\n }\n }>({\n ...WikiPage.DEFAULT_QUERY_PARAMS,\n titles: titles?.join('|') ?? undefined,\n pageids: pageids?.join('|') ?? undefined,\n revids: revids?.join('|') ?? undefined,\n ...rest,\n })\n return data?.query?.pages?.map((page) => new WikiPage(page, true)) || []\n }\n\n // Page actions\n async parse(params?: MwApiParams) {\n return this.api.post({\n action: 'parse',\n page: this.pageInfo.title,\n prop: 'text|langlinks|categories|links|templates|images|externallinks|sections|revid|displaytitle|iwlinks|properties|parsewarnings',\n ...params,\n })\n }\n async preview(text: string, params?: MwApiParams) {\n return this.parse({\n action: 'parse',\n page: undefined,\n title: this.title,\n text,\n pst: 1,\n preview: 1,\n disableeditsection: 1,\n disablelimitreport: 1,\n ...params,\n })\n }\n async edit(payload: WikiPageEditPayload, params?: MwApiParams) {\n const {\n text,\n prependtext,\n appendtext,\n summary = '',\n watchlist = WatchlistAction.preferences,\n section,\n } = payload\n return this.api.postWithEditToken({\n action: 'edit',\n title: this.title,\n starttimestamp: this.pageInfo.touched,\n basetimestamp: this.revisions[0]?.timestamp,\n text,\n prependtext,\n appendtext,\n summary,\n watchlist,\n section,\n ...params,\n })\n }\n async createOnly(\n payload: { text: string; summary?: string; watchlist?: WatchlistAction },\n params?: MwApiParams\n ) {\n return this.edit(payload, { createonly: 1, ...params })\n }\n async delete(reason?: string, params?: MwApiParams & { deletetalk?: boolean }) {\n return this.api.postWithEditToken<{\n delete: {\n title: string\n reason: string\n logid: boolean\n }\n }>({\n action: 'delete',\n title: this.pageInfo.title || undefined,\n pageid: this.pageInfo.pageid || undefined,\n reason,\n deletetalk: params?.deletetalk,\n ...params,\n })\n }\n async moveTo(\n title: string,\n reason?: string,\n params?: Partial<\n MwApiParams & {\n movetalk: boolean\n movesubpages: boolean\n }\n >\n ) {\n return this.api.postWithEditToken({\n action: 'move',\n from: this.pageInfo.title,\n to: title,\n reason,\n movetalk: 1,\n movesubpages: 1,\n ...params,\n })\n }\n\n // === utilities ===\n\n userCan(action: keyof PageInfo['actions']) {\n const val = this.pageInfo?.actions?.[action]\n return !!val\n }\n userCanEdit() {\n return this.userCan('edit')\n }\n async reloadSelfInfo() {\n const page = await WikiPage.newFromApi({\n pageids: this.pageInfo.pageid,\n titles: this.pageInfo.title,\n })\n const revisions = (this.pageInfo.revisions || [])\n .concat(page.revisions || [])\n .sort((a, b) => a.revid - b.revid)\n .reduce(\n (acc, cur) => {\n if (!acc.find((rev) => rev.revid === cur.revid)) acc.push(cur)\n return acc\n },\n [] as Required<PageInfo>['revisions']\n )\n this.pageInfo = page.pageInfo\n this.pageInfo.revisions = revisions\n this._loaded = true\n return this\n }\n\n // === sugar getters ===\n get pageid() {\n return this.pageInfo.pageid\n }\n get title() {\n return this.pageInfo.title\n }\n get ns() {\n return this.pageInfo.ns\n }\n get contentmodel() {\n return this.pageInfo.contentmodel\n }\n get fullurl() {\n return this.pageInfo.fullurl\n }\n get canonicalurl() {\n return this.pageInfo.canonicalurl\n }\n get editurl() {\n return this.pageInfo.editurl\n }\n get revisions() {\n return this.pageInfo.revisions || []\n }\n get lastrevid() {\n return this.pageInfo.lastrevid\n }\n get templates() {\n return this.pageInfo.templates || []\n }\n get images() {\n return this.pageInfo.images || []\n }\n }\n\n return WikiPage as WikiPageConstructor\n}\n\n// re-export types\nexport * from './types/PageInfo'\nexport * from './types/PageParseData'\nexport * from './types/WatchlistAction'\n","import { WikiSiteInfo } from '@/types/WikiMetadata'\n\n// 使用 WeakMap 避免内存泄漏\nconst caches = new WeakMap<WikiSiteInfo, WikiTitleConstructor>()\n\n// 命名空间查找索引\ninterface NamespaceIndex {\n byName: Map<string, number>\n byCanonical: Map<string, number>\n byAlias: Map<string, number>\n byNormalized: Map<string, number> // 标准化索引:全小写+下划线格式\n}\n\n// 特殊页面别名索引\ninterface SpecialPageIndex {\n byRealName: Map<string, string> // realname -> realname\n byAlias: Map<string, string> // alias -> realname\n byNormalized: Map<string, string> // normalized -> realname\n}\n\nexport interface IWikiTitle {\n /**\n * Get db key without namespace prefix\n * e.g. \"template:hello world\" -> \"Hello_world\"\n */\n getMainDBKey(): string\n\n /**\n * Get page name without namespace prefix\n * e.g. \"template:hello world\" -> \"Hello world\"\n */\n getMainText(): string\n\n /**\n * Get db key with namespace prefix\n * e.g. \"template:hello world\" -> \"Template:Hello_world\"\n */\n getPrefixedDBKey(): string\n\n /**\n * Get page name with namespace prefix\n * e.g. \"template:hello world\" -> \"Template:Hello world\"\n */\n getPrefixedText(): string\n\n // Shortcuts\n toText: () => string\n toString: () => string\n\n /**\n * Get namespace ID\n * e.g. \"template:hello world\" -> 10\n */\n getNamespaceId(): number\n\n /**\n * Get namespace text\n * e.g. \"template:hello world\" -> \"Template\"\n */\n getNamespaceText(): string\n\n /**\n * Get namespace db key\n * e.g. \"template talk:hello world\" -> \"Template_talk\"\n */\n getNamespaceDBKey(): string\n\n /**\n * Get subject page\n * If current page is subject page, return itself\n * e.g. \"template talk:hello world\" -> new WikiTitle(\"Template:Hello world\")\n */\n getSubjectPage(): IWikiTitle\n\n /**\n * Get talk page\n * If current page is talk page, return itself\n * If current page cannot have talk page, return null\n * e.g. \"template:hello world\" -> new WikiTitle(\"Template talk:Hello world\")\n */\n getTalkPage(): IWikiTitle | null\n\n /**\n * Get URL of the page\n * e.g. \"template:hello world\" -> \"https://example.com/wiki/Template:Hello_world\"\n */\n getURL(params?: Record<string, string> | URLSearchParams): URL\n\n /**\n * Reset current title with given title string\n */\n setTitle(title: string): IWikiTitle\n\n /**\n * Set main title, keep current ns, update dbkey\n */\n setMainText(mainTitle: string): IWikiTitle\n\n /**\n * Set namespace by text\n */\n setNamespaceText(namespaceText: string): IWikiTitle\n\n /**\n * Set namespace by ID\n */\n setNamespaceId(namespaceId: number): IWikiTitle\n\n /**\n * Check if the title is equal to another title\n */\n equals(other: IWikiTitle | string): boolean\n\n /**\n * Check if the title is specific special page\n * e.g. \"Special:Diff\" is \"差异\" or \"diff\" -> true\n */\n isSpecial(alia: string): boolean\n\n newTitle(title: string, namespace?: number): IWikiTitle\n}\n\nexport interface WikiTitleConstructor {\n new (title: string, namespace?: number): IWikiTitle\n create(title: string, namespace?: number): IWikiTitle\n}\n\n// 工具函数\nconst titleUtils = {\n toDBKey: (text: string): string => text.replace(/ /g, '_'),\n toNormalText: (text: string): string => text.replace(/_/g, ' '),\n ensureCase: (text: string, caseType: string): string => {\n if (caseType === 'first-letter') {\n return text.charAt(0).toUpperCase() + text.slice(1)\n } else {\n return text\n }\n },\n}\n\n// 特殊页面工具函数\nconst specialPageUtils = {\n /**\n * 标准化特殊页面名称:转换为全小写\n */\n normalizeSpecialPageName: (name: string): string => {\n return name.toLowerCase()\n },\n\n /**\n * 构建特殊页面别名索引\n */\n buildSpecialPageIndex: (metadata: WikiSiteInfo): SpecialPageIndex => {\n const byRealName = new Map<string, string>()\n const byAlias = new Map<string, string>()\n const byNormalized = new Map<string, string>()\n\n for (const specialPage of metadata.specialpagealiases) {\n const realName = specialPage.realname\n byRealName.set(realName, realName)\n\n // 添加标准化索引\n const normalizedRealName = specialPageUtils.normalizeSpecialPageName(realName)\n byNormalized.set(normalizedRealName, realName)\n\n // 处理别名\n for (const alias of specialPage.aliases) {\n byAlias.set(alias, realName)\n\n // 添加标准化的别名索引\n const normalizedAlias = specialPageUtils.normalizeSpecialPageName(alias)\n byNormalized.set(normalizedAlias, realName)\n }\n }\n\n return { byRealName, byAlias, byNormalized }\n },\n\n /**\n * 查找特殊页面的真实名称\n */\n findSpecialPageRealName: (name: string, index: SpecialPageIndex): string | null => {\n // 提取主部分(忽略子页面)\n const mainPart = name.split('/')[0]\n\n // 首先尝试原始输入(精确匹配)\n let result = index.byRealName.get(mainPart) ?? index.byAlias.get(mainPart)\n if (result !== undefined) {\n return result\n }\n\n // 标准化输入并查找\n const normalized = specialPageUtils.normalizeSpecialPageName(mainPart)\n return index.byNormalized.get(normalized) ?? null\n },\n}\n\n// 命名空间工具函数\nconst namespaceUtils = {\n /**\n * 标准化命名空间文本:转换为全小写+下划线格式\n */\n normalizeNamespaceText: (text: string): string => {\n return text\n .replace(/[_\\s]+/g, '_') // 将空格和下划线统一为下划线\n .toLowerCase()\n .replace(/^_+|_+$/g, '') // 移除首尾下划线\n },\n\n buildIndex: (metadata: WikiSiteInfo): NamespaceIndex => {\n const byName = new Map<string, number>()\n const byCanonical = new Map<string, number>()\n const byAlias = new Map<string, number>()\n const byNormalized = new Map<string, number>()\n\n // 构建命名空间索引\n for (const [id, ns] of Object.entries(metadata.namespaces)) {\n const nsId = parseInt(id)\n byName.set(ns.name, nsId)\n byCanonical.set(ns.canonical ?? '', nsId)\n\n // 添加标准化索引\n const normalizedName = namespaceUtils.normalizeNamespaceText(ns.name)\n const normalizedCanonical = namespaceUtils.normalizeNamespaceText(ns.canonical ?? '')\n byNormalized.set(normalizedName, nsId)\n byNormalized.set(normalizedCanonical, nsId)\n }\n\n // 构建别名索引\n for (const alias of metadata.namespacealiases) {\n byAlias.set(alias.alias, alias.id)\n\n // 添加标准化的别名索引\n const normalizedAlias = namespaceUtils.normalizeNamespaceText(alias.alias)\n byNormalized.set(normalizedAlias, alias.id)\n }\n\n return { byName, byCanonical, byAlias, byNormalized }\n },\n\n findNamespaceId: (namespaceText: string, index: NamespaceIndex): number | null => {\n // 首先尝试原始输入(精确匹配)\n let result =\n index.byName.get(namespaceText) ??\n index.byCanonical.get(namespaceText) ??\n index.byAlias.get(namespaceText)\n if (result !== undefined) {\n return result\n }\n\n // 标准化输入并查找\n const normalized = namespaceUtils.normalizeNamespaceText(namespaceText)\n return index.byNormalized.get(normalized) ?? null\n },\n\n isTalkPage: (ns: number): boolean => ns % 2 === 1 && ns > 0,\n\n getDefaultNamespaceInfo: (ns: number) => ({\n id: ns,\n name: '',\n canonical: '',\n case: 'first-letter' as const,\n content: false,\n nonincludable: false,\n subpages: false,\n }),\n}\n\nexport function createWikiTitleModel(metadata: WikiSiteInfo): WikiTitleConstructor {\n const exists = caches.get(metadata)\n if (exists) {\n return exists\n }\n\n // 预建命名空间索引\n const namespaceIndex = namespaceUtils.buildIndex(metadata)\n // 预建特殊页面索引\n const specialPageIndex = specialPageUtils.buildSpecialPageIndex(metadata)\n\n class WikiTitle implements IWikiTitle {\n static readonly _meta = metadata\n static readonly _namespaceIndex = namespaceIndex\n static readonly _specialPageIndex = specialPageIndex\n\n /** 缓存的 main title,不包含命名空间前缀,大小写和空格状态不确定 */\n #title: string\n /** 缓存的 namespace ID */\n #ns: number\n\n constructor(title: string, namespace?: number) {\n this.#title = title || ''\n this.#ns = namespace ?? 0\n\n // 只有在没有显式命名空间参数时才解析标题中的命名空间前缀\n if (namespace === void 0) {\n this.fixNSByTitle()\n } else {\n // 如果显式传入了命名空间,移除标题中的命名空间前缀\n this.stripNamespaceFromTitle()\n }\n\n if (this.getMainText() === '') {\n throw new Error('Invalid title')\n }\n }\n\n static create(title: string, namespace?: number): WikiTitle {\n return new WikiTitle(title, namespace)\n }\n newTitle = WikiTitle.create.bind(WikiTitle)\n\n private fixNSByTitle(): void {\n const colonIndex = this.#title.indexOf(':')\n if (colonIndex === -1) {\n return // 没有命名空间前缀\n }\n\n if (colonIndex === 0) {\n // 只有冒号,将冒号后的部分作为标题\n this.#title = this.#title.substring(1)\n return\n }\n\n const potentialNamespace = this.#title.substring(0, colonIndex)\n const mainTitle = this.#title.substring(colonIndex + 1)\n\n // 查找匹配的命名空间\n const namespaceId = namespaceUtils.findNamespaceId(\n potentialNamespace,\n WikiTitle._namespaceIndex\n )\n if (namespaceId !== null) {\n this.#title = mainTitle\n this.#ns = namespaceId\n }\n }\n\n private stripNamespaceFromTitle(): void {\n const colonIndex = this.#title.indexOf(':')\n if (colonIndex === -1) {\n return // 没有命名空间前缀,不需要处理\n }\n\n if (colonIndex === 0) {\n // 只有冒号,将冒号后的部分作为标题\n this.#title = this.#title.substring(1)\n return\n }\n\n const potentialNamespace = this.#title.substring(0, colonIndex)\n const mainTitle = this.#title.substring(colonIndex + 1)\n\n // 查找匹配的命名空间,如果找到则移除前缀\n const namespaceId = namespaceUtils.findNamespaceId(\n potentialNamespace,\n WikiTitle._namespaceIndex\n )\n if (namespaceId !== null) {\n // 移除命名空间前缀,只保留主标题\n this.#title = mainTitle\n }\n }\n\n private getNamespaceInfo() {\n return (\n WikiTitle._meta.namespaces[this.#ns] ?? namespaceUtils.getDefaultNamespaceInfo(this.#ns)\n )\n }\n\n getMainDBKey(): string {\n const nsInfo = this.getNamespaceInfo()\n\n // 如果是特殊页面,将主部分替换为真实名称,保留子页面部分\n if (this.#ns === -1) {\n const realName = specialPageUtils.findSpecialPageRealName(\n this.#title,\n WikiTitle._specialPageIndex\n )\n if (realName) {\n // 构建包含子页面的完整标题\n const subPage = this.#title.includes('/')\n ? this.#title.substring(this.#title.indexOf('/'))\n : ''\n const fullTitle = realName + subPage\n return titleUtils.ensureCase(titleUtils.toDBKey(fullTitle), nsInfo.case)\n }\n }\n\n return titleUtils.ensureCase(titleUtils.toDBKey(this.#title), nsInfo.case)\n }\n\n getMainText(): string {\n const nsInfo = this.getNamespaceInfo()\n\n // 如果是特殊页面,将主部分替换为真实名称,保留子页面部分\n if (this.#ns === -1) {\n const realName = specialPageUtils.findSpecialPageRealName(\n this.#title,\n WikiTitle._specialPageIndex\n )\n if (realName) {\n // 构建包含子页面的完整标题\n const subPage = this.#title.includes('/')\n ? this.#title.substring(this.#title.indexOf('/'))\n : ''\n const fullTitle = realName + subPage\n return titleUtils.ensureCase(titleUtils.toNormalText(fullTitle), nsInfo.case)\n }\n }\n\n return titleUtils.ensureCase(titleUtils.toNormalText(this.#title), nsInfo.case)\n }\n\n private getMainRootText(): string {\n return this.getMainText().split('/')[0]\n }\n\n getPrefixedDBKey(): string {\n if (this.#ns === 0) {\n return this.getMainDBKey()\n }\n return `${this.getNamespaceDBKey()}:${this.getMainDBKey()}`\n }\n\n getPrefixedText(): string {\n if (this.#ns === 0) {\n return this.getMainText()\n }\n return `${this.getNamespaceText()}:${this.getMainText()}`\n }\n\n // aliases\n toText = this.getPrefixedText.bind(this)\n toString = this.getPrefixedDBKey.bind(this)\n\n getNamespaceId(): number {\n return this.#ns\n }\n\n getNamespaceText(): string {\n return this.getNamespaceInfo().name ?? ''\n }\n getNamespaceDBKey(): string {\n const nsInfo = this.getNamespaceInfo()\n return titleUtils.ensureCase(titleUtils.toDBKey(this.getNamespaceText()), nsInfo.case)\n }\n\n getSubjectPage(): IWikiTitle {\n if (namespaceUtils.isTalkPage(this.#ns)) {\n const subjectNs = this.#ns - 1\n return new WikiTitle(this.#title, subjectNs)\n }\n return this\n }\n\n getTalkPage(): IWikiTitle | null {\n if (namespaceUtils.isTalkPage(this.#ns)) {\n return this\n }\n\n // 特殊页面和媒体页面没有讨论页\n if (this.#ns < 0) {\n return null\n }\n\n const talkNs = this.#ns + 1\n const talkNsInfo = WikiTitle._meta.namespaces[talkNs.toString()]\n if (!talkNsInfo) {\n return null\n }\n\n return new WikiTitle(this.#title, talkNs)\n }\n\n getURL(params?: Record<string, string> | URLSearchParams): URL {\n const articlePath = WikiTitle._meta.general.articlepath\n const prefixedDbKey = this.getPrefixedDBKey()\n\n // 替换 $1 占位符为页面标题,冒号不进行编码\n const path = articlePath.replace('$1', prefixedDbKey)\n const url = new URL(path, location.origin)\n\n if (params) {\n const searchParams =\n params instanceof URLSearchParams ? params : new URLSearchParams(params)\n\n searchParams.forEach((value, key) => {\n url.searchParams.set(key, value)\n })\n }\n\n return url\n }\n\n /**\n * 设置标题,重置当前实例的 dbkey 和 ns\n * @param title 新的标题字符串\n */\n setTitle(title: string): this {\n this.#title = title\n this.#ns = 0\n this.fixNSByTitle()\n return this\n }\n\n setMainText(text: string): this {\n this.#title = text\n return this\n }\n\n setNamespaceText(namespaceText: string): this {\n const namespaceId = namespaceUtils.findNamespaceId(namespaceText, WikiTitle._namespaceIndex)\n if (namespaceId !== null) {\n this.#ns = namespaceId\n }\n return this\n }\n\n setNamespaceId(namespaceId: number): this {\n this.#ns = namespaceId\n return this\n }\n\n equals(other: IWikiTitle | string): boolean {\n if (typeof other === 'string') {\n other = new WikiTitle(other)\n }\n return this.getPrefixedDBKey() === other.getPrefixedDBKey()\n }\n\n isSpecial(alia: string): boolean {\n // 如果不是特殊页面命名空间,直接返回 false\n if (this.#ns !== -1) {\n return false\n }\n const targetTitle = new WikiTitle(alia, -1)\n return this.getMainRootText() === targetTitle.getMainRootText()\n }\n\n toJSON(): Record<string, any> {\n return {\n ns: this.#ns,\n text: this.getMainText(),\n title: this.getPrefixedText(),\n url: this.getURL().toString(),\n isSpecial: this.#ns < 0,\n }\n }\n }\n\n caches.set(metadata, WikiTitle)\n return WikiTitle\n}\n"],"names":["MemoryStorage","key","value","index","useMemoryStorage","target","prop","createWikiPageModel","api","WikiPage","pageInfo","_loaded","rev","payload","data","info","init","title","pageId","revisionId","params","titles","pageids","revids","rest","page","text","prependtext","appendtext","summary","watchlist","WatchlistAction","section","reason","action","revisions","b","acc","cur","caches","titleUtils","caseType","specialPageUtils","name","metadata","byRealName","byAlias","byNormalized","specialPage","realName","normalizedRealName","alias","normalizedAlias","mainPart","result","normalized","namespaceUtils","byName","byCanonical","id","ns","nsId","normalizedName","normalizedCanonical","namespaceText","createWikiTitleModel","exists","namespaceIndex","specialPageIndex","WikiTitle","namespace","#title","#ns","colonIndex","potentialNamespace","mainTitle","namespaceId","nsInfo","subPage","fullTitle","subjectNs","talkNs","articlePath","prefixedDbKey","path","url","other","alia","targetTitle"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"noop-ClDc6zv4.js","sources":["../src/utils/noop.ts"],"sourcesContent":["export const noop = () => {}\n"],"names":["noop"],"mappings":"AAAO,MAAMA,IAAO,MAAM;AAAC;"}
1
+ {"version":3,"file":"noop-ClDc6zv4.js","sources":["../src/utils/noop.ts"],"sourcesContent":["export const noop = () => {}\r\n"],"names":["noop"],"mappings":"AAAO,MAAMA,IAAO,MAAM;AAAC;"}
@@ -1,7 +1,7 @@
1
1
  import { PluginAnalytics as i } from "../index-BQ-cHWkJ.js";
2
2
  import { PluginInArticleLinks as u } from "../index-BJ7_Q1mB.js";
3
3
  import { PluginPluginStore as t } from "../index-BwdWyHLe.js";
4
- import { PluginPreferencesUI as f } from "../index-BCdABp0e.js";
4
+ import { PluginPreferencesUI as f } from "../index-B7c6jL9x.js";
5
5
  import { PluginQuickDiff as g } from "../index-CCRMmnwk.js";
6
6
  import { PluginQuickEdit as m } from "../index-CyG7_IYz.js";
7
7
  import { PluginQuickMove as c } from "../index-2RfILgXm.js";
@@ -1,4 +1,4 @@
1
- import { A as r, C as i, b as s, N as c, P as o, M as v, c as S, R as t, a as d, W as P, d as M, e as l } from "../index-DdTiZqwt.js";
1
+ import { A as r, C as i, b as s, N as c, P as o, M as v, c as S, R as t, a as d, W as P, d as M, e as l } from "../index-C_BIsubQ.js";
2
2
  export {
3
3
  r as ApiService,
4
4
  i as CurrentPageService,