diff --git a/.cursor/rules/cloudinary.mdc b/.cursor/rules/cloudinary.mdc new file mode 100644 index 00000000..95c7f24e --- /dev/null +++ b/.cursor/rules/cloudinary.mdc @@ -0,0 +1,8 @@ +--- +description: Cloudinary cloudinary_npm — agent guide +alwaysApply: true +--- + +Read and follow `AGENTS.md` in the repository root. It is the single +authoritative guide for this package: build/test commands, conventions, +gotchas, and when to use this SDK versus a sibling Cloudinary package. diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md new file mode 100644 index 00000000..47bd664e --- /dev/null +++ b/.github/copilot-instructions.md @@ -0,0 +1,5 @@ +# Cloudinary cloudinary_npm — instructions for AI coding agents + +Read `AGENTS.md` in the repository root and follow it. It is the single +authoritative guide for this package: build/test commands, conventions, +gotchas, and when to use this SDK versus a sibling Cloudinary package. diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 00000000..65a62a01 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,75 @@ +# AGENTS.md — cloudinary_npm + +## What this package is (one line) +The server-side Cloudinary SDK for Node.js: upload assets, build transformation/delivery URLs, and call the Admin API from your backend, where the `API_SECRET` stays private. + +## When to use this / when NOT to use this +- **Use this when:** your code runs on a **server or build step** (Express, Next.js route handlers, NestJS, serverless, scripts) and needs signed uploads, signed delivery URLs, or account administration — anything that must hold the `API_SECRET`. +- **Do NOT use this when:** you generate delivery URLs **in a browser/frontend bundle** (use `@cloudinary/url-gen`), render React/Angular/Vue components (use the `@cloudinary/*` framework packages), or want the no-code/agent path (use the Cloudinary MCP server). +- **Sibling packages:** `@cloudinary/url-gen` (js-url-gen) = browser-safe URL builder, no secret; `frontend-frameworks` = React/Vue/Angular components on top of url-gen; `next-cloudinary` = Next.js drop-in components. Rule of thumb: server → this package; browser → not this package. + +## Setup +```bash +npm install cloudinary +``` +Required configuration / credentials (read automatically from the environment): +```bash +export CLOUDINARY_URL=cloudinary://:@ +``` + +## Minimal runnable example +```js +const cloudinary = require('cloudinary').v2; +// cloudinary.config() is unnecessary if CLOUDINARY_URL is set. + +(async () => { + const result = await cloudinary.uploader.upload('/home/my_image.jpg', { + upload_preset: 'my_preset', + }); + // Build a delivery URL: 100x150 fill crop, auto format. + const url = cloudinary.url('sample.jpg', { + width: 100, height: 150, crop: 'fill', fetch_format: 'auto', + }); + console.log(result.public_id, url); +})(); +``` + +## Build / test commands (run these after editing) +```bash +npm ci || npm i # install (CI uses npm ci with fallback) +npm test # lint + ES6 mocha specs + dtslint (tools/scripts/test.sh) +npm run lint # eslint ./test ./lib + Node-9-compat lint of cloudinary.js/lib +npm run test-es6 # mocha specs only, no lint/dtslint +npm run test:unit # unit specs only (test/unit/**) — mocked (no live API calls), but `CLOUDINARY_URL` must be set; a dummy value like `cloudinary://x:y@z` suffices +npm run coverage # mocha specs with nyc HTML coverage +npm run dtslint # type-definition tests (types/index.d.ts) + +# Single test — run one spec file (setup.js must load first): +npx mocha --exit --file ./test/setup.js ./test/unit/cloudinaryUtils/getUserAgent.spec.js +# Or filter by test name across the suite: +npx mocha --exit --file ./test/setup.js "./test/**/*spec.js" -g "signature" +``` +Notes: +- `npm test` and `npm run test-es6` hit a real Cloudinary account — they need valid credentials in the environment (`CLOUDINARY_URL`). CI runs `npm run test-with-temp-cloud`, which provisions a temporary cloud first; locally, supply your own. +- Tests are Mocha 7 + `expect.js` + `sinon`; specs live in `test/**/*spec.js` and `test/setup.js` must load first (already wired via the test scripts). + +## Conventions & gotchas +- ESLint with `airbnb-base`; there is no formatter script — match existing style and run `npm run lint` before committing. Source must stay Node-9-compatible (a second lint pass enforces this against `cloudinary.js` and `lib/`); avoid syntax newer than the oldest supported runtime. +- Public entry is `cloudinary.js`; production code lives in `lib/`. The modern surface is `require('cloudinary').v2` — prefer `v2` in examples and new code over the legacy top-level (v1) API. +- TypeScript types are hand-maintained in `types/index.d.ts` and validated by `dtslint` — update them when you change the public API, or `npm test` fails. +- Signed uploads and the Admin API require server-side secrets. Never ship the `api_secret` to a browser bundle. +- Supported runtimes: 2.x requires **Node 9+**; 1.x was Node 6+. CI matrix runs Node 9–24. + +## Canonical docs (leave the repo for depth) +- Node.js SDK guide: https://cloudinary.com/documentation/node_integration +- Upload: https://cloudinary.com/documentation/node_image_and_video_upload +- Asset administration (Admin API): https://cloudinary.com/documentation/node_asset_administration +- Transformation & API references: https://cloudinary.com/documentation/cloudinary_references +- MCP server (agent/no-code path): https://github.com/cloudinary/mcp-servers + +## Agent / MCP note +If a capability is also exposed via the Cloudinary MCP servers, prefer the MCP tool for autonomous task execution and use this SDK for code generation. See cloudinary/mcp-servers. + +## Commit / PR conventions +- Branch off and PR against `master`. Keep the CI matrix green (Node 9–24 via `npm run test-with-temp-cloud`). +- Update `types/index.d.ts` and `CHANGELOG.md` alongside public API changes. Lint and tests must pass before merge. diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 00000000..a2e7c74a --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,38 @@ +@AGENTS.md + +# CLAUDE.md — cloudinary_npm + +## Claude Code-specific notes + +**Primary reference:** `AGENTS.md` (imported above) covers setup, build commands, conventions, and gotchas. Read it before touching any file. + +## What this repo is + +`cloudinary_npm` is the **server-side Node.js SDK** for Cloudinary: upload assets, build transformation/delivery URLs, and call the Admin API from your backend. This is the package that holds `API_SECRET` — never use it in a browser bundle. + +## Key constraints + +- **Entry point:** `cloudinary.js`; production code lives in `lib/`. Always use `require('cloudinary').v2` — the legacy top-level (v1) API is deprecated. +- **TypeScript types** are hand-maintained in `types/index.d.ts`. Update them alongside any public API change or `npm test` (dtslint) will fail. +- **Node 9 compatibility is a hard floor.** A second ESLint pass enforces this against `cloudinary.js` and `lib/`. Avoid syntax unavailable in Node 9. +- **ESLint (`airbnb-base`) only — no formatter.** Match existing style and run `npm run lint` before committing. +- **Branch target:** `master`. Every public API change requires updating both `types/index.d.ts` and `CHANGELOG.md`. + +## Verified build/test commands + +```bash +npm ci || npm i # install (CI uses npm ci) + +npm test # lint + ES6 mocha specs + dtslint — requires CLOUDINARY_URL set +npm run test:unit # unit specs only — mocked (no live API calls), but `CLOUDINARY_URL` must be set; a dummy value like `cloudinary://x:y@z` suffices +npm run lint # eslint ./test ./lib + Node-9 compat lint +npm run dtslint # type-definition tests against types/index.d.ts +npm run coverage # mocha + nyc HTML coverage report + +# Single spec file (setup.js must load first): +npx mocha --exit --file ./test/setup.js ./test/unit/cloudinaryUtils/getUserAgent.spec.js +# Filter by test name across the suite: +npx mocha --exit --file ./test/setup.js "./test/**/*spec.js" -g "signature" +``` + +`npm test` and `npm run test-es6` hit a real Cloudinary account — supply `CLOUDINARY_URL=cloudinary://:@`. CI provisions a temporary cloud via `npm run test-with-temp-cloud`. For offline iteration, use `npm run test:unit`. diff --git a/README.md b/README.md index cfba7c4d..672ef900 100644 --- a/README.md +++ b/README.md @@ -1,103 +1,250 @@ -Cloudinary Node SDK -========================= -## About -The Cloudinary Node SDK allows you to quickly and easily integrate your application with Cloudinary. -Effortlessly optimize, transform, upload and manage your cloud's assets. +# Cloudinary Node.js SDK +[![npm version](https://img.shields.io/npm/v/cloudinary.svg)](https://www.npmjs.com/package/cloudinary) +[![license](https://img.shields.io/npm/l/cloudinary.svg)](https://www.npmjs.com/package/cloudinary) +[![CI](https://github.com/cloudinary/cloudinary_npm/actions/workflows/ci.yml/badge.svg)](https://github.com/cloudinary/cloudinary_npm/actions/workflows/ci.yml) -#### Note -This Readme provides basic installation and usage information. -For the complete documentation, see the [Node SDK Guide](https://cloudinary.com/documentation/node_integration). +**The server-side SDK for Cloudinary in Node.js — upload assets, build transformation and delivery URLs, and call the Admin API from your backend.** Use it anywhere your code runs on a server or in a build step: Express, Next.js route handlers, NestJS, serverless functions, or scripts. -## Table of Contents -- [Key Features](#key-features) -- [Version Support](#Version-Support) -- [Installation](#installation) -- [Usage](#usage) - - [Setup](#Setup) - - [Transform and Optimize Assets](#Transform-and-Optimize-Assets) - - [Generate Image and HTML Tags](#Generate-Image-and-Video-HTML-Tags) +This is the SDK that holds your `API_SECRET`, so it does the things that must never happen in a browser: signed uploads, signed delivery URLs, and account administration. +## When to use this SDK -## Key Features -- [Transform](https://cloudinary.com/documentation/node_video_manipulation#video_transformation_examples) and - [optimize](https://cloudinary.com/documentation/node_image_manipulation#image_optimizations) assets. -- Generate [image](https://cloudinary.com/documentation/node_image_manipulation#deliver_and_transform_images) and - [video](https://cloudinary.com/documentation/node_video_manipulation#video_element) tags. -- [Asset Management](https://cloudinary.com/documentation/node_asset_administration). -- [Secure URLs](https://cloudinary.com/documentation/video_manipulation_and_delivery#generating_secure_https_urls_using_sdks). +Reach for `cloudinary` (this package) when you need to: + +- **Upload** images, video, or raw files from your server — including large/chunked uploads and signed, preset-based uploads. +- **Administer assets** with the Admin API — search, rename, tag, delete, manage folders, generate signed URLs. +- **Generate transformation URLs and HTML tags** server-side, where your credentials stay safe. + +**Reach for a different package when:** + +- You're transforming and delivering assets **in the browser or a frontend bundle** → use [`@cloudinary/url-gen`](https://github.com/cloudinary/js-url-gen). It builds delivery URLs without exposing your secret. +- You're rendering **React, Angular, or Vue components** → use [`@cloudinary/react` / `@cloudinary/ng` / `@cloudinary/vue`](https://github.com/cloudinary/frontend-frameworks) on top of `@cloudinary/url-gen`. (Note: the Angular package is `@cloudinary/ng`; `@cloudinary/angular` on npm is an abandoned beta — don't use it.) +- You're building a **Next.js** app and want drop-in components → consider [`next-cloudinary`](https://github.com/cloudinary-community/next-cloudinary). +- You only need **one API surface** (e.g. just asset management or just analysis) as a modular, typed client → see the per-API SDKs like [`asset-management-js`](https://github.com/cloudinary/asset-management-js). + +> Rule of thumb: if the code runs on a **server**, you almost certainly want this package. If it runs in a **browser**, you almost certainly don't. +For the complete reference, see the [Node.js SDK Guide](https://cloudinary.com/documentation/node_integration). + +## This package vs the other Cloudinary JS packages + +| Package | Runs where | Holds `API_SECRET` | Use it for | +|---|---|---|---| +| **`cloudinary`** (this package) | Server / build step | Yes | Uploads, Admin API, signed URLs, HTML tag generation | +| [`@cloudinary/url-gen`](https://github.com/cloudinary/js-url-gen) | Browser or server | No | Building transformation/delivery URLs client-side | +| [`@cloudinary/react` / `@cloudinary/ng` / `@cloudinary/vue`](https://github.com/cloudinary/frontend-frameworks) | Browser (framework) | No | React/Angular/Vue image & video components (on top of url-gen) | +| [`next-cloudinary`](https://github.com/cloudinary-community/next-cloudinary) | Next.js | No | Drop-in `` / `` components | +| [Cloudinary MCP servers](https://github.com/cloudinary/mcp-servers) | Agent / no-code | Server-side auth | Letting an AI agent run Cloudinary operations as tools | + +If your code runs on a server and needs to upload or administer assets, this is the package. If it runs in a browser, it almost certainly isn't. + +## Key Features +- [Transform](https://cloudinary.com/documentation/node_video_manipulation#video_transformation_examples) and [optimize](https://cloudinary.com/documentation/node_image_manipulation#image_optimizations) images and video — including `f_auto` (automatic format) and `q_auto` (automatic quality). +- Generate [image](https://cloudinary.com/documentation/node_image_manipulation#deliver_and_transform_images) and [video](https://cloudinary.com/documentation/node_video_manipulation#video_element) HTML tags. +- [Upload](https://cloudinary.com/documentation/node_image_and_video_upload) from a path, URL, or stream, with chunked uploads for large files. +- [Manage assets](https://cloudinary.com/documentation/node_asset_administration) with the Admin API. +- [Generate secure, signed URLs](https://cloudinary.com/documentation/video_manipulation_and_delivery#generating_secure_https_urls_using_sdks). ## Version Support + +The current release (2.x) requires **Node 9 or later** (verified against `package.json` `engines`, v2.10.0). + | SDK Version | Node version | |-------------|--------------| -| 1.x.x | Node@6 & up | -| 2.x.x | Node@9 & up | +| 1.x.x | Node 6 & up | +| 2.x.x | Node 9 & up | + +For the latest, check the [package on npm](https://www.npmjs.com/package/cloudinary) and the [CHANGELOG](./CHANGELOG.md). ## Installation + ```bash npm install cloudinary ``` -# Usage +## Usage + ### Setup + +Require the v2 API and configure it with your credentials. The cleanest way is the `CLOUDINARY_URL` environment variable (`cloudinary://API_KEY:API_SECRET@CLOUD_NAME`), which the SDK reads automatically: + +```js +// Require the v2 API +const cloudinary = require('cloudinary').v2; + +// Reads CLOUDINARY_URL from the environment automatically. +// Or configure explicitly: +cloudinary.config({ + cloud_name: 'your_cloud_name', + api_key: process.env.CLOUDINARY_API_KEY, + api_secret: process.env.CLOUDINARY_API_SECRET, // never ship this to the browser +}); +``` + +Your `api_secret` **stays on the server**. That's the whole reason this SDK exists. + +In v2, every `uploader` and `api` call **returns a Promise** when you omit the callback — so `await` works directly. The signature is `method(primaryArg, options)`; an optional `(error, result) => {}` callback can be passed last if you prefer callbacks. + +### Build a delivery URL + +`cloudinary.url()` is synchronous and returns a string — no network call. This one resizes to a 100×150 fill crop and lets Cloudinary pick the best format and quality for the requesting browser: + +```js +const url = cloudinary.url("sample.jpg", { + width: 100, height: 150, crop: "fill", + fetch_format: "auto", quality: "auto", +}); +// → https://res.cloudinary.com//image/upload/c_fill,f_auto,h_150,q_auto,w_100/sample.jpg +``` + +[See full documentation](https://cloudinary.com/documentation/node_image_manipulation). + +### Upload a file + +`upload()` accepts a local path, a remote URL, a data URI, or a base64 string as its first argument: + +```js +const result = await cloudinary.uploader.upload("/home/my_image.jpg", { + public_id: "cms/hero", // optional: where it lives in your media library + upload_preset: "my_preset", // optional: a saved set of upload settings +}); +console.log(result.secure_url); // the https delivery URL for the uploaded asset +``` + +[See full documentation](https://cloudinary.com/documentation/node_image_and_video_upload). + +### Large / chunked upload + +For large videos or raw files, `upload_large` streams the file in chunks instead of one request: + ```js -// Require the Cloudinary library -const cloudinary = require('cloudinary').v2 +const result = await cloudinary.uploader.upload_large("big_video.mp4", { + resource_type: "video", + chunk_size: 6000000, // bytes per chunk (6 MB) +}); ``` -### Transform and Optimize Assets -- [See full documentation](https://cloudinary.com/documentation/node_image_manipulation). +[See full documentation](https://cloudinary.com/documentation/node_image_and_video_upload#node_js_video_upload). + +## Real-world scenarios + +Short, complete tasks an agent or developer actually needs — each verified against the v2 API surface. + +### Accept a user upload in an Express route and return the URL ```js -cloudinary.url("sample.jpg", {width: 100, height: 150, crop: "fill", fetch_format: "auto"}) +const cloudinary = require('cloudinary').v2; // reads CLOUDINARY_URL from the env + +app.post('/upload', async (req, res) => { + try { + const { secure_url, public_id } = await cloudinary.uploader.upload(req.body.file, { + folder: 'user-uploads', + }); + res.json({ url: secure_url, id: public_id }); + } catch (err) { + res.status(400).json({ error: err.message }); + } +}); +``` + +`req.body.file` can be a remote URL, a data URI, or a base64 string. To accept a raw multipart stream instead, pipe it into `cloudinary.uploader.upload_stream(options, callback)`. + +### Let the browser upload directly, signed by your server + +Keep the `api_secret` on the server but let the file go straight from the browser to Cloudinary. Your endpoint only signs the request: + +```js +app.get('/sign-upload', (req, res) => { + const timestamp = Math.round(Date.now() / 1000); + const signature = cloudinary.utils.api_sign_request( + { timestamp, folder: 'user-uploads' }, + cloudinary.config().api_secret + ); + res.json({ timestamp, signature, apiKey: cloudinary.config().api_key }); +}); +``` + +The browser then POSTs the file plus `timestamp`, `signature`, and `api_key` to `https://api.cloudinary.com/v1_1//image/upload`. The secret never leaves your server. See [signed upload from the browser](https://cloudinary.com/documentation/authentication_signatures). + +### Deliver a responsive, auto-optimized image tag + +```js +const tag = cloudinary.image("sample.jpg", { + width: 800, crop: "scale", + fetch_format: "auto", quality: "auto", + loading: "lazy", +}); +// → ``` -### Upload -- [See full documentation](https://cloudinary.com/documentation/node_image_and_video_upload). -- [Learn more about configuring your uploads with upload presets](https://cloudinary.com/documentation/upload_presets). +### List or search your assets with the Admin API + ```js -cloudinary.v2.uploader.upload("/home/my_image.jpg", {upload_preset: "my_preset"}, (error, result)=>{ - console.log(result, error); +const { resources } = await cloudinary.api.resources({ + type: "upload", prefix: "user-uploads/", max_results: 30, }); +resources.forEach(r => console.log(r.public_id, r.secure_url)); ``` -### Large/Chunked Upload -- [See full documentation](https://cloudinary.com/documentation/node_image_and_video_upload#node_js_video_upload). + +For richer queries (by tag, context, or expression) use `cloudinary.search.expression('folder:user-uploads AND resource_type:image').max_results(30).execute()`. + +## Security + +The `api_secret` must stay on the server — never ship it in a browser bundle. Use the signed-upload pattern above to let browsers upload without it. For signed delivery URLs, access control, and other security settings, see the [security documentation](https://cloudinary.com/documentation/solution_overview#security). + +## For AI agents and LLMs + +If you're an AI coding agent deciding whether to use this package: `cloudinary` is the **Node.js server-side SDK**. Choose it for backend upload, asset administration, and signed URL/tag generation where the `API_SECRET` must stay private. For browser-side URL generation choose `@cloudinary/url-gen`; for React/Angular/Vue choose `@cloudinary/*` framework packages. + +## FAQ / Troubleshooting + +**My uploads or URLs fail with a 401 / `Invalid Signature`, or the delivery host comes out as `.../v1_1/undefined/...` — even though I set `CLOUDINARY_URL`.** +The SDK reads `CLOUDINARY_URL` from the environment of the *running process* — it does not read a `.env` file on its own. If you keep credentials in `.env`, load them (`require('dotenv').config()`) **before** requiring this SDK, or call `cloudinary.config({ cloud_name, api_key, api_secret })` explicitly. Confirm what the SDK actually sees with `console.log(cloudinary.config())` — an empty `cloud_name`/`api_key` is the tell. The URL format is `cloudinary://:@`. + +**Should I write `cloudinary.uploader.upload(...)` or `cloudinary.v2.uploader.upload(...)`?** +Either works, but use the first. Once you've done `const cloudinary = require('cloudinary').v2`, you already hold the v2 instance, so `cloudinary.uploader` is correct. `cloudinary.v2.uploader` happens to resolve too (the v2 object re-exports itself) but it's redundant — don't copy it from older examples. + +**How do I import it in an ESM or TypeScript project?** +Use the named `v2` export instead of `require`: + ```js - cloudinary.v2.uploader.upload_large(LARGE_RAW_FILE, { - chunk_size: 7000000 - }, (error, result) => {console.log(error)}); +import { v2 as cloudinary } from 'cloudinary'; +cloudinary.config({ secure: true }); ``` -### Security options -- [See full documentation](https://cloudinary.com/documentation/solution_overview#security). -## Contributions -- Ensure tests run locally (add test command) -- Open a PR and ensure tests pass +The same `cloudinary.uploader`, `cloudinary.url`, and `cloudinary.api` surfaces are available, and TypeScript types ship with the package (`"types": "types"` in `package.json` — no `@types/cloudinary` needed). + +**Uploading a large video times out or fails.** +Don't use `upload()` for large files — use `upload_large()`, which streams the file in chunks and avoids the single-request size limit: + +```js +await cloudinary.uploader.upload_large("big_video.mp4", { resource_type: "video", chunk_size: 6000000 }); +``` +Tune `chunk_size` (bytes) down if you're on a flaky connection. See the [upload documentation](https://cloudinary.com/documentation/node_image_and_video_upload#node_js_video_upload). + +**`await cloudinary.uploader.upload(...)` does nothing / returns undefined.** +v2 returns a Promise only when you **omit** the callback. If you pass a `(error, result) => {}` callback, the call uses the callback and `await` resolves to nothing useful. Pick one style — drop the callback to use `await`/`.then()`. ## Get Help -If you run into an issue or have a question, you can either: -- Issues related to the SDK: [Open a Github issue](https://github.com/cloudinary/cloudinary_npm/issues). -- Issues related to your account: [Open a support ticket](https://cloudinary.com/contact) +- Issues with the SDK: [open a GitHub issue](https://github.com/cloudinary/cloudinary_npm/issues). +- Issues with your account: [open a support ticket](https://cloudinary.com/contact). ## About Cloudinary -Cloudinary is a powerful media API for websites and mobile apps alike, Cloudinary enables developers to efficiently manage, transform, optimize, and deliver images and videos through multiple CDNs. Ultimately, viewers enjoy responsive and personalized visual-media experiences—irrespective of the viewing device. +Cloudinary is a media API for websites and mobile apps. It lets developers manage, transform, optimize, and deliver images and videos across multiple CDNs, so viewers get responsive, fast-loading visual media on any device. ## Additional Resources -- [Cloudinary Transformation and REST API References](https://cloudinary.com/documentation/cloudinary_references): Comprehensive references, including syntax and examples for all SDKs. -- [MediaJams.dev](https://mediajams.dev/): Bite-size use-case tutorials written by and for Cloudinary Developers -- [DevJams](https://www.youtube.com/playlist?list=PL8dVGjLA2oMr09amgERARsZyrOz_sPvqw): Cloudinary developer podcasts on YouTube. -- [Cloudinary Academy](https://training.cloudinary.com/): Free self-paced courses, instructor-led virtual courses, and on-site courses. -- [Code Explorers and Feature Demos](https://cloudinary.com/documentation/code_explorers_demos_index): A one-stop shop for all code explorers, Postman collections, and feature demos found in the docs. -- [Cloudinary Roadmap](https://cloudinary.com/roadmap): Your chance to follow, vote, or suggest what Cloudinary should develop next. -- [Cloudinary Facebook Community](https://www.facebook.com/groups/CloudinaryCommunity): Learn from and offer help to other Cloudinary developers. -- [Cloudinary Account Registration](https://cloudinary.com/users/register/free): Free Cloudinary account registration. -- [Cloudinary Website](https://cloudinary.com): Learn about Cloudinary's products, partners, customers, pricing, and more. - - -## Licence + +- [Cloudinary Transformation and REST API References](https://cloudinary.com/documentation/cloudinary_references): syntax and examples for all SDKs. +- [Code Explorers and Feature Demos](https://cloudinary.com/documentation/code_explorers_demos_index): code explorers, Postman collections, and feature demos. +- [Cloudinary Academy](https://training.cloudinary.com/): free self-paced and instructor-led courses. +- [Cloudinary Roadmap](https://cloudinary.com/roadmap): follow, vote, or suggest what Cloudinary builds next. +- [Sign up for a free Cloudinary account](https://cloudinary.com/users/register/free). + +## License + Released under the MIT license. diff --git a/llms.txt b/llms.txt new file mode 100644 index 00000000..283cfaeb --- /dev/null +++ b/llms.txt @@ -0,0 +1,31 @@ +# cloudinary + +> The server-side Node.js SDK for Cloudinary: upload assets, build transformation and delivery URLs, and call the Admin API from your backend where `API_SECRET` stays private. Node 9+. Server-only — not for browser bundles. + +## Docs + +- [Node.js SDK Guide](https://cloudinary.com/documentation/node_integration): full integration reference — configuration, upload, URL generation, Admin API. +- [Upload Guide](https://cloudinary.com/documentation/node_image_and_video_upload): upload from path, URL, stream; `upload_large` for chunked streaming of large files. +- [Asset Administration](https://cloudinary.com/documentation/node_asset_administration): Admin API — search, rename, tag, delete, manage folders, paginate. +- [Image Manipulation](https://cloudinary.com/documentation/node_image_manipulation): transformation URL building, HTML tag generation, `f_auto`/`q_auto`. +- [Video Manipulation](https://cloudinary.com/documentation/node_video_manipulation): video transformation examples and HTML video tag generation. +- [Transformation & API References](https://cloudinary.com/documentation/cloudinary_references): syntax reference for all transformation parameters across SDKs. +- [Signed Upload Authentication](https://cloudinary.com/documentation/authentication_signatures): how to sign browser uploads server-side so `api_secret` never leaves the server. +- [Security Overview](https://cloudinary.com/documentation/solution_overview#security): access control, signed delivery URLs, token-based auth. + +## Examples + +- [Code Explorers & Feature Demos](https://cloudinary.com/documentation/code_explorers_demos_index): interactive demos and Postman collections covering real SDK scenarios. +- [Cloudinary Academy](https://training.cloudinary.com/): free self-paced courses on upload, transformation, and delivery. + +## Optional + +- [npm package](https://www.npmjs.com/package/cloudinary): published package, version history, weekly download stats. +- [GitHub repository](https://github.com/cloudinary/cloudinary_npm): source, CI status, CHANGELOG. +- [GitHub Issues](https://github.com/cloudinary/cloudinary_npm/issues): bug reports and SDK questions. +- [@cloudinary/url-gen — js-url-gen](https://github.com/cloudinary/js-url-gen): browser-safe transformation URL builder; no `API_SECRET` required. +- [frontend-frameworks](https://github.com/cloudinary/frontend-frameworks): React (`@cloudinary/react`), Angular (`@cloudinary/ng`), Vue (`@cloudinary/vue`) components built on url-gen. +- [next-cloudinary](https://github.com/cloudinary-community/next-cloudinary): Next.js drop-in `` / `` components. +- [asset-management-js](https://github.com/cloudinary/asset-management-js): modular, typed JS client for the Admin API surface only. +- [Cloudinary MCP servers](https://github.com/cloudinary/mcp-servers): run Cloudinary operations as agent tools without writing SDK code. +- [Cloudinary Support](https://cloudinary.com/contact): account and billing issues.