{"id":47183393,"url":"https://github.com/letsroti/sourceembed","last_synced_at":"2026-04-01T17:48:24.959Z","repository":{"id":344042547,"uuid":"1179831623","full_name":"letsroti/sourceembed","owner":"letsroti","description":"Store raw text or JSON in Cloudflare R2 and instantly get a public URL","archived":false,"fork":false,"pushed_at":"2026-03-13T09:13:41.000Z","size":153,"stargazers_count":2,"open_issues_count":0,"forks_count":1,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-03-13T15:49:21.805Z","etag":null,"topics":["cloudflare-r2","json-hosting","public-url-storage","raw-text-storage","s3-compatible"],"latest_commit_sha":null,"homepage":"https://letsroti.com","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/letsroti.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null},"funding":{"github":["letsroti"]}},"created_at":"2026-03-12T12:31:04.000Z","updated_at":"2026-03-13T09:13:44.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/letsroti/sourceembed","commit_stats":null,"previous_names":["letsroti/sourceembed"],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/letsroti/sourceembed","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/letsroti%2Fsourceembed","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/letsroti%2Fsourceembed/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/letsroti%2Fsourceembed/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/letsroti%2Fsourceembed/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/letsroti","download_url":"https://codeload.github.com/letsroti/sourceembed/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/letsroti%2Fsourceembed/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30579568,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-16T09:53:36.164Z","status":"ssl_error","status_checked_at":"2026-03-16T09:53:29.590Z","response_time":96,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cloudflare-r2","json-hosting","public-url-storage","raw-text-storage","s3-compatible"],"created_at":"2026-03-13T08:09:42.932Z","updated_at":"2026-03-17T12:01:30.571Z","avatar_url":"https://github.com/letsroti.png","language":"TypeScript","funding_links":["https://github.com/sponsors/letsroti"],"categories":[],"sub_categories":[],"readme":"# @letsroti/sourceembed\n\nA small utility for storing raw text (typically embed JSON) in\n**Cloudflare R2** and returning a **public URL**.\n\nUseful for hosting embed payloads, temporary JSON data, or shareable\nconfiguration files without building custom storage logic.\n\nThe library uploads text to an R2 bucket using the S3-compatible API,\ngenerates a UUID-based filename, and returns a public URL using your\nconfigured domain.\n\n## Installation\n\nInstall the package using your preferred Node.js package manager.\n\n``` bash\nnpm install @letsroti/sourceembed\n```\n\nor\n\n``` bash\nyarn add @letsroti/sourceembed\n```\n\nor\n\n``` bash\npnpm add @letsroti/sourceembed\n```\n\n## Requirements\n\nThis package only needs two things.\n\n### Cloudflare R2 Credentials\n\nValid **Cloudflare R2 API credentials** with permission to upload\nobjects to your bucket.\n\nRequired values:\n\n-   Access Key ID\n-   Secret Access Key\n-   R2 S3-compatible endpoint URL\n\nExample endpoint format:\n\n    https://\u003caccount-id\u003e.r2.cloudflarestorage.com\n\nThese credentials are used by the AWS S3 client to upload files to your\nR2 bucket.\n\n### Public Domain\n\nYou must also have a **public domain that serves files from your R2\nbucket**.\n\nExample:\n\n    raw.example.com\n\nUploaded files will be returned as URLs in this format:\n\n    https://raw.example.com/\u003cuuid\u003e.json\n\n## Usage\n\n### Import and Initialize\n\n``` ts\nimport { SourceEmbed } from '@letsroti/sourceembed';\n\nconst sourceEmbed = new SourceEmbed({\n  accessKeyId: process.env.R2_ACCESS_KEY_ID!,\n  secretAccessKey: process.env.R2_ACCESS_KEY_SECRET!,\n  endpoint: process.env.R2_ENDPOINT_URL!,\n  bucket: process.env.R2_BUCKET!,\n  publicDomain: process.env.R2_PUBLIC_DOMAIN!,\n});\n```\n\n## Store a Single File\n\nUploads raw text to the configured R2 bucket and returns the generated\nkey and public URL.\n\n``` ts\nconst embedData = {\n  title: \"Example\",\n  description: \"Hello world\"\n};\n\nconst result = await sourceEmbed.store(\n  JSON.stringify(embedData, null, 2)\n);\n\nconsole.log(result);\n```\n\nExample result:\n\n``` ts\n{\n  key: \"550e8400-e29b-41d4-a716-446655440000.json\",\n  url: \"https://raw.example.com/550e8400-e29b-41d4-a716-446655440000.json\"\n}\n```\n\n## Store with Custom Extension\n\nThe file extension can be changed. Default extension is `json`.\n\n``` ts\nawait sourceEmbed.store(\"Hello world\", \"txt\");\n```\n\nExample URL:\n\n    https://raw.example.com/\u003cuuid\u003e.txt\n\n## Store Multiple Files\n\nUploads multiple texts in parallel.\n\n``` ts\nconst contents = [\n  JSON.stringify({ message: \"one\" }),\n  JSON.stringify({ message: \"two\" }),\n  JSON.stringify({ message: \"three\" })\n];\n\nconst results = await sourceEmbed.storeMany(contents);\n```\n\nExample result:\n\n``` ts\n[\n  { status: \"fulfilled\", value: { key: \"...\", url: \"...\" } },\n  { status: \"fulfilled\", value: { key: \"...\", url: \"...\" } },\n  { status: \"rejected\", reason: Error }\n]\n```\n\n## Example Environment Variables\n\nStore your Cloudflare R2 credentials as environment variables.\n\nExample `.env` file:\n\n```env\nR2_ACCESS_KEY_ID=your_access_key_id\nR2_ACCESS_KEY_SECRET=your_secret_access_key\nR2_ENDPOINT_URL=https://your-account-id.r2.cloudflarestorage.com\nR2_BUCKET=your_bucket_name\nR2_PUBLIC_DOMAIN=raw.example.com\n```\n\n## License\n\nMIT License","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fletsroti%2Fsourceembed","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fletsroti%2Fsourceembed","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fletsroti%2Fsourceembed/lists"}