{"_id":"@coszone/koharu-astro","_rev":"2-66c1880376dcd3a23195db1dbac0b566","name":"@coszone/koharu-astro","dist-tags":{"latest":"0.2.0"},"versions":{"0.1.0":{"name":"@coszone/koharu-astro","version":"0.1.0","keywords":["astro","astro-loader","content-collections","koharu","telegram","withastro"],"license":"AGPL-3.0-only","_id":"@coszone/koharu-astro@0.1.0","maintainers":[{"name":"coszone","email":"cosine2333@gmail.com"}],"homepage":"https://github.com/cosZone/koharu-suite#readme","bugs":{"url":"https://github.com/cosZone/koharu-suite/issues"},"dist":{"shasum":"cb7f630739bed0465bc38a90f917f4976aef2808","tarball":"https://registry.npmjs.org/@coszone/koharu-astro/-/koharu-astro-0.1.0.tgz","fileCount":16,"integrity":"sha512-ZuNZHMcp8ebGIVn6UAICghvCS11NeOqGMsqsRgcxBpY/uitEZF6eHyEO01FPL3eXKgbiXQ/mI8k44LNVodSsYg==","signatures":[{"sig":"MEUCIQDqdjsjLb1Bdbtyqf8P+iN05PP8pBRHSX+Q1kJZahcHoQIgGoRN8+K2NkST+fcPnRJURbs0zqHSandCYAtUpTBeyD4=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":77569},"type":"module","_from":"file:.artifacts/koharu-astro-ci/package.tgz","engines":{"node":">=22.20.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./client":{"types":"./dist/client.d.ts","import":"./dist/client.js"},"./loaders":{"types":"./dist/loaders.d.ts","import":"./dist/loaders.js"},"./schemas":{"types":"./dist/schemas.d.ts","import":"./dist/schemas.js"},"./package.json":"./package.json"},"scripts":{"test":"vitest run","build":"tsc -p tsconfig.build.json","typecheck":"tsc --noEmit"},"_npmUser":{"name":"coszone","email":"cosine2333@gmail.com"},"_resolved":"/Users/nahida/Documents/Programming/me/koharu-suite/.artifacts/koharu-astro-ci/package.tgz","_integrity":"sha512-ZuNZHMcp8ebGIVn6UAICghvCS11NeOqGMsqsRgcxBpY/uitEZF6eHyEO01FPL3eXKgbiXQ/mI8k44LNVodSsYg==","repository":{"url":"git+https://github.com/cosZone/koharu-suite.git","type":"git","directory":"packages/koharu-astro"},"_npmVersion":"11.8.0","description":"Typed Koharu Suite client and Astro 6 Live Content Collection loaders.","directories":{},"sideEffects":false,"_nodeVersion":"25.6.0","publishConfig":{"access":"public","registry":"https://registry.npmjs.org/","provenance":true},"_hasShrinkwrap":false,"devDependencies":{"astro":"6.4.8","vitest":"4.1.10","typescript":"7.0.2","@types/node":"22.20.1"},"peerDependencies":{"astro":"^6.0.0"},"_npmOperationalInternal":{"tmp":"tmp/koharu-astro_0.1.0_1784968675495_0.28633698932263174","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"_id":"@coszone/koharu-astro@0.2.0","bugs":{"url":"https://github.com/cosZone/koharu-suite/issues"},"dist":{"shasum":"a112576695878a976afcee756a55e6c83726768e","tarball":"https://registry.npmjs.org/@coszone/koharu-astro/-/koharu-astro-0.2.0.tgz","integrity":"sha512-K2w3JUMC+LnlFIKscUgdZ9PawwXoRYCxaHBwm5mxKLr8zgtTKpqbzAoXVsA3w9aGiJYDs2WrSvZzUkc3erUCjQ==","fileCount":16,"unpackedSize":84656,"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@coszone%2fkoharu-astro@0.2.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIGW1hbee8aphmvcSSJ73ubx4ZdZfAoyCl4/1FM3vIq2uAiEAunoitwyzmAgpYCTfBnQrfi/Dowv1lNAfOJ1LQj05HAw="}]},"name":"@coszone/koharu-astro","type":"module","_from":"file:.artifacts/koharu-astro/package.tgz","engines":{"node":">=22.20.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./client":{"types":"./dist/client.d.ts","import":"./dist/client.js"},"./loaders":{"types":"./dist/loaders.d.ts","import":"./dist/loaders.js"},"./schemas":{"types":"./dist/schemas.d.ts","import":"./dist/schemas.js"},"./package.json":"./package.json"},"license":"AGPL-3.0-only","scripts":{"test":"vitest run","build":"tsc -p tsconfig.build.json","typecheck":"tsc --noEmit"},"version":"0.2.0","_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:6d4b1222-ee00-45dd-b431-53e09b06697d"},"approver":{"name":"coszone","email":"cosine2333@gmail.com"}},"homepage":"https://github.com/cosZone/koharu-suite#readme","keywords":["astro","astro-loader","content-collections","koharu","telegram","withastro"],"_resolved":"/home/runner/work/koharu-suite/koharu-suite/.artifacts/koharu-astro/package.tgz","_integrity":"sha512-K2w3JUMC+LnlFIKscUgdZ9PawwXoRYCxaHBwm5mxKLr8zgtTKpqbzAoXVsA3w9aGiJYDs2WrSvZzUkc3erUCjQ==","repository":{"url":"git+https://github.com/cosZone/koharu-suite.git","type":"git","directory":"packages/koharu-astro"},"_npmVersion":"11.18.0","description":"Typed Koharu Suite client and Astro 6/7 Live Content Collection loaders.","directories":{},"maintainers":[{"name":"coszone","email":"cosine2333@gmail.com"}],"sideEffects":false,"_nodeVersion":"24.18.0","publishConfig":{"access":"public","registry":"https://registry.npmjs.org/","provenance":true},"devDependencies":{"astro":"6.4.8","vitest":"4.1.10","typescript":"7.0.2","@types/node":"22.20.1"},"peerDependencies":{"astro":"^6.0.0 || ^7.0.0"},"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/koharu-astro_0.2.0_1785015078253_0.8927884655181237"},"_hasShrinkwrap":false}},"time":{"created":"2026-07-25T08:37:55.299Z","modified":"2026-07-25T21:31:18.684Z","0.1.0":"2026-07-25T08:37:55.626Z","0.2.0":"2026-07-25T21:31:18.338Z"},"bugs":{"url":"https://github.com/cosZone/koharu-suite/issues"},"license":"AGPL-3.0-only","homepage":"https://github.com/cosZone/koharu-suite#readme","keywords":["astro","astro-loader","content-collections","koharu","telegram","withastro"],"repository":{"url":"git+https://github.com/cosZone/koharu-suite.git","type":"git","directory":"packages/koharu-astro"},"description":"Typed Koharu Suite client and Astro 6/7 Live Content Collection loaders.","maintainers":[{"name":"coszone","email":"cosine2333@gmail.com"}],"readme":"# `@coszone/koharu-astro`\n\n`@coszone/koharu-astro` 是 [koharu-suite](https://github.com/cosZone/koharu-suite) 的 Astro 6/7\n适配器，提供：\n\n- 经过 Zod 校验的公开只读 client；\n- 频道与消息的 Astro 6/7 Live Loaders；\n- 统一、可判别且不会泄露响应正文的错误；\n- RSS 与媒体 URL 构造工具。\n\n它不会读取环境变量、自动请求后端、注册 collection 或安装部署 adapter。只要站点不导入并配置\nLive Collection，现有纯静态博客仍然照常构建。\n\n## 安装\n\n```bash\npnpm add @coszone/koharu-astro\n```\n\n需要 Astro `^6.0.0 || ^7.0.0`、Node.js `>=22.20.0`。Live Collection 在请求时运行，因此消费站点还需要自行配置\n支持 on-demand rendering 的 Astro adapter。\n\n## Typed client\n\n```ts\nimport { createKoharuClient } from '@coszone/koharu-astro/client';\n\nconst client = createKoharuClient({\n  baseUrl: 'https://suite.example.com',\n});\n\nconst channels = await client.channels.list();\nconst page = await client.messages.list({\n  channelId: channels.items[0].id,\n  limit: 20,\n});\n\nconst latest = await client.messages.latest({\n  // 可省略；重复 ID 会被去重，最多 32 个可见频道。\n  channelIds: channels.items.map((channel) => channel.id),\n  limit: 20,\n});\n\nconst context = await client.messages.context({\n  messageId: latest.items[0].id,\n});\n\nconst result = await client.search.messages({\n  query: 'Astro',\n  channelIds: channels.items.map((channel) => channel.id),\n});\n```\n\n`nextCursor` 是不透明字符串，必须原样传回 client，不能解析或修改。client 默认使用 5 秒超时与\n`cache: 'no-store'`；也可以为每次调用传入 `AbortSignal`。\n\n媒体 URL 可能是相对 suite origin 的路径，应使用：\n\n```ts\nclient.resolveUrl(page.items[0].media[0]?.thumbnailUrl);\nclient.urls.globalRss();\nclient.urls.channelRss(channels.items[0].id);\n```\n\n`messages.context()` 返回完整当前消息，以及不含媒体的轻量 `newer` / `older` 引用，适合详情页导航。\n`messages.latest()` 和 `search.messages()` 的 `channelIds` 会以服务端过滤执行，避免先取一页再在客户端过滤而漏项。\n搜索原有的单个 `channelId` 参数保持兼容，但不能与 `channelIds` 同时传入。空 `channelIds` 与省略参数都表示不限制频道。\n\n## Astro 6/7 Live Collections\n\n```ts\n// src/live.config.ts\nimport { defineLiveCollection } from 'astro:content';\nimport {\n  koharuChannelsLoader,\n  koharuMessagesLoader,\n  publicChannelSchema,\n  publicMessageSchema,\n} from '@coszone/koharu-astro';\n\nconst baseUrl = process.env.KOHARU_SUITE_URL;\nif (!baseUrl) throw new Error('KOHARU_SUITE_URL is required');\n\nexport const collections = {\n  koharuChannels: defineLiveCollection({\n    loader: koharuChannelsLoader({ baseUrl }),\n    schema: publicChannelSchema,\n  }),\n  koharuMessages: defineLiveCollection({\n    loader: koharuMessagesLoader({ baseUrl }),\n    schema: publicMessageSchema,\n  }),\n};\n```\n\n页面通过 `getLiveCollection()` 和 `getLiveEntry()` 在运行时读取数据。消息 loader 只加载一页；\nAstro 的 Live Collection result 无法携带 suite 的 `nextCursor`，需要分页或搜索时请直接调用 typed\nclient。\n\n安全 HTML 会映射到 entry 的 `rendered.html`，页面可以用 Astro 的 `set:html` 输出。loader 不把\nHTML 当作 Markdown/MDX 再执行，也不提供无法从公开 API 证明的 `lastModified`。\n\n```astro\n<Fragment set:html={entry.rendered?.html ?? ''} />\n```\n\n## 错误处理\n\n```ts\nimport { isKoharuError } from '@coszone/koharu-astro';\n\ntry {\n  await client.messages.get({ messageId: '...' });\n} catch (error) {\n  if (isKoharuError(error)) {\n    console.error(error.kind, error.status, error.code);\n  }\n}\n```\n\n`kind` 为 `aborted`、`timeout`、`network`、`http` 或 `invalid_response`。错误不会附带完整 response\nbody、用户内容或 URL credentials。\n\n完整英文说明见 [README.en.md](./README.en.md)。\n","readmeFilename":"README.md"}