npm package: @synchronized-studio/response-transformer
Description: Transform CMS response asset URLs (Prismic/Contentful/Sanity/Shopify/Cloudinary/Imgix/Generic) to your CMS assets proxy base URL.
Author: Synchronized Studio
Latest version: 0.7.3

# @synchronized-studio/response-transformer

Small JavaScript utility for transforming CMS response payloads by replacing CMS asset URLs with your proxy/base URL.

Supports:
- Prismic (`*.cdn.prismic.io` and `images.prismic.io`)
- Contentful (`images.ctfassets.net` and `videos.ctfassets.net`)
- Sanity (`cdn.sanity.io`)
- Shopify (`*.myshopify.com/cdn/`)
- Cloudinary (`res.cloudinary.com`)
- Imgix (custom Imgix domains)
- Generic (any HTTPS origin — S3, R2, GCS, custom servers)

The transformer works on any JSON-serializable value using:
`JSON.stringify -> replace -> JSON.parse`.

## Install

```bash
npm install @synchronized-studio/response-transformer
```

NPM package page:

`https://www.npmjs.com/package/@synchronized-studio/response-transformer`

## Quick Start

Set your base URL:

```bash
export CMS_ASSETS_URL="https://assets.example.com"
```

Then use:

```js
import { transformCmsAssetUrls } from '@synchronized-studio/response-transformer'

const transformed = transformCmsAssetUrls(cmsData, {
  cms: 'prismic',
  repository: 'example-repo',
})
```

## API

### `transformPrismicAssetUrls(data, options)`

```js
import { transformPrismicAssetUrls } from '@synchronized-studio/response-transformer'

const transformed = transformPrismicAssetUrls(data, {
  repository: 'example-repo',
  cmsAssetsUrl: 'https://assets.example.com',
})
```

### `transformContentfulAssetUrls(data, options)`

```js
import { transformContentfulAssetUrls } from '@synchronized-studio/response-transformer'

const transformed = transformContentfulAssetUrls(data, {
  spaceId: 'exampleSpaceId',
  cmsAssetsUrl: 'https://assets.example.com',
})
```

### `transformGenericAssetUrls(data, options)`

```js
import { transformGenericAssetUrls } from '@synchronized-studio/response-transformer'

const transformed = transformGenericAssetUrls(data, {
  originUrl: 'https://my-bucket.s3.amazonaws.com',
  cmsAssetsUrl: 'https://assets.example.com',
})
```

### `transformCmsAssetUrls(data, options)`

Unified helper:

```js
import { transformCmsAssetUrls } from '@synchronized-studio/response-transformer'

const transformedPrismic = transformCmsAssetUrls(data, {
  cms: 'prismic',
  repository: 'example-repo',
  cmsAssetsUrl: 'https://assets.example.com',
})

const transformedContentful = transformCmsAssetUrls(data, {
  cms: 'contentful',
  spaceId: 'exampleSpaceId',
  cmsAssetsUrl: 'https://assets.example.com',
})

const transformedGeneric = transformCmsAssetUrls(data, {
  cms: 'generic',
  originUrl: 'https://my-bucket.s3.amazonaws.com',
  cmsAssetsUrl: 'https://assets.example.com',
})
```

## Options

Common options:
- `cmsAssetsUrl`: explicit base URL override (otherwise uses env)
- `envVarName`: environment variable name (default: `CMS_ASSETS_URL`)
- `env`: environment object override (default: `process.env`)
- `nodeEnv`: runtime env override
- `forceHttpsInProduction`: defaults to `true`
- `throwOnError`: when `true`, throws transform errors instead of returning original data
- `transformers`: array of custom string transformers
- `postTransform`: hook called after JSON parse
- `onError`: custom error callback

Provider-specific required options when using `transformCmsAssetUrls`:
- `cms: 'prismic'` -> `repository`
- `cms: 'contentful'` -> `spaceId`
- `cms: 'sanity'` -> `projectId`
- `cms: 'shopify'` -> `storeDomain`
- `cms: 'cloudinary'` -> `cloudName`
- `cms: 'imgix'` -> `imgixDomain`
- `cms: 'generic'` -> `originUrl`

## Custom Transformers

```js
import { transformPrismicAssetUrls } from '@synchronized-studio/response-transformer'

const transformed = transformPrismicAssetUrls(data, {
  repository: 'example-repo',
  transformers: [
    (jsonStr, { base }) => jsonStr.replaceAll('"legacyBase"', `"${base}"`)
  ],
})
```

## Separate End-to-End Examples

### Prismic

```js
import { transformPrismicAssetUrls } from '@synchronized-studio/response-transformer'

const prismicData = {
  heroImage: {
    url: 'https://images.prismic.io/example-repo/banner.png?auto=format'
  }
}

const transformed = transformPrismicAssetUrls(prismicData, {
  repository: 'example-repo',
  cmsAssetsUrl: 'https://assets.example.com',
})
```

### Contentful

```js
import { transformContentfulAssetUrls } from '@synchronized-studio/response-transformer'

const contentfulData = {
  image: {
    url: 'https://images.ctfassets.net/exampleSpaceId/token/hero.webp?w=1200'
  },
  video: {
    url: 'https://videos.ctfassets.net/exampleSpaceId/videoToken/intro.mp4'
  }
}

const transformed = transformContentfulAssetUrls(contentfulData, {
  spaceId: 'exampleSpaceId',
  cmsAssetsUrl: 'https://assets.example.com',
})
```

### Generic Origin

```js
import { transformGenericAssetUrls } from '@synchronized-studio/response-transformer'

const s3Data = {
  image: {
    url: 'https://my-bucket.s3.amazonaws.com/uploads/photo.jpg?v=123'
  }
}

const transformed = transformGenericAssetUrls(s3Data, {
  originUrl: 'https://my-bucket.s3.amazonaws.com',
  cmsAssetsUrl: 'https://assets.example.com',
})
// Result: { image: { url: 'https://assets.example.com/uploads/photo.jpg?v=123' } }
```

## Examples

See `examples/basic-usage.js`.

## Publish

From this package folder:

```bash
npm run prepublishOnly
npm publish --access public
```

## Metadata checklist (recommended)

Before first public publish, set these fields in `package.json` if you have URLs:
- `repository`
- `homepage`
- `bugs`