{"_id":"@bozonx/social-posting","_rev":"5-f85b7fbf46cb72075cbf72578e5c3b47","name":"@bozonx/social-posting","dist-tags":{"latest":"0.8.0"},"versions":{"0.3.0":{"name":"@bozonx/social-posting","version":"0.3.0","keywords":["social-media","posting","publishing","automation","library"],"author":"Ivan K","license":"MIT","_id":"@bozonx/social-posting@0.3.0","maintainers":[{"name":"bozonx","email":"ipkozyrin@gmail.com"}],"homepage":"https://github.com/bozonx/social-media-posting/tree/main/packages/core#readme","bugs":{"url":"https://github.com/bozonx/social-media-posting/issues"},"dist":{"shasum":"57c7f332fbfeda0e76531416a8427fc190fbe145","tarball":"https://registry.npmjs.org/@bozonx/social-posting/-/social-posting-0.3.0.tgz","fileCount":123,"integrity":"sha512-nClmdg4clYOjIMRjoB7y7AuZQwk0tx0P0kBjbHrJJS0wYy4co4or/lyNgwoTmySbwiaYMdnTvag93exIKkbYVQ==","signatures":[{"sig":"MEUCICb5A7KzhuAxePk5PpTUGovgXTMBaYWeVSRDy1Lz+GP4AiEA9LyaotN8tTlqDL6CNAHq+OXyXgRiQxMV78e/RFxa1u4=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":344961},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=24.0.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","default":"./dist/index.js","workerd":"./dist/index.js"},"./platform":{"types":"./dist/platform.d.ts","import":"./dist/platform.js","default":"./dist/platform.js","workerd":"./dist/platform.js"}},"scripts":{"test":"pnpm -w exec vitest run --project core","build":"tsc -p tsconfig.build.json","clean":"rm -rf dist *.tsbuildinfo","typecheck":"tsc -p tsconfig.json --noEmit","test:workerd":"pnpm -w exec vitest run --config vitest.workerd.config.ts"},"_npmUser":{"name":"bozonx","email":"ipkozyrin@gmail.com"},"repository":{"url":"git+https://github.com/bozonx/social-media-posting.git","type":"git","directory":"packages/core"},"description":"Framework-free core for publishing posts to social networks","directories":{},"sideEffects":false,"_nodeVersion":"24.19.0","dependencies":{},"publishConfig":{"access":"public","provenance":true},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/social-posting_0.3.0_1787230928229_0.41821024560584874","host":"s3://npm-registry-packages-npm-production"}},"0.4.0":{"name":"@bozonx/social-posting","version":"0.4.0","keywords":["social-media","posting","publishing","automation","library"],"author":"Ivan K","license":"MIT","_id":"@bozonx/social-posting@0.4.0","maintainers":[{"name":"bozonx","email":"ipkozyrin@gmail.com"}],"homepage":"https://github.com/bozonx/social-media-posting/tree/main/packages/core#readme","bugs":{"url":"https://github.com/bozonx/social-media-posting/issues"},"dist":{"shasum":"ccedee9cb4b890d5bea53e85a11f2be5ec362786","tarball":"https://registry.npmjs.org/@bozonx/social-posting/-/social-posting-0.4.0.tgz","fileCount":123,"integrity":"sha512-cAf4uAmaoTA+RRLs86oGTm5wL+vPTSa/zZOVHoyHNPmhZEcZ7kFQQJA8Y/mD9Yna/+e/fJoWfkrjwA+h19Dpfw==","signatures":[{"sig":"MEQCIHyPauQzklvnBdvSoJ1rXDIekg3fo4ck72N69Lmk5bovAiAUqTzwJYIdPOHm6V/3hGUkDtcZuoyKp6di4Nb5QHnd7A==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":344961},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=24.0.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","default":"./dist/index.js","workerd":"./dist/index.js"},"./platform":{"types":"./dist/platform.d.ts","import":"./dist/platform.js","default":"./dist/platform.js","workerd":"./dist/platform.js"}},"scripts":{"test":"pnpm -w exec vitest run --project core","build":"tsc -p tsconfig.build.json","clean":"rm -rf dist *.tsbuildinfo","typecheck":"tsc -p tsconfig.json --noEmit","test:workerd":"pnpm -w exec vitest run --config vitest.workerd.config.ts"},"_npmUser":{"name":"bozonx","email":"ipkozyrin@gmail.com"},"repository":{"url":"git+https://github.com/bozonx/social-media-posting.git","type":"git","directory":"packages/core"},"description":"Framework-free core for publishing posts to social networks","directories":{},"sideEffects":false,"_nodeVersion":"24.19.0","dependencies":{},"publishConfig":{"access":"public","provenance":true},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/social-posting_0.4.0_1787264511175_0.8452903572350507","host":"s3://npm-registry-packages-npm-production"}},"0.5.1":{"name":"@bozonx/social-posting","version":"0.5.1","keywords":["social-media","posting","publishing","automation","library"],"author":"Ivan K","license":"MIT","_id":"@bozonx/social-posting@0.5.1","maintainers":[{"name":"bozonx","email":"ipkozyrin@gmail.com"}],"homepage":"https://github.com/bozonx/social-media-posting/tree/main/packages/core#readme","bugs":{"url":"https://github.com/bozonx/social-media-posting/issues"},"dist":{"shasum":"3b8b95cdc4d9d1d678d3ddc4fbe7872cc2e4bc8f","tarball":"https://registry.npmjs.org/@bozonx/social-posting/-/social-posting-0.5.1.tgz","fileCount":123,"integrity":"sha512-2PvFqQ7KKzaG/mY4GGyvAw7HVovpQhxLoSq7Nq1c8usm3MIXuKbX7UVswsNUxdcqg0zeOvJnFk19v7LCgK8Y5Q==","signatures":[{"sig":"MEUCIQDiEmfCQy92Ost0DAcTg7tp7cTpa09QR2cOTf412CsJiQIgSBMcCNNuaPZ7TNidv1+BEaC2oGngtwGjM8OZE2WjA6s=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":344961},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=24.0.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","default":"./dist/index.js","workerd":"./dist/index.js"},"./platform":{"types":"./dist/platform.d.ts","import":"./dist/platform.js","default":"./dist/platform.js","workerd":"./dist/platform.js"}},"scripts":{"test":"pnpm -w exec vitest run --project core","build":"tsc -p tsconfig.build.json","clean":"rm -rf dist *.tsbuildinfo","typecheck":"tsc -p tsconfig.json --noEmit","test:workerd":"pnpm -w exec vitest run --config vitest.workerd.config.ts"},"_npmUser":{"name":"bozonx","email":"ipkozyrin@gmail.com"},"repository":{"url":"git+https://github.com/bozonx/social-media-posting.git","type":"git","directory":"packages/core"},"description":"Framework-free core for publishing posts to social networks","directories":{},"sideEffects":false,"_nodeVersion":"24.19.0","dependencies":{},"publishConfig":{"access":"public","provenance":true},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/social-posting_0.5.1_1787267087419_0.09222359973989236","host":"s3://npm-registry-packages-npm-production"}},"0.7.0":{"name":"@bozonx/social-posting","version":"0.7.0","keywords":["social-media","posting","publishing","automation","library"],"author":"Ivan K","license":"MIT","_id":"@bozonx/social-posting@0.7.0","maintainers":[{"name":"bozonx","email":"ipkozyrin@gmail.com"}],"homepage":"https://github.com/bozonx/social-media-posting/tree/main/packages/core#readme","bugs":{"url":"https://github.com/bozonx/social-media-posting/issues"},"dist":{"shasum":"e8dbaf5d6019dc8bd7866d85d48dad9d990ef917","tarball":"https://registry.npmjs.org/@bozonx/social-posting/-/social-posting-0.7.0.tgz","fileCount":123,"integrity":"sha512-hTCtdWJML0LwvOLrqIcLvlB+/jVaQz+O3iU1pXtyxyjtTzQV1r6w3zBn1+daANX+ewYsXJaM44fy0eL27F0zAw==","signatures":[{"sig":"MEYCIQDRuqr1Zyg3fa2KmJjPSU0rgZt3BceyTlg6JyiF3cNwewIhAK8UO1AmSJiw87iQ366Gjbn3hjeWkLezpR6Shx/Zxj1R","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":348662},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=24.0.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","default":"./dist/index.js","workerd":"./dist/index.js"},"./platform":{"types":"./dist/platform.d.ts","import":"./dist/platform.js","default":"./dist/platform.js","workerd":"./dist/platform.js"}},"scripts":{"test":"pnpm -w exec vitest run --project core","build":"tsc -p tsconfig.build.json","clean":"rm -rf dist *.tsbuildinfo","typecheck":"tsc -p tsconfig.json --noEmit","test:workerd":"pnpm -w exec vitest run --config vitest.workerd.config.ts"},"_npmUser":{"name":"bozonx","email":"ipkozyrin@gmail.com"},"repository":{"url":"git+https://github.com/bozonx/social-media-posting.git","type":"git","directory":"packages/core"},"description":"Framework-free core for publishing posts to social networks","directories":{},"sideEffects":false,"_nodeVersion":"24.19.0","dependencies":{},"publishConfig":{"access":"public","provenance":true},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/social-posting_0.7.0_1788032535357_0.03280907766605545","host":"s3://npm-registry-packages-npm-production"}},"0.8.0":{"name":"@bozonx/social-posting","version":"0.8.0","description":"Framework-free core for publishing posts to social networks","keywords":["social-media","posting","publishing","automation","library"],"type":"module","main":"./dist/index.js","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","workerd":"./dist/index.js","import":"./dist/index.js","default":"./dist/index.js"},"./platform":{"types":"./dist/platform.d.ts","workerd":"./dist/platform.js","import":"./dist/platform.js","default":"./dist/platform.js"}},"dependencies":{},"author":"Ivan K","license":"MIT","engines":{"node":">=24.0.0"},"repository":{"type":"git","url":"git+https://github.com/bozonx/social-media-posting.git","directory":"packages/core"},"bugs":{"url":"https://github.com/bozonx/social-media-posting/issues"},"homepage":"https://github.com/bozonx/social-media-posting/tree/main/packages/core#readme","publishConfig":{"access":"public","provenance":true},"sideEffects":false,"scripts":{"build":"tsc -p tsconfig.build.json","clean":"rm -rf dist *.tsbuildinfo","typecheck":"tsc -p tsconfig.json --noEmit","test":"pnpm -w exec vitest run --project core","test:workerd":"pnpm -w exec vitest run --config vitest.workerd.config.ts"},"_nodeVersion":"24.19.0","_id":"@bozonx/social-posting@0.8.0","dist":{"integrity":"sha512-nTluXJdsQbmR2yRPcf4PZqLtqDFoJRRMC2EriMJiTnGniBKT/1dEqOqrJ2OwAqVp1XbIOwf0KLXArxZCq9zwOQ==","shasum":"9b106b1d11d795fc56e32a4d15584939fce152ea","tarball":"https://registry.npmjs.org/@bozonx/social-posting/-/social-posting-0.8.0.tgz","fileCount":132,"unpackedSize":482768,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIAjNHknf5a0n9JSfvcJQcSOgvABe/JpLFjcCfdgKUfD3AiEA2RVbNfMjpcpANDsJCIu1kVu15H/KSuxjxuTO3/CpLzg="}]},"_npmUser":{"name":"bozonx","email":"ipkozyrin@gmail.com"},"directories":{},"maintainers":[{"name":"bozonx","email":"ipkozyrin@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/social-posting_0.8.0_1788181087288_0.29144170268565106"},"_hasShrinkwrap":false}},"time":{"created":"2026-08-20T13:02:07.986Z","modified":"2026-08-31T12:58:07.665Z","0.3.0":"2026-08-20T13:02:08.366Z","0.4.0":"2026-08-20T22:21:51.332Z","0.5.1":"2026-08-20T23:04:47.570Z","0.7.0":"2026-08-29T19:42:15.507Z","0.8.0":"2026-08-31T12:58:07.465Z"},"bugs":{"url":"https://github.com/bozonx/social-media-posting/issues"},"author":"Ivan K","license":"MIT","homepage":"https://github.com/bozonx/social-media-posting/tree/main/packages/core#readme","keywords":["social-media","posting","publishing","automation","library"],"repository":{"type":"git","url":"git+https://github.com/bozonx/social-media-posting.git","directory":"packages/core"},"description":"Framework-free core for publishing posts to social networks","maintainers":[{"name":"bozonx","email":"ipkozyrin@gmail.com"}],"readme":"# @bozonx/social-posting\n\nThe framework-free core of a social posting library. Zero runtime dependencies; targets web\nstandards, so the same build runs on Node, Cloudflare Workers, Deno and Bun.\n\nIt ships no network of its own. Install the ones you need alongside it —\n[`@bozonx/social-posting-telegram`](https://www.npmjs.com/package/@bozonx/social-posting-telegram),\nor your own.\n\n```bash\npnpm add @bozonx/social-posting @bozonx/social-posting-telegram\n```\n\n## Creating a client\n\n```ts\nimport { createPostingClient } from '@bozonx/social-posting';\nimport { telegram } from '@bozonx/social-posting-telegram';\n\nconst client = createPostingClient({\n  accounts: {\n    myChannel: { platform: 'telegram', auth: { apiKey: '…' }, target: '@my_channel' },\n  },\n  requestTimeoutSecs: 60,\n  platforms: [telegram],\n  logger, // optional; nothing global is ever reconfigured\n  credentialProvider, // optional; see docs/OAUTH.md\n});\n```\n\n| Option               | Meaning                                                    |\n| -------------------- | ---------------------------------------------------------- |\n| `accounts`           | Named credentials and per-account defaults                 |\n| `requestTimeoutSecs` | Overall limit for one publish call (default 60)            |\n| `platforms`          | The `PlatformModule` descriptors to serve                  |\n| `logger`             | An `ILogger`; defaults to a console logger at `logLevel`   |\n| `logLevel`           | `debug` \\| `info` \\| `warn` \\| `error` (default `warn`)    |\n| `credentialProvider` | Where credentials come from and where rotated ones go back |\n| `fetch`              | Custom `fetch` function (for proxies or testing)           |\n\nThere is deliberately no retry setting. One call makes one attempt.\n\n## Client API\n\n```ts\nclient.post(request, { signal?, resume?, includeRaw? }); // publish once\nclient.delete(request, ref, { signal?, resume?, includeRaw? }); // delete a post\nclient.preview(request);                      // validate without publishing\nclient.checkStatus(request, handle, signal?); // follow up a 'processing' publication\nclient.resolveCapabilities(request, signal?); // account-specific limits; never cached here\nclient.getQuota(request, signal?);             // remaining allowance where supported\nclient.registerPlatform(platformModule);      // add a network at runtime\nclient.getRegisteredPlatforms();              // string[]\nclient.getCapabilities(platform);             // PlatformCapabilities\n```\n\n## The request\n\n```ts\ninterface PostRequest {\n  platform: string; // 'telegram'\n  account?: string; // a named account …\n  auth?: Record<string, unknown>; // … or inline credentials\n  target?: string | number | { id: string; [key: string]: unknown };\n\n  body?: string;\n  bodyFormat?: BodyFormat; // 'text' | 'html' | 'md' | 'MarkdownV2'\n  type?: PostType; // omit for auto-detection\n  title?: string;\n  description?: string;\n  article?: ArticleDocument;\n  thread?: PostSegment[];\n\n  media?: MediaInput[]; // array of MediaInput items\n  thumbnail?: ThumbnailInput; // dedicated preview asset\n\n  tags?: string[];\n  language?: string;\n  scheduledAt?: string; // rejected where the network cannot schedule\n  mode?: 'publish' | 'draft'; // rejected where the network has no drafts\n  silent?: boolean;\n  visibility?: Visibility; // 'public' | 'unlisted' | 'private' | 'direct'\n  inReplyTo?: PlatformObjectRef;\n  repostOf?: PlatformObjectRef;\n  poll?: PollInput;\n  location?: LocationInput;\n  extra?: Record<string, unknown>; // platform-specific extra payload\n}\n```\n\n`media[].source` is a discriminated union: `{ kind: 'url', url }`, `{ kind: 'bytes', bytes }`,\n`{ kind: 'blob', blob }`, `{ kind: 'stream', open, sizeBytes? }`, or\n`{ kind: 'platformRef', ref }`. A platform reference is native to that network (a Telegram\n`file_id`, for instance), not a generic URL.\n\nA field a network cannot honour is **rejected**, not silently dropped. A field it accepts and\nignores comes back as a preview warning naming it.\n\n## The result\n\n```ts\ntype PostResult =\n  | {\n      success: true;\n      data: {\n        status: 'published' | 'processing';\n        postId?: string;\n        url?: string;\n        parts?: PostPart[];\n        ref?: PostRef;\n        handle?: ResumeHandle;\n        checkAfterMs?: number;\n        platform: string;\n        type: PostType;\n        publishedAt: string;\n        raw?: Record<string, unknown>; // only when includeRaw is true\n        requestId: string;\n      };\n    }\n  | {\n      success: false;\n      error: {\n        code: ErrorCode;\n        message: string;\n        retryable: boolean;\n        retryAfterMs?: number;\n        httpStatus?: number;\n        platformCode?: string;\n        resumeHandle?: ResumeHandle;\n        issues?: Issue[];\n        details?: Record<string, unknown>;\n        raw?: unknown; // only when includeRaw is true\n        requestId: string;\n      };\n    };\n```\n\n`post()` and `delete()` never throw for an expected failure, so branching on `success` replaces a try/catch\naround every call.\n\nRaw platform payloads are diagnostic and may contain sensitive content. They are omitted by\ndefault; pass `includeRaw: true` only when the caller is allowed to receive them.\n\n## Retrying is yours\n\n```ts\nconst result = await client.post(request, { resume: job.resumeHandle });\n\nif (result.success) return markPublished(job, result.data);\nif (!result.error.retryable) return deadLetter(job, result.error);\n\njob.resumeHandle = result.error.resumeHandle; // persist before scheduling\nscheduleRetry(job, result.error.retryAfterMs ?? backoff(job.attempts));\n```\n\nThe one exception is transport-level: `httpRequest()` repeats a request once when the connection\ndied before the request completed and the body can be replayed. A request the platform may already\nhave seen is never repeated automatically.\n\n## Implementing a network\n\n```ts\nimport type { PlatformModule } from '@bozonx/social-posting';\nimport type { IPlatform } from '@bozonx/social-posting/platform';\n\nexport const mastodon: PlatformModule = {\n  name: 'mastodon',\n  capabilities: mastodonCapabilities, // types, limits, formats, transport traits\n  create: deps => new MastodonPlatform(deps),\n  authValidator: new MastodonAuthValidator(),\n};\n```\n\nThe core exports adapter utilities via `@bozonx/social-posting/platform`: `IPlatform`, `PlatformCapabilities`, `PlatformError`,\n`ResumeHandle`, `validateAgainstCapabilities()`, `previewFromCapabilities()`, `httpRequest()`,\n`MediaFetcher`, `runChunkedUpload()`, `OAuth2TokenRefresher`, and the body-rendering helpers.\n\nRun [`@bozonx/social-posting-conformance`](https://www.npmjs.com/package/@bozonx/social-posting-conformance)\nagainst it, and see `CONTRIBUTING-PLATFORMS.md`.\n\n## Runtime\n\n`fetch`, `Request`/`Response`, WHATWG streams, Web Crypto, `URL`. No Node built-ins — enforced by\nlint and by running the whole test suite inside `workerd`.\n\n## License\n\nMIT\n","readmeFilename":""}