Skip to content

feat(cloudinary): migrate sanity-plugin-cloudinary to the monorepo#970

Open
stipsan wants to merge 109 commits into
mainfrom
cursor/migrate-sanity-plugin-cloudinary-1e91
Open

feat(cloudinary): migrate sanity-plugin-cloudinary to the monorepo#970
stipsan wants to merge 109 commits into
mainfrom
cursor/migrate-sanity-plugin-cloudinary-1e91

Conversation

@stipsan

@stipsan stipsan commented Jun 12, 2026

Copy link
Copy Markdown
Member

Migrate sanity-plugin-cloudinary

Transfers sanity-plugin-cloudinary into the monorepo using the copy plugin generator (git subtree import preserving full history).

Demo

cloudinary_plugin_test_studio_demo.mp4

Test-studio walkthrough: the Cloudinary document type renders the custom asset input ("Select…" opens the Cloudinary config dialog), the array field exposes the "Add multiple" function, and "Cloudinary" appears as an asset source on image fields.

Cloudinary document form

Changes

  • Imported plugin source via git subtree with history, scaffolded monorepo config (package.json, package.config.ts, tsconfig.json, tsconfig.build.json, vitest.config.ts)
  • Dependencies: @sanity/studio-secrets now uses the in-repo workspace:* version (v4), @sanity/ui uses the catalog (v3), dropped @sanity/incompatible-plugin
  • Peer dependencies updated to monorepo baseline: React 19.2+, react-dom 19.2+, Sanity v5+, styled-components 6.1+, Node.js 20.19+
  • Modernized legacy code to pass monorepo lint rules: type-only imports, removed unused React default imports, replaced script.onload with addEventListener, replaced the props as ArrayOfObjectsInputProps cast with the isArrayOfObjectsInputProps type guard, fixed React Compiler memoization in CloudinaryInput, fixed positive tabIndex, migrated deprecated Stack space to gap, removed stale eslint directives
  • Added a targeted .oxlintrc.json override disabling no-unsafe-type-assertion for this plugin's legacy src/ (same pattern as sanity-naive-html-serializer)
  • Wired a test-studio example (dev/test-studio/src/cloudinary) exercising cloudinarySchemaPlugin (single cloudinary.asset field + array) and cloudinaryAssetSourcePlugin (image field asset source)
  • Added package exports test, major changeset, and root README plugins table entry

Transfer verification

  • Trusted publishing configured: npm trust github sanity-plugin-cloudinary --file=release.yml --repository=sanity-io/plugins
  • package.json dependencies/peerDependencies/exports verified against original repo
  • Test studio example wired and manually verified (pnpm dev)
  • pnpm format, pnpm knip, pnpm lint, pnpm build, pnpm test run all pass
  • Major changeset added with validated breaking changes

Maintainer follow-up

To show artifacts inline, enable in settings.

Open in Web Open in Cursor 

runeb and others added 30 commits March 17, 2021 21:14
…array. One action for adding mutiple assets at once, and one action to configure the setup
fix: create array if not already existing, before adding items. Fixes #1
bump sanity-secrets + sanipack versions
npx @sanity/plugin-kit@1.1.0-ecosystem-preset.7 inject --preset semver-workflow --preset renovatebot
@vercel

vercel Bot commented Jun 12, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
plugins-studio Ready Ready Preview, Comment Jun 17, 2026 3:55pm

Request Review

@changeset-bot

changeset-bot Bot commented Jun 12, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: ca02117

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
sanity-plugin-cloudinary Major

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@socket-security

socket-security Bot commented Jun 12, 2026

Copy link
Copy Markdown

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Addednpm/​nanoid@​4.0.2100998188100

View full report

…-plugin-cloudinary-1e91

# Conflicts:
#	pnpm-lock.yaml
…-plugin-cloudinary-1e91

# Conflicts:
#	dev/test-studio/sanity.config.ts
#	knip.jsonc
#	pnpm-lock.yaml
…-plugin-cloudinary-1e91

