diff --git a/.github/workflows/readme-list-update.yml b/.github/workflows/readme-list-update.yml new file mode 100644 index 00000000..215ec9c3 --- /dev/null +++ b/.github/workflows/readme-list-update.yml @@ -0,0 +1,62 @@ +name: Update Examples List in README + +on: + pull_request: + branches: + - main + paths: + - "examples/**" + - "techs.json" + +jobs: + update-readme: + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + fetch-depth: 0 + ref: ${{ github.head_ref }} + + - name: Set up Bun + uses: oven-sh/setup-bun@v2 + with: + bun-version: latest + + - name: Update README + id: update-readme + run: | + if ! bun run scripts/update-readme.ts; then + echo "README update failed. See details below:" + cat error.log + exit 1 + fi + + - name: Commit changes + if: success() + run: | + git config --local user.email "action@github.com" + git config --local user.name "GitHub Action" + git add README.md + git commit -m "Update README.md with new examples and technologies" || echo "No changes to commit" + + - name: Push changes + if: success() + run: git push origin ${{ github.head_ref }} + + - name: Comment on Pull Request if README Update Fails + if: failure() + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + tech_error=$(cat error.log) + response=$(curl -s -o /dev/null -w "%{http_code}" -H "Authorization: token $GITHUB_TOKEN" \ + -X POST \ + -d '{"body": "🚨 **README Update Failed**\n\nThe following tech stack(s) were found in examples but do not have entries in `techs.json`. Please add each missing tech in `techs.json` with the following format:\n\n```json\n\"tech-id\": \"Tech Display Name\"\n```\n\nFor example:\n\n```json\n\"nextjs\": \"Next.js\"\n```\n\nMissing Tech(s):\n\n```\n'"$tech_error"'\n```"}' \ + "https://api.github.com/repos/${{ github.repository }}/issues/${{ github.event.pull_request.number }}/comments") + + if [ "$response" -eq 201 ]; then + echo "Comment posted successfully." + else + echo "Failed to post comment. HTTP status: $response" + fi diff --git a/README.md b/README.md index 6ee9a574..d757df5f 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,7 @@ Learn how to easily integrate [Cloudinary](https://cloudinary.com/) into your projects with real examples. + - [.NET](#net) - [Android](#android) - [JavaScript](#javascript) @@ -47,16 +48,16 @@ Learn how to easily integrate [Cloudinary](https://cloudinary.com/) into your pr ### Android -- [Image SDK](https://github.com/cloudinary-community/cloudinary-examples/tree/main/examples/angular-imagesdk) - [ImageView](https://github.com/cloudinary-community/cloudinary-examples/tree/main/examples/android-imageview) -- [Video Player](https://github.com/cloudinary-community/cloudinary-examples/tree/main/examples/angular-video-player) ### JavaScript - [Image Upload with Fetch](https://github.com/cloudinary-community/cloudinary-examples/tree/main/examples/javascript-image-upload-fetch) ### Angular +- [Image SDK](https://github.com/cloudinary-community/cloudinary-examples/tree/main/examples/angular-imagesdk) - [Cloudinary Upload Widget with an Upload Preset (Unsigned)](https://github.com/cloudinary-community/cloudinary-examples/tree/main/examples/angular-upload-widget) +- [Video Player](https://github.com/cloudinary-community/cloudinary-examples/tree/main/examples/angular-video-player) ### Astro @@ -225,7 +226,7 @@ Learn how to easily integrate [Cloudinary](https://cloudinary.com/) into your pr - [Countdown Timer](https://github.com/cloudinary-community/cloudinary-examples/tree/main/examples/vercel-countdown-timer) - [Custom Function Remote](https://github.com/cloudinary-community/cloudinary-examples/tree/main/examples/vercel-custom-function-remote) - + ## 🧐 Not seeing an example? diff --git a/examples/android-imageview/config.json b/examples/android-imageview/config.json new file mode 100644 index 00000000..32cc58b4 --- /dev/null +++ b/examples/android-imageview/config.json @@ -0,0 +1,4 @@ +{ + "name": "ImageView", + "tech": "android" +} \ No newline at end of file diff --git a/examples/angular-imagesdk/config.json b/examples/angular-imagesdk/config.json new file mode 100644 index 00000000..a86d3c29 --- /dev/null +++ b/examples/angular-imagesdk/config.json @@ -0,0 +1,4 @@ +{ + "name": "Image SDK", + "tech": "angular" +} \ No newline at end of file diff --git a/examples/angular-upload-widget/config.json b/examples/angular-upload-widget/config.json new file mode 100644 index 00000000..7c050da6 --- /dev/null +++ b/examples/angular-upload-widget/config.json @@ -0,0 +1,4 @@ +{ + "name": "Cloudinary Upload Widget with an Upload Preset (Unsigned)", + "tech": "angular" +} \ No newline at end of file diff --git a/examples/angular-video-player/config.json b/examples/angular-video-player/config.json new file mode 100644 index 00000000..071fe659 --- /dev/null +++ b/examples/angular-video-player/config.json @@ -0,0 +1,4 @@ +{ + "name": "Video Player", + "tech": "angular" +} \ No newline at end of file diff --git a/examples/astro-cloudinary/config.json b/examples/astro-cloudinary/config.json new file mode 100644 index 00000000..22bc1697 --- /dev/null +++ b/examples/astro-cloudinary/config.json @@ -0,0 +1,4 @@ +{ + "name": "Astro Cloudinary SDK", + "tech": "astro" +} \ No newline at end of file diff --git a/examples/astro-form-upload/config.json b/examples/astro-form-upload/config.json new file mode 100644 index 00000000..787c55ac --- /dev/null +++ b/examples/astro-form-upload/config.json @@ -0,0 +1,4 @@ +{ + "name": "Uploading with Forms", + "tech": "astro" +} \ No newline at end of file diff --git a/examples/astro-image/config.json b/examples/astro-image/config.json new file mode 100644 index 00000000..50716f02 --- /dev/null +++ b/examples/astro-image/config.json @@ -0,0 +1,4 @@ +{ + "name": "Using Astro Image", + "tech": "astro" +} \ No newline at end of file diff --git a/examples/astro-product-gallery/config.json b/examples/astro-product-gallery/config.json new file mode 100644 index 00000000..9f70e4c4 --- /dev/null +++ b/examples/astro-product-gallery/config.json @@ -0,0 +1,4 @@ +{ + "name": "Cloudinary Product Gallery", + "tech": "astro" +} \ No newline at end of file diff --git a/examples/astro-upload-widget-preset/config.json b/examples/astro-upload-widget-preset/config.json new file mode 100644 index 00000000..0b3c00af --- /dev/null +++ b/examples/astro-upload-widget-preset/config.json @@ -0,0 +1,4 @@ +{ + "name": "Cloudinary Upload Widget with an Upload Preset (Unsigned)", + "tech": "astro" +} \ No newline at end of file diff --git a/examples/dart-image-upload/config.json b/examples/dart-image-upload/config.json new file mode 100644 index 00000000..b107b2c0 --- /dev/null +++ b/examples/dart-image-upload/config.json @@ -0,0 +1,4 @@ +{ + "name": "Uploading Images", + "tech": "dart" +} \ No newline at end of file diff --git a/examples/dart-transformation-effects/config.json b/examples/dart-transformation-effects/config.json new file mode 100644 index 00000000..d5d847fc --- /dev/null +++ b/examples/dart-transformation-effects/config.json @@ -0,0 +1,4 @@ +{ + "name": "Transformations & Effects", + "tech": "dart" +} \ No newline at end of file diff --git a/examples/dotnet-image-upload/config.json b/examples/dotnet-image-upload/config.json new file mode 100644 index 00000000..328e9997 --- /dev/null +++ b/examples/dotnet-image-upload/config.json @@ -0,0 +1,4 @@ +{ + "name": "Uploading Images", + "tech": "net" +} \ No newline at end of file diff --git a/examples/dotnet-video-upload/config.json b/examples/dotnet-video-upload/config.json new file mode 100644 index 00000000..a3281e70 --- /dev/null +++ b/examples/dotnet-video-upload/config.json @@ -0,0 +1,4 @@ +{ + "name": "Uploading Videos", + "tech": "net" +} \ No newline at end of file diff --git a/examples/flutter-cldimagewidget/config.json b/examples/flutter-cldimagewidget/config.json new file mode 100644 index 00000000..8576d8ea --- /dev/null +++ b/examples/flutter-cldimagewidget/config.json @@ -0,0 +1,4 @@ +{ + "name": "CldImageWidget", + "tech": "flutter" +} \ No newline at end of file diff --git a/examples/flutter-transformation-effects/config.json b/examples/flutter-transformation-effects/config.json new file mode 100644 index 00000000..049a0580 --- /dev/null +++ b/examples/flutter-transformation-effects/config.json @@ -0,0 +1,4 @@ +{ + "name": "Transformations & Effects", + "tech": "flutter" +} \ No newline at end of file diff --git a/examples/go-credentials/config.json b/examples/go-credentials/config.json new file mode 100644 index 00000000..f47d2433 --- /dev/null +++ b/examples/go-credentials/config.json @@ -0,0 +1,4 @@ +{ + "name": "Credentials", + "tech": "go" +} \ No newline at end of file diff --git a/examples/go-image-upload/config.json b/examples/go-image-upload/config.json new file mode 100644 index 00000000..48795ffb --- /dev/null +++ b/examples/go-image-upload/config.json @@ -0,0 +1,4 @@ +{ + "name": "Uploading Images", + "tech": "go" +} \ No newline at end of file diff --git a/examples/go-transformation-effects/config.json b/examples/go-transformation-effects/config.json new file mode 100644 index 00000000..1c53ae4f --- /dev/null +++ b/examples/go-transformation-effects/config.json @@ -0,0 +1,4 @@ +{ + "name": "Transformations & Effects", + "tech": "go" +} \ No newline at end of file diff --git a/examples/html-client-hints/config.json b/examples/html-client-hints/config.json new file mode 100644 index 00000000..3eb63ab7 --- /dev/null +++ b/examples/html-client-hints/config.json @@ -0,0 +1,4 @@ +{ + "name": "Client Hints", + "tech": "html&browser" +} \ No newline at end of file diff --git a/examples/ios-uiimageview/config.json b/examples/ios-uiimageview/config.json new file mode 100644 index 00000000..f0c02a6c --- /dev/null +++ b/examples/ios-uiimageview/config.json @@ -0,0 +1,4 @@ +{ + "name": "CLDUIImageView", + "tech": "ios" +} \ No newline at end of file diff --git a/examples/java-image-upload/config.json b/examples/java-image-upload/config.json new file mode 100644 index 00000000..44789988 --- /dev/null +++ b/examples/java-image-upload/config.json @@ -0,0 +1,4 @@ +{ + "name": "Uploading Images", + "tech": "java" +} \ No newline at end of file diff --git a/examples/javascript-image-upload-fetch/config.json b/examples/javascript-image-upload-fetch/config.json new file mode 100644 index 00000000..4f7940fd --- /dev/null +++ b/examples/javascript-image-upload-fetch/config.json @@ -0,0 +1,4 @@ +{ + "name": "Image Upload with Fetch", + "tech": "javascript" +} \ No newline at end of file diff --git a/examples/kotlin-imageview/config.json b/examples/kotlin-imageview/config.json new file mode 100644 index 00000000..355b9af6 --- /dev/null +++ b/examples/kotlin-imageview/config.json @@ -0,0 +1,4 @@ +{ + "name": "ImageView", + "tech": "kotlin" +} \ No newline at end of file diff --git a/examples/laravel-image-upload/config.json b/examples/laravel-image-upload/config.json new file mode 100644 index 00000000..f7760347 --- /dev/null +++ b/examples/laravel-image-upload/config.json @@ -0,0 +1,4 @@ +{ + "name": "Uploading Images", + "tech": "laravel" +} \ No newline at end of file diff --git a/examples/netlify-custom-function-remote/config.json b/examples/netlify-custom-function-remote/config.json new file mode 100644 index 00000000..f55a8a86 --- /dev/null +++ b/examples/netlify-custom-function-remote/config.json @@ -0,0 +1,4 @@ +{ + "name": "Netlify Function - Cloudinary Custom Remote Function", + "tech": "netlify" +} \ No newline at end of file diff --git a/examples/netlify-function-webhook-endpoint/config.json b/examples/netlify-function-webhook-endpoint/config.json new file mode 100644 index 00000000..81c0bbf4 --- /dev/null +++ b/examples/netlify-function-webhook-endpoint/config.json @@ -0,0 +1,4 @@ +{ + "name": "Netlify Function - Cloudinary Webhook Endpoint", + "tech": "netlify" +} \ No newline at end of file diff --git a/examples/netlify-graph-authentication-function/config.json b/examples/netlify-graph-authentication-function/config.json new file mode 100644 index 00000000..a66d5894 --- /dev/null +++ b/examples/netlify-graph-authentication-function/config.json @@ -0,0 +1,4 @@ +{ + "name": "Netlify Graph Authentication - Cloudinary Auth in Netlify Function", + "tech": "netlify" +} \ No newline at end of file diff --git a/examples/nextjs-app-shoppable-video/config.json b/examples/nextjs-app-shoppable-video/config.json new file mode 100644 index 00000000..2f438d89 --- /dev/null +++ b/examples/nextjs-app-shoppable-video/config.json @@ -0,0 +1,4 @@ +{ + "name": "App Shoppable Video", + "tech": "nextjs" +} \ No newline at end of file diff --git a/examples/nextjs-cldimage/config.json b/examples/nextjs-cldimage/config.json new file mode 100644 index 00000000..1bb2ef47 --- /dev/null +++ b/examples/nextjs-cldimage/config.json @@ -0,0 +1,4 @@ +{ + "name": "Next Cloudinary - CldImage", + "tech": "nextjs" +} \ No newline at end of file diff --git a/examples/nextjs-cldogimage/config.json b/examples/nextjs-cldogimage/config.json new file mode 100644 index 00000000..0bf9d60e --- /dev/null +++ b/examples/nextjs-cldogimage/config.json @@ -0,0 +1,4 @@ +{ + "name": "Next Cloudinary - CldOgImage", + "tech": "nextjs" +} \ No newline at end of file diff --git a/examples/nextjs-clduploadbutton/config.json b/examples/nextjs-clduploadbutton/config.json new file mode 100644 index 00000000..4d0c715c --- /dev/null +++ b/examples/nextjs-clduploadbutton/config.json @@ -0,0 +1,4 @@ +{ + "name": "Next Cloudinary - CldUploadButton", + "tech": "nextjs" +} \ No newline at end of file diff --git a/examples/nextjs-clduploadwidget-captions/config.json b/examples/nextjs-clduploadwidget-captions/config.json new file mode 100644 index 00000000..0c539df7 --- /dev/null +++ b/examples/nextjs-clduploadwidget-captions/config.json @@ -0,0 +1,4 @@ +{ + "name": "Upload Widget with Captions", + "tech": "nextjs" +} \ No newline at end of file diff --git a/examples/nextjs-clduploadwidget-signed/config.json b/examples/nextjs-clduploadwidget-signed/config.json new file mode 100644 index 00000000..4b26f4ce --- /dev/null +++ b/examples/nextjs-clduploadwidget-signed/config.json @@ -0,0 +1,4 @@ +{ + "name": "Next Cloudinary - CldUploadWidget - Signed Uploads", + "tech": "nextjs" +} \ No newline at end of file diff --git a/examples/nextjs-clduploadwidget/config.json b/examples/nextjs-clduploadwidget/config.json new file mode 100644 index 00000000..d26191ed --- /dev/null +++ b/examples/nextjs-clduploadwidget/config.json @@ -0,0 +1,4 @@ +{ + "name": "Next Cloudinary - CldUploadWidget", + "tech": "nextjs" +} \ No newline at end of file diff --git a/examples/nextjs-cldvideoplayer-abr/config.json b/examples/nextjs-cldvideoplayer-abr/config.json new file mode 100644 index 00000000..26672d8b --- /dev/null +++ b/examples/nextjs-cldvideoplayer-abr/config.json @@ -0,0 +1,4 @@ +{ + "name": "Next Cloudinary - CldVideoPlayer - Streaming & ABR", + "tech": "nextjs" +} \ No newline at end of file diff --git a/examples/nextjs-cldvideoplayer/config.json b/examples/nextjs-cldvideoplayer/config.json new file mode 100644 index 00000000..c89c0ae8 --- /dev/null +++ b/examples/nextjs-cldvideoplayer/config.json @@ -0,0 +1,4 @@ +{ + "name": "Next Cloudinary - CldVideoPlayer", + "tech": "nextjs" +} \ No newline at end of file diff --git a/examples/nextjs-holiday-card/config.json b/examples/nextjs-holiday-card/config.json new file mode 100644 index 00000000..d7621e25 --- /dev/null +++ b/examples/nextjs-holiday-card/config.json @@ -0,0 +1,4 @@ +{ + "name": "Holiday Card", + "tech": "nextjs" +} \ No newline at end of file diff --git a/examples/nextjs-next-image-domain/config.json b/examples/nextjs-next-image-domain/config.json new file mode 100644 index 00000000..59bcbdb7 --- /dev/null +++ b/examples/nextjs-next-image-domain/config.json @@ -0,0 +1,4 @@ +{ + "name": "Next Image - Cloudinary URLs", + "tech": "nextjs" +} \ No newline at end of file diff --git a/examples/nextjs-next-image-loader/config.json b/examples/nextjs-next-image-loader/config.json new file mode 100644 index 00000000..6db42495 --- /dev/null +++ b/examples/nextjs-next-image-loader/config.json @@ -0,0 +1,4 @@ +{ + "name": "Next Image - Cloudinary Loader", + "tech": "nextjs" +} \ No newline at end of file diff --git a/examples/nextjs-route-handlers-upload/config.json b/examples/nextjs-route-handlers-upload/config.json new file mode 100644 index 00000000..2fa3201e --- /dev/null +++ b/examples/nextjs-route-handlers-upload/config.json @@ -0,0 +1,4 @@ +{ + "name": "Upload Files with Route Handlers", + "tech": "nextjs" +} \ No newline at end of file diff --git a/examples/nextjs-server-actions-upload/config.json b/examples/nextjs-server-actions-upload/config.json new file mode 100644 index 00000000..22c7c834 --- /dev/null +++ b/examples/nextjs-server-actions-upload/config.json @@ -0,0 +1,4 @@ +{ + "name": "Upload Files with Server Actions", + "tech": "nextjs" +} \ No newline at end of file diff --git a/examples/nextjs-social-media-card/config.json b/examples/nextjs-social-media-card/config.json new file mode 100644 index 00000000..49b0186d --- /dev/null +++ b/examples/nextjs-social-media-card/config.json @@ -0,0 +1,4 @@ +{ + "name": "Social Media Cards", + "tech": "nextjs" +} \ No newline at end of file diff --git a/examples/nextjs-upload-formdata/config.json b/examples/nextjs-upload-formdata/config.json new file mode 100644 index 00000000..d340c924 --- /dev/null +++ b/examples/nextjs-upload-formdata/config.json @@ -0,0 +1,4 @@ +{ + "name": "Upload Files with FormData in API Routes", + "tech": "nextjs" +} \ No newline at end of file diff --git a/examples/nextjs-upload-widget-preset/config.json b/examples/nextjs-upload-widget-preset/config.json new file mode 100644 index 00000000..c5ef5eff --- /dev/null +++ b/examples/nextjs-upload-widget-preset/config.json @@ -0,0 +1,4 @@ +{ + "name": "Cloudinary Upload Widget with an Upload Preset (Unsigned)", + "tech": "nextjs" +} \ No newline at end of file diff --git a/examples/nextjs-upload-widget-signed/config.json b/examples/nextjs-upload-widget-signed/config.json new file mode 100644 index 00000000..9b3030c9 --- /dev/null +++ b/examples/nextjs-upload-widget-signed/config.json @@ -0,0 +1,4 @@ +{ + "name": "Cloudinary Upload Widget with Signed Uploads", + "tech": "nextjs" +} \ No newline at end of file diff --git a/examples/node-image-upload/config.json b/examples/node-image-upload/config.json new file mode 100644 index 00000000..18bd89b8 --- /dev/null +++ b/examples/node-image-upload/config.json @@ -0,0 +1,4 @@ +{ + "name": "Uploading Images", + "tech": "nodejs" +} \ No newline at end of file diff --git a/examples/node-personalized-email-images/config.json b/examples/node-personalized-email-images/config.json new file mode 100644 index 00000000..1587c691 --- /dev/null +++ b/examples/node-personalized-email-images/config.json @@ -0,0 +1,4 @@ +{ + "name": "Personalized Email Images", + "tech": "nodejs" +} \ No newline at end of file diff --git a/examples/node-social-media-card/config.json b/examples/node-social-media-card/config.json new file mode 100644 index 00000000..2d814981 --- /dev/null +++ b/examples/node-social-media-card/config.json @@ -0,0 +1,4 @@ +{ + "name": "Social Media Card", + "tech": "nodejs" +} \ No newline at end of file diff --git a/examples/node-transformations-effects/config.json b/examples/node-transformations-effects/config.json new file mode 100644 index 00000000..e48b374d --- /dev/null +++ b/examples/node-transformations-effects/config.json @@ -0,0 +1,4 @@ +{ + "name": "Transformations & Effects", + "tech": "nodejs" +} \ No newline at end of file diff --git a/examples/node-upload-eval/config.json b/examples/node-upload-eval/config.json new file mode 100644 index 00000000..7e49750a --- /dev/null +++ b/examples/node-upload-eval/config.json @@ -0,0 +1,4 @@ +{ + "name": "Eval on Upload", + "tech": "nodejs" +} \ No newline at end of file diff --git a/examples/node-video-upload/config.json b/examples/node-video-upload/config.json new file mode 100644 index 00000000..c9474d87 --- /dev/null +++ b/examples/node-video-upload/config.json @@ -0,0 +1,4 @@ +{ + "name": "Uploading Videos", + "tech": "nodejs" +} \ No newline at end of file diff --git a/examples/nuxt-cldimage/config.json b/examples/nuxt-cldimage/config.json new file mode 100644 index 00000000..121fb3ab --- /dev/null +++ b/examples/nuxt-cldimage/config.json @@ -0,0 +1,4 @@ +{ + "name": "Nuxt Cloudinary - CldImage", + "tech": "nuxt" +} \ No newline at end of file diff --git a/examples/nuxt-cldogimage/config.json b/examples/nuxt-cldogimage/config.json new file mode 100644 index 00000000..49bdb86b --- /dev/null +++ b/examples/nuxt-cldogimage/config.json @@ -0,0 +1,4 @@ +{ + "name": "Nuxt Cloudinary - CldOgImage", + "tech": "nuxt" +} \ No newline at end of file diff --git a/examples/nuxt-clduploadbutton/config.json b/examples/nuxt-clduploadbutton/config.json new file mode 100644 index 00000000..f70f0623 --- /dev/null +++ b/examples/nuxt-clduploadbutton/config.json @@ -0,0 +1,4 @@ +{ + "name": "Nuxt Cloudinary - CldUploadButton", + "tech": "nuxt" +} \ No newline at end of file diff --git a/examples/nuxt-clduploadwidget/config.json b/examples/nuxt-clduploadwidget/config.json new file mode 100644 index 00000000..0078e2a2 --- /dev/null +++ b/examples/nuxt-clduploadwidget/config.json @@ -0,0 +1,4 @@ +{ + "name": "Nuxt Cloudinary - CldUploadWidget", + "tech": "nuxt" +} \ No newline at end of file diff --git a/examples/nuxt-cldvideoplayer/config.json b/examples/nuxt-cldvideoplayer/config.json new file mode 100644 index 00000000..21d9f622 --- /dev/null +++ b/examples/nuxt-cldvideoplayer/config.json @@ -0,0 +1,4 @@ +{ + "name": "Nuxt Cloudinary - CldVideoPlayer", + "tech": "nuxt" +} \ No newline at end of file diff --git a/examples/nuxt-nuxt-image-provider/config.json b/examples/nuxt-nuxt-image-provider/config.json new file mode 100644 index 00000000..401fcb2f --- /dev/null +++ b/examples/nuxt-nuxt-image-provider/config.json @@ -0,0 +1,4 @@ +{ + "name": "Nuxt Image - Cloudinary Image Provider", + "tech": "nuxt" +} \ No newline at end of file diff --git a/examples/nuxt-upload-widget-preset/config.json b/examples/nuxt-upload-widget-preset/config.json new file mode 100644 index 00000000..ea81fd1f --- /dev/null +++ b/examples/nuxt-upload-widget-preset/config.json @@ -0,0 +1,4 @@ +{ + "name": "Cloudinary Upload Widget with an Upload Preset (Unsigned)", + "tech": "nuxt" +} \ No newline at end of file diff --git a/examples/php-image-upload/config.json b/examples/php-image-upload/config.json new file mode 100644 index 00000000..e3232538 --- /dev/null +++ b/examples/php-image-upload/config.json @@ -0,0 +1,4 @@ +{ + "name": "Uploading Images", + "tech": "php" +} \ No newline at end of file diff --git a/examples/php-transformations-effects/config.json b/examples/php-transformations-effects/config.json new file mode 100644 index 00000000..9e5355c1 --- /dev/null +++ b/examples/php-transformations-effects/config.json @@ -0,0 +1,4 @@ +{ + "name": "Transformations & Effects", + "tech": "php" +} \ No newline at end of file diff --git a/examples/python-image-overlay/config.json b/examples/python-image-overlay/config.json new file mode 100644 index 00000000..74398e1d --- /dev/null +++ b/examples/python-image-overlay/config.json @@ -0,0 +1,4 @@ +{ + "name": "Image Overlays", + "tech": "python" +} \ No newline at end of file diff --git a/examples/python-image-upload/config.json b/examples/python-image-upload/config.json new file mode 100644 index 00000000..081ec471 --- /dev/null +++ b/examples/python-image-upload/config.json @@ -0,0 +1,4 @@ +{ + "name": "Uploading Images", + "tech": "python" +} \ No newline at end of file diff --git a/examples/python-transformations-effects/config.json b/examples/python-transformations-effects/config.json new file mode 100644 index 00000000..3691ee23 --- /dev/null +++ b/examples/python-transformations-effects/config.json @@ -0,0 +1,4 @@ +{ + "name": "Transformations & Effects", + "tech": "python" +} \ No newline at end of file diff --git a/examples/react-advanced-image/config.json b/examples/react-advanced-image/config.json new file mode 100644 index 00000000..1f3ecee7 --- /dev/null +++ b/examples/react-advanced-image/config.json @@ -0,0 +1,4 @@ +{ + "name": "Cloudinary AdvancedImage", + "tech": "react" +} \ No newline at end of file diff --git a/examples/react-advanced-video/config.json b/examples/react-advanced-video/config.json new file mode 100644 index 00000000..30afbc5f --- /dev/null +++ b/examples/react-advanced-video/config.json @@ -0,0 +1,4 @@ +{ + "name": "Cloudinary AdvancedVideo", + "tech": "react" +} \ No newline at end of file diff --git a/examples/react-background-removal/config.json b/examples/react-background-removal/config.json new file mode 100644 index 00000000..5dbf14c8 --- /dev/null +++ b/examples/react-background-removal/config.json @@ -0,0 +1,4 @@ +{ + "name": "Removing Backgrounds", + "tech": "react" +} \ No newline at end of file diff --git a/examples/react-custom-fonts/config.json b/examples/react-custom-fonts/config.json new file mode 100644 index 00000000..a77387a7 --- /dev/null +++ b/examples/react-custom-fonts/config.json @@ -0,0 +1,4 @@ +{ + "name": "Custom Fonts", + "tech": "react" +} \ No newline at end of file diff --git a/examples/react-dark-mode/config.json b/examples/react-dark-mode/config.json new file mode 100644 index 00000000..203591c5 --- /dev/null +++ b/examples/react-dark-mode/config.json @@ -0,0 +1,4 @@ +{ + "name": "Dark Mode & Light Mode Images", + "tech": "react" +} \ No newline at end of file diff --git a/examples/react-drag-drop-upload/config.json b/examples/react-drag-drop-upload/config.json new file mode 100644 index 00000000..c8e46d54 --- /dev/null +++ b/examples/react-drag-drop-upload/config.json @@ -0,0 +1,4 @@ +{ + "name": "Drag & Drop Upload", + "tech": "react" +} \ No newline at end of file diff --git a/examples/react-image-collage/config.json b/examples/react-image-collage/config.json new file mode 100644 index 00000000..378ddd08 --- /dev/null +++ b/examples/react-image-collage/config.json @@ -0,0 +1,4 @@ +{ + "name": "Image Collage", + "tech": "react" +} \ No newline at end of file diff --git a/examples/react-product-gallery/config.json b/examples/react-product-gallery/config.json new file mode 100644 index 00000000..8dfbd38e --- /dev/null +++ b/examples/react-product-gallery/config.json @@ -0,0 +1,4 @@ +{ + "name": "Cloudinary Product Gallery", + "tech": "react" +} \ No newline at end of file diff --git a/examples/react-transformations-effects/config.json b/examples/react-transformations-effects/config.json new file mode 100644 index 00000000..4f30092b --- /dev/null +++ b/examples/react-transformations-effects/config.json @@ -0,0 +1,4 @@ +{ + "name": "Transformations & Effects", + "tech": "react" +} \ No newline at end of file diff --git a/examples/react-ts-media-library/config.json b/examples/react-ts-media-library/config.json new file mode 100644 index 00000000..f8e397b5 --- /dev/null +++ b/examples/react-ts-media-library/config.json @@ -0,0 +1,4 @@ +{ + "name": "Cloudinary Media Library", + "tech": "react" +} \ No newline at end of file diff --git a/examples/react-upload-widget-preset-ts/config.json b/examples/react-upload-widget-preset-ts/config.json new file mode 100644 index 00000000..f791113c --- /dev/null +++ b/examples/react-upload-widget-preset-ts/config.json @@ -0,0 +1,4 @@ +{ + "name": "Upload Widget with Upload Preset (TypeScript)", + "tech": "react" +} \ No newline at end of file diff --git a/examples/react-upload-widget-preset/config.json b/examples/react-upload-widget-preset/config.json new file mode 100644 index 00000000..69ddef1f --- /dev/null +++ b/examples/react-upload-widget-preset/config.json @@ -0,0 +1,4 @@ +{ + "name": "Cloudinary Upload Widget with an Upload Preset (Unsigned)", + "tech": "react" +} \ No newline at end of file diff --git a/examples/react-video-player/config.json b/examples/react-video-player/config.json new file mode 100644 index 00000000..7126e6c9 --- /dev/null +++ b/examples/react-video-player/config.json @@ -0,0 +1,4 @@ +{ + "name": "Cloudinary Video Player", + "tech": "react" +} \ No newline at end of file diff --git a/examples/react-webcam/config.json b/examples/react-webcam/config.json new file mode 100644 index 00000000..d0c4e2f2 --- /dev/null +++ b/examples/react-webcam/config.json @@ -0,0 +1,4 @@ +{ + "name": "Webcam", + "tech": "react" +} \ No newline at end of file diff --git a/examples/remix-product-gallery/config.json b/examples/remix-product-gallery/config.json new file mode 100644 index 00000000..75c5ded7 --- /dev/null +++ b/examples/remix-product-gallery/config.json @@ -0,0 +1,4 @@ +{ + "name": "Cloudinary Product Gallery", + "tech": "remix" +} \ No newline at end of file diff --git a/examples/remix-transformations-effects/config.json b/examples/remix-transformations-effects/config.json new file mode 100644 index 00000000..ed18f4ca --- /dev/null +++ b/examples/remix-transformations-effects/config.json @@ -0,0 +1,4 @@ +{ + "name": "Transformations & Effects", + "tech": "remix" +} \ No newline at end of file diff --git a/examples/remix-upload-widget-preset/config.json b/examples/remix-upload-widget-preset/config.json new file mode 100644 index 00000000..73748b55 --- /dev/null +++ b/examples/remix-upload-widget-preset/config.json @@ -0,0 +1,4 @@ +{ + "name": "Cloudinary Upload Widget with an Upload Preset (Unsigned)", + "tech": "remix" +} \ No newline at end of file diff --git a/examples/remix-video-preview/config.json b/examples/remix-video-preview/config.json new file mode 100644 index 00000000..7b876db2 --- /dev/null +++ b/examples/remix-video-preview/config.json @@ -0,0 +1,4 @@ +{ + "name": "Video Preview", + "tech": "remix" +} \ No newline at end of file diff --git a/examples/ruby-image-overlay/config.json b/examples/ruby-image-overlay/config.json new file mode 100644 index 00000000..34f428a4 --- /dev/null +++ b/examples/ruby-image-overlay/config.json @@ -0,0 +1,4 @@ +{ + "name": "Image Overlays", + "tech": "ruby" +} \ No newline at end of file diff --git a/examples/ruby-image-upload/config.json b/examples/ruby-image-upload/config.json new file mode 100644 index 00000000..1678299a --- /dev/null +++ b/examples/ruby-image-upload/config.json @@ -0,0 +1,4 @@ +{ + "name": "Uploading Images", + "tech": "ruby" +} \ No newline at end of file diff --git a/examples/solid-product-gallery/config.json b/examples/solid-product-gallery/config.json new file mode 100644 index 00000000..d11ddc32 --- /dev/null +++ b/examples/solid-product-gallery/config.json @@ -0,0 +1,4 @@ +{ + "name": "Cloudinary Product Gallery", + "tech": "solidjs" +} \ No newline at end of file diff --git a/examples/solid-transformations-effects/config.json b/examples/solid-transformations-effects/config.json new file mode 100644 index 00000000..c8540fa6 --- /dev/null +++ b/examples/solid-transformations-effects/config.json @@ -0,0 +1,4 @@ +{ + "name": "Transformations & Effects", + "tech": "solidjs" +} \ No newline at end of file diff --git a/examples/solid-upload-widget-preset/config.json b/examples/solid-upload-widget-preset/config.json new file mode 100644 index 00000000..94ced555 --- /dev/null +++ b/examples/solid-upload-widget-preset/config.json @@ -0,0 +1,4 @@ +{ + "name": "Cloudinary Upload Widget with an Upload Preset (Unsigned)", + "tech": "solidjs" +} \ No newline at end of file diff --git a/examples/streamlit-transformations-effects/config.json b/examples/streamlit-transformations-effects/config.json new file mode 100644 index 00000000..8e2422a2 --- /dev/null +++ b/examples/streamlit-transformations-effects/config.json @@ -0,0 +1,4 @@ +{ + "name": "Transformations & Effects", + "tech": "streamlit" +} \ No newline at end of file diff --git a/examples/svelte-product-gallery/config.json b/examples/svelte-product-gallery/config.json new file mode 100644 index 00000000..c935cee6 --- /dev/null +++ b/examples/svelte-product-gallery/config.json @@ -0,0 +1,4 @@ +{ + "name": "Cloudinary Product Gallery", + "tech": "svelte" +} \ No newline at end of file diff --git a/examples/svelte-video-player/config.json b/examples/svelte-video-player/config.json new file mode 100644 index 00000000..496c7ef9 --- /dev/null +++ b/examples/svelte-video-player/config.json @@ -0,0 +1,4 @@ +{ + "name": "Cloudinary Video Player", + "tech": "svelte" +} \ No newline at end of file diff --git a/examples/sveltekit-cldimage/config.json b/examples/sveltekit-cldimage/config.json new file mode 100644 index 00000000..adb7a177 --- /dev/null +++ b/examples/sveltekit-cldimage/config.json @@ -0,0 +1,4 @@ +{ + "name": "Svelte Cloudinary - CldImage", + "tech": "sveltekit" +} \ No newline at end of file diff --git a/examples/sveltekit-cldogimage/config.json b/examples/sveltekit-cldogimage/config.json new file mode 100644 index 00000000..2dd795a9 --- /dev/null +++ b/examples/sveltekit-cldogimage/config.json @@ -0,0 +1,4 @@ +{ + "name": "Svelte Cloudinary - CldOgImage", + "tech": "sveltekit" +} \ No newline at end of file diff --git a/examples/sveltekit-clduploadwidget/config.json b/examples/sveltekit-clduploadwidget/config.json new file mode 100644 index 00000000..0c35a947 --- /dev/null +++ b/examples/sveltekit-clduploadwidget/config.json @@ -0,0 +1,4 @@ +{ + "name": "Svelte Cloudinary - CldUploadWidget", + "tech": "sveltekit" +} \ No newline at end of file diff --git a/examples/sveltekit-image-upload/config.json b/examples/sveltekit-image-upload/config.json new file mode 100644 index 00000000..fce1d176 --- /dev/null +++ b/examples/sveltekit-image-upload/config.json @@ -0,0 +1,4 @@ +{ + "name": "Uploading Images", + "tech": "sveltekit" +} \ No newline at end of file diff --git a/examples/sveltekit-transformations-effects/config.json b/examples/sveltekit-transformations-effects/config.json new file mode 100644 index 00000000..11546ea7 --- /dev/null +++ b/examples/sveltekit-transformations-effects/config.json @@ -0,0 +1,4 @@ +{ + "name": "Transformations & Effects", + "tech": "sveltekit" +} \ No newline at end of file diff --git a/examples/sveltekit-upload-widget-preset/config.json b/examples/sveltekit-upload-widget-preset/config.json new file mode 100644 index 00000000..3064da88 --- /dev/null +++ b/examples/sveltekit-upload-widget-preset/config.json @@ -0,0 +1,4 @@ +{ + "name": "Cloudinary Upload Widget with an Upload Preset (Unsigned)", + "tech": "sveltekit" +} \ No newline at end of file diff --git a/examples/tina-with-cloudinary/config.json b/examples/tina-with-cloudinary/config.json new file mode 100644 index 00000000..3e3f42b1 --- /dev/null +++ b/examples/tina-with-cloudinary/config.json @@ -0,0 +1,4 @@ +{ + "name": "Cloudinary Media Manager Integration", + "tech": "tina" +} \ No newline at end of file diff --git a/examples/vercel-countdown-timer/config.json b/examples/vercel-countdown-timer/config.json new file mode 100644 index 00000000..1671b851 --- /dev/null +++ b/examples/vercel-countdown-timer/config.json @@ -0,0 +1,4 @@ +{ + "name": "Countdown Timer", + "tech": "vercel" +} \ No newline at end of file diff --git a/examples/vercel-custom-function-remote/config.json b/examples/vercel-custom-function-remote/config.json new file mode 100644 index 00000000..ebb18d68 --- /dev/null +++ b/examples/vercel-custom-function-remote/config.json @@ -0,0 +1,4 @@ +{ + "name": "Custom Function Remote", + "tech": "vercel" +} \ No newline at end of file diff --git a/examples/vue-advanced-image/config.json b/examples/vue-advanced-image/config.json new file mode 100644 index 00000000..954cafc3 --- /dev/null +++ b/examples/vue-advanced-image/config.json @@ -0,0 +1,4 @@ +{ + "name": "Cloudinary AdvancedImage", + "tech": "vue" +} \ No newline at end of file diff --git a/examples/vue-product-gallery/config.json b/examples/vue-product-gallery/config.json new file mode 100644 index 00000000..bbd85f7c --- /dev/null +++ b/examples/vue-product-gallery/config.json @@ -0,0 +1,4 @@ +{ + "name": "Cloudinary Product Gallery", + "tech": "vue" +} \ No newline at end of file diff --git a/examples/vue-upload-widget-preset/config.json b/examples/vue-upload-widget-preset/config.json new file mode 100644 index 00000000..4059ce44 --- /dev/null +++ b/examples/vue-upload-widget-preset/config.json @@ -0,0 +1,4 @@ +{ + "name": "Cloudinary Upload Widget with an Upload Preset (Unsigned)", + "tech": "vue" +} \ No newline at end of file diff --git a/scripts/bun.lockb b/scripts/bun.lockb new file mode 100644 index 00000000..366f7012 Binary files /dev/null and b/scripts/bun.lockb differ diff --git a/scripts/package.json b/scripts/package.json new file mode 100644 index 00000000..6b5896b3 --- /dev/null +++ b/scripts/package.json @@ -0,0 +1,11 @@ +{ + "name": "scripts", + "module": "index.ts", + "type": "module", + "devDependencies": { + "@types/bun": "^1.1.12" + }, + "peerDependencies": { + "typescript": "^5.0.0" + } +} \ No newline at end of file diff --git a/scripts/tsconfig.json b/scripts/tsconfig.json new file mode 100644 index 00000000..238655f2 --- /dev/null +++ b/scripts/tsconfig.json @@ -0,0 +1,27 @@ +{ + "compilerOptions": { + // Enable latest features + "lib": ["ESNext", "DOM"], + "target": "ESNext", + "module": "ESNext", + "moduleDetection": "force", + "jsx": "react-jsx", + "allowJs": true, + + // Bundler mode + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "verbatimModuleSyntax": true, + "noEmit": true, + + // Best practices + "strict": true, + "skipLibCheck": true, + "noFallthroughCasesInSwitch": true, + + // Some stricter flags (disabled by default) + "noUnusedLocals": false, + "noUnusedParameters": false, + "noPropertyAccessFromIndexSignature": false + } +} diff --git a/scripts/update-readme.ts b/scripts/update-readme.ts new file mode 100644 index 00000000..91ecfd0e --- /dev/null +++ b/scripts/update-readme.ts @@ -0,0 +1,101 @@ +import fs from "node:fs/promises"; +import path from "node:path"; + +type TechMapping = Record; +type ExampleMapping = Record; +type ExampleConfig = Omit; +interface Example { + name: string; + tech: string; + url: string; +} + +const repoUrl = + "https://github.com/cloudinary-community/cloudinary-examples/tree/main/examples/"; + +async function loadTechs(): Promise { + const techsData: TechMapping = await Bun.file("techs.json").json(); + return techsData; +} + +async function getExamples(techs: TechMapping): Promise { + const examplesByTech: ExampleMapping = {}; + const missingTechs = new Set(); + + const folders = await fs.readdir("examples"); + for (const folder of folders) { + const configPath = path.join("examples", folder, "config.json"); + try { + const config: ExampleConfig = await Bun.file(configPath).json(); + + if (!techs[config.tech]) { + missingTechs.add(config.tech); + continue; + } + + const tech = techs[config.tech]; + if (!examplesByTech[tech]) examplesByTech[tech] = []; + + examplesByTech[tech].push({ + tech, + name: config.name, + url: repoUrl + encodeURIComponent(folder), + }); + } catch (error) { + console.error(`Error reading ${configPath}:`, error); + throw error; + } + } + + if (missingTechs.size > 0) { + const missingTechsMsg = [...missingTechs].join(", "); + await Bun.write("error.log", missingTechsMsg); + throw new Error(missingTechsMsg); + } + + return examplesByTech; +} + +async function updateReadme() { + const techs = await loadTechs(); + const examplesByTech = await getExamples(techs); + + const techList = Object.keys(techs) + .map(key => `- [${techs[key]}](#${key})`) + .join("\n"); + + const exampleSections = Object.keys(techs) + .map(key => { + const tech = techs[key]; + if (examplesByTech[tech] && examplesByTech[tech].length > 0) { + return `### ${tech}\n\n${examplesByTech[tech] + .map(example => `- [${example.name}](${example.url})`) + .join("\n")}`; + } + return null; + }) + .filter(Boolean) + .join("\n\n"); + + let readmeContent = await fs.readFile("README.md", "utf-8"); + + readmeContent = readmeContent.replace( + /[\s\S]*?/, + ` +${techList} + +## 🧰 Examples + +${exampleSections} +` + ); + + await Bun.write("README.md", readmeContent.trim()); +} + +updateReadme() + .then(() => console.log("README updated successfully.")) + .catch(error => { + console.error("Error updating README:", error); + process.exit(1); + }); diff --git a/techs.json b/techs.json new file mode 100644 index 00000000..93972012 --- /dev/null +++ b/techs.json @@ -0,0 +1,31 @@ +{ + "net": ".NET", + "android": "Android", + "javascript": "JavaScript", + "angular": "Angular", + "astro": "Astro", + "dart": "Dart", + "flutter": "Flutter", + "go": "Go", + "html--browser": "HTML & Browser", + "ios": "iOS", + "java": "Java", + "kotlin": "Kotlin", + "laravel": "Laravel", + "netlify": "Netlify", + "nextjs": "Next.js", + "nodejs": "Node.js", + "nuxt": "Nuxt", + "php": "PHP", + "python": "Python", + "react": "React", + "remix": "Remix", + "ruby": "Ruby", + "solidjs": "SolidJS", + "svelte": "Svelte", + "sveltekit": "SvelteKit", + "streamlit": "Streamlit", + "tina": "Tina", + "vue": "Vue", + "vercel": "Vercel" +}