# Conflicts:
#	README.md
#	dev/test-studio/package.json
#	knip.jsonc
#	pnpm-lock.yaml
…-plugin-cloudinary-1e91

# Conflicts:
#	dev/test-studio/sanity.config.ts
#	knip.jsonc
@stipsan stipsan marked this pull request as ready for review June 16, 2026 12:51
@stipsan stipsan requested a review from a team as a code owner June 16, 2026 12:51
@stipsan stipsan requested review from Copilot and juice49 and removed request for a team June 16, 2026 12:51

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Ports sanity-plugin-cloudinary into the sanity-io/plugins monorepo, wiring it into the test studio and aligning build/lint/test setup with the monorepo toolchain.

Changes:

  • Adds the plugins/sanity-plugin-cloudinary workspace with monorepo config (pkg-utils build, TS/Vitest configs) and a package-exports test.
  • Integrates the plugin into the dev test-studio via a new cloudinary example workspace module and dependency wiring.
  • Updates repo-level configs (README plugin list, Knip workspace entry, oxlint override) and adds a major changeset for the migration.

Reviewed changes

Copilot reviewed 31 out of 32 changed files in this pull request and generated 12 comments.

Show a summary per file
File Description
README.md Adds the Cloudinary plugin to the monorepo “Current Plugins” list.
pnpm-lock.yaml Adds the new workspace and its resolved dependencies (including nanoid v4).
plugins/sanity-plugin-cloudinary/vitest.config.ts Adds per-plugin Vitest config to support vitest-package-exports.
plugins/sanity-plugin-cloudinary/tsconfig.json Adds typecheck TS config extending repo defaults.
plugins/sanity-plugin-cloudinary/tsconfig.build.json Adds build TS config for dist compilation.
plugins/sanity-plugin-cloudinary/src/utils.ts Adds Cloudinary widget loading + encoding helpers used by inputs/asset source.
plugins/sanity-plugin-cloudinary/src/types.ts Adds shared types + window.cloudinary global typing.
plugins/sanity-plugin-cloudinary/src/schema/cloudinaryAssetDerived.ts Adds schema type for derived transformations.
plugins/sanity-plugin-cloudinary/src/schema/cloudinaryAssetContextCustom.ts Adds schema type for Cloudinary context custom fields.
plugins/sanity-plugin-cloudinary/src/schema/cloudinaryAssetContext.ts Adds schema type for Cloudinary asset context wrapper.
plugins/sanity-plugin-cloudinary/src/schema/cloudinaryAsset.ts Adds the main cloudinary.asset schema with custom components.
plugins/sanity-plugin-cloudinary/src/index.ts Exposes plugins/schemas and registers schema + asset-source plugins.
plugins/sanity-plugin-cloudinary/src/index.test.ts Adds package exports manifest snapshot test.
plugins/sanity-plugin-cloudinary/src/components/WidgetInput.tsx Adds the object input UI for selecting/removing Cloudinary assets and opening config.
plugins/sanity-plugin-cloudinary/src/components/VideoPlayer.tsx Adds a simple video preview player for Cloudinary video assets.
plugins/sanity-plugin-cloudinary/src/components/SecretsConfigView.tsx Adds studio-secrets-based configuration UI for Cloudinary credentials.
plugins/sanity-plugin-cloudinary/src/components/CloudinaryInput.tsx Adds the custom input that maps Cloudinary selections to Sanity object value patches.
plugins/sanity-plugin-cloudinary/src/components/AssetPreview.tsx Adds previews for image/pdf/raw/video assets within the custom input.
plugins/sanity-plugin-cloudinary/src/components/AssetListFunctions.tsx Adds array functions to “Add multiple” assets + open configuration from arrays.
plugins/sanity-plugin-cloudinary/src/components/AssetDiff.tsx Adds diff preview support (incl. video) for Cloudinary assets.
plugins/sanity-plugin-cloudinary/src/components/asset-source/Icon.tsx Adds the Cloudinary icon SVG used for the asset source.
plugins/sanity-plugin-cloudinary/src/components/asset-source/CloudinaryAssetSource.tsx Adds the asset source dialog that embeds the Cloudinary Media Library.
plugins/sanity-plugin-cloudinary/README.md Adds plugin documentation (usage/config/examples).
plugins/sanity-plugin-cloudinary/package.json Adds plugin package metadata, deps/peerDeps, exports, and build scripts.
plugins/sanity-plugin-cloudinary/package.config.ts Enables React Compiler + styled-components support for pkg-utils build.
plugins/sanity-plugin-cloudinary/CHANGELOG.md Brings over historical changelog from the standalone repo.
knip.jsonc Registers the new workspace for Knip analysis and ignores a babel-only dependency.
dev/test-studio/src/cloudinary/index.tsx Adds a test-studio example schema and plugin wiring to exercise the integration.
dev/test-studio/sanity.config.ts Registers the new Cloudinary example workspace plugin in the test studio.
dev/test-studio/package.json Adds the Cloudinary plugin workspace dependency to the test studio.
.oxlintrc.json Adds a per-plugin oxlint override for legacy unsafe assertions in this plugin.
.changeset/cloudinary-monorepo-transfer.md Adds a major changeset describing the breaking changes from the monorepo migration.
Files not reviewed (1)
  • pnpm-lock.yaml: Generated file

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +58 to +60
export const cloudinaryAssetSourcePlugin = definePlugin({
name: 'cloudinart-asset-source',
form: {
Comment on lines +77 to +92
function loadJS(url: string, callback: () => void) {
const existingScript = document.getElementById('damWidget')
if (!existingScript) {
const script = document.createElement('script')
script.src = url
script.id = 'damWidget'
document.body.appendChild(script)
script.addEventListener('load', () => {
callback()
})
}
if (existingScript && callback) {
return callback()
}
return true
}
Comment on lines +19 to +21
const [loadingMessage, setLoadingMessage] = useState<string | undefined>(
'Loading Cloudinary Media Libary',
)
const {secrets} = useSecrets<Secrets>(namespace)
const cloudName = secrets?.cloudName
const apiKey = secrets?.apiKey
const [widgetId] = useState(() => `cloundinaryWidget-${Date.now()}`)

useEffect(() => {
// because we have to access props after loading js in a callback,
// we cannot pass props as dependecnies as that will cause infinite updates
Comment on lines +47 to +50
import {defineConfg} from 'sanity'
import {cloudinaryImageSource} from 'sanity-plugin-cloudinary'

export default defineConfg({
Comment on lines +74 to +77
import {defineConfg} from 'sanity'
import {cloudinarySchemaPlugin} from 'sanity-plugin-cloudinary'

export default defineConfg({
Comment on lines +60 to +64
// only use clooudinary as an asset source
return [cloudinaryImageSource]
}
// dont add cloudnary as an asset sources
return previousAssetSources
Comment on lines +222 to +235
## Develop & test

This plugin uses [@sanity/plugin-kit](https://github.com/sanity-io/plugin-kit)
with default configuration for build & watch scripts.

See [Testing a plugin in Sanity Studio](https://github.com/sanity-io/plugin-kit#testing-a-plugin-in-sanity-studio)
on how to run this plugin with hotreload in the studio.

### Release new version

Run ["CI & Release" workflow](https://github.com/sanity-io/sanity-plugin-cloudinary/actions/workflows/main.yml).
Make sure to select the main branch and check "Release new version".

Semantic release will only release on configured branches, so it is safe to run release on any branch.
{
"name": "sanity-plugin-cloudinary",
"version": "1.4.1",
"description": "Cloudinary integration for Sanity Studio V3.",
…-plugin-cloudinary-1e91

# Conflicts:
#	dev/test-studio/sanity.config.ts
#	knip.jsonc
…-plugin-cloudinary-1e91

# Conflicts:
#	dev/test-studio/sanity.config.ts
#	pnpm-lock.yaml
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.