diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index a5237d2..d5e1c7a 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -1,18 +1,51 @@
name: CI
on:
push:
- branches-ignore:
- - 'generated'
- - 'codegen/**'
- - 'integrated/**'
- - 'stl-preview-head/**'
- - 'stl-preview-base/**'
+ branches:
+ - '**'
+ - '!integrated/**'
+ - '!stl-preview-head/**'
+ - '!stl-preview-base/**'
+ - '!generated'
+ - '!codegen/**'
+ - 'codegen/stl/**'
pull_request:
branches-ignore:
- 'stl-preview-head/**'
- 'stl-preview-base/**'
jobs:
+ build:
+ timeout-minutes: 10
+ name: build
+ permissions:
+ contents: read
+ id-token: write
+ runs-on: ${{ github.repository == 'stainless-sdks/imagekit-go' && 'depot-ubuntu-24.04' || 'ubuntu-latest' }}
+ if: |-
+ github.repository == 'stainless-sdks/imagekit-go' &&
+ (github.event_name == 'push' || github.event.pull_request.head.repo.fork) && (github.event_name != 'push' || github.event.head_commit.message != 'codegen metadata')
+ steps:
+ - uses: actions/checkout@v6
+
+ - name: Get GitHub OIDC Token
+ if: |-
+ github.repository == 'stainless-sdks/imagekit-go' &&
+ !startsWith(github.ref, 'refs/heads/stl/')
+ id: github-oidc
+ uses: actions/github-script@v8
+ with:
+ script: core.setOutput('github_token', await core.getIDToken());
+
+ - name: Upload tarball
+ if: |-
+ github.repository == 'stainless-sdks/imagekit-go' &&
+ !startsWith(github.ref, 'refs/heads/stl/')
+ env:
+ URL: https://pkg.stainless.com/s
+ AUTH: ${{ steps.github-oidc.outputs.github_token }}
+ SHA: ${{ github.sha }}
+ run: ./scripts/utils/upload-artifact.sh
lint:
timeout-minutes: 10
name: lint
diff --git a/.gitignore b/.gitignore
index f7cafc9..01c321d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,4 +1,5 @@
.prism.log
+.stdy.log
codegen.log
Brewfile.lock.json
.idea/
diff --git a/.release-please-manifest.json b/.release-please-manifest.json
index bfc26f9..75ec52f 100644
--- a/.release-please-manifest.json
+++ b/.release-please-manifest.json
@@ -1,3 +1,3 @@
{
- ".": "2.2.0"
+ ".": "2.3.0"
}
\ No newline at end of file
diff --git a/.stats.yml b/.stats.yml
index 94357b3..0e8db84 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
configured_endpoints: 48
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/imagekit-inc%2Fimagekit-13fc3d7cafdea492f62eef7c1d63424d6d9d8adbff74b9f6ca6fd3fc12a36840.yml
-openapi_spec_hash: a1fe6fa48207791657a1ea2d60a6dfcc
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/imagekit-inc%2Fimagekit-63aff1629530786015da3c86131afa8a9b60545d488884b77641f1d4b89c6e9d.yml
+openapi_spec_hash: 586d357bd7e5217d240a99e0d83c6d1f
config_hash: 47cb702ee2cb52c58d803ae39ade9b44
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 6a9b04c..99dd1f7 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,53 @@
# Changelog
+## 2.3.0 (2026-04-06)
+
+Full Changelog: [v2.2.0...v2.3.0](https://github.com/imagekit-developer/imagekit-go/compare/v2.2.0...v2.3.0)
+
+### Features
+
+* **api:** add support for xCenter, yCenter, and anchorPoint in overlay URL generation ([50ef82e](https://github.com/imagekit-developer/imagekit-go/commit/50ef82eb5eb19302a7c9933166e2643c4b60b6ec))
+* **api:** dpr type update ([7b5ed76](https://github.com/imagekit-developer/imagekit-go/commit/7b5ed7649a30f369e05741ad26e87866ab369341))
+* **api:** Introduce lxc, lyc, lap parameters in overlays. ([1d33db8](https://github.com/imagekit-developer/imagekit-go/commit/1d33db8dbb8860ca132781e558ce3dab880860b2))
+* **api:** revert dpr breaking change ([4f76b02](https://github.com/imagekit-developer/imagekit-go/commit/4f76b02da01cce562522509abc4aeb9f43632227))
+* **internal:** support comma format in multipart form encoding ([e0ecf81](https://github.com/imagekit-developer/imagekit-go/commit/e0ecf8124b1c7a1f02cef55883fb139e0bbf2363))
+
+
+### Bug Fixes
+
+* allow canceling a request while it is waiting to retry ([c772a06](https://github.com/imagekit-developer/imagekit-go/commit/c772a06aa381125614083d572ce99b73b4eb3ce5))
+* **encoder:** correctly serialize NullStruct ([c8a223a](https://github.com/imagekit-developer/imagekit-go/commit/c8a223a358428b56cd5f13843928252c58acff90))
+* fix issue with unmarshaling in some cases ([c05145e](https://github.com/imagekit-developer/imagekit-go/commit/c05145eb2eced30cb2398810796c0b6a2fa81e00))
+* fix request delays for retrying to be more respectful of high requested delays ([065df63](https://github.com/imagekit-developer/imagekit-go/commit/065df633342605e2d5f69d707170c8b92e5f59fb))
+* prevent duplicate ? in query params ([1c53d0d](https://github.com/imagekit-developer/imagekit-go/commit/1c53d0da2b0a2eaa26b29b3fa6b69dc84d78a8be))
+* **types:** generate shared enum types that are not referenced by other schemas ([420472d](https://github.com/imagekit-developer/imagekit-go/commit/420472d6e58c1626a7a15fa0c81cfbe02539c2d0))
+
+
+### Chores
+
+* **ci:** add build step ([950faa7](https://github.com/imagekit-developer/imagekit-go/commit/950faa70ba325a3af7e2149618d1690d681888a1))
+* **ci:** skip lint on metadata-only changes ([cb58aa5](https://github.com/imagekit-developer/imagekit-go/commit/cb58aa516481e088ef0924c1d2e8979df33800aa))
+* **ci:** skip uploading artifacts on stainless-internal branches ([1fedd9f](https://github.com/imagekit-developer/imagekit-go/commit/1fedd9f85df8d3c231fb7eb7e342ef98a2fe3acc))
+* **ci:** support opting out of skipping builds on metadata-only commits ([9781c64](https://github.com/imagekit-developer/imagekit-go/commit/9781c64025356760a3b067d0f13c897282747997))
+* **client:** fix multipart serialisation of Default() fields ([facb97a](https://github.com/imagekit-developer/imagekit-go/commit/facb97a34c051ca7f0b5ce1c18fca7eddf94b68e))
+* **internal:** codegen related update ([a4bb374](https://github.com/imagekit-developer/imagekit-go/commit/a4bb374e09dc89d66cc143dc3b6bb1f315e0e4cb))
+* **internal:** codegen related update ([255a031](https://github.com/imagekit-developer/imagekit-go/commit/255a0313de39110cdedc4002d451bdc39e3bc308))
+* **internal:** codegen related update ([e1e4755](https://github.com/imagekit-developer/imagekit-go/commit/e1e47559733779920f899cb665b244e431702668))
+* **internal:** codegen related update ([5071176](https://github.com/imagekit-developer/imagekit-go/commit/50711763c0f3bee01b36ab00500db61aa371415b))
+* **internal:** minor cleanup ([bba2f4a](https://github.com/imagekit-developer/imagekit-go/commit/bba2f4a012b76ed18936d5659db28505d88cf694))
+* **internal:** move custom custom `json` tags to `api` ([4609e1f](https://github.com/imagekit-developer/imagekit-go/commit/4609e1fd02735cc92d442ab6c6360429b5a8318d))
+* **internal:** remove mock server code ([ab007f7](https://github.com/imagekit-developer/imagekit-go/commit/ab007f7fa428ff639b7c1177976d76b4c66eb5f5))
+* **internal:** support default value struct tag ([86a3f7c](https://github.com/imagekit-developer/imagekit-go/commit/86a3f7cc8bce7c25b59720b35dfe590b974933eb))
+* **internal:** tweak CI branches ([28a816d](https://github.com/imagekit-developer/imagekit-go/commit/28a816d34c0bb30be0a550ade3fc7e3a848c98bf))
+* **internal:** update gitignore ([bbc7450](https://github.com/imagekit-developer/imagekit-go/commit/bbc745035b8765ad93a60ab91114135d1343e1d0))
+* **internal:** use explicit returns ([3d59762](https://github.com/imagekit-developer/imagekit-go/commit/3d59762abc0b08d20e1d3aa2f10e1e46b8e605b0))
+* **internal:** use explicit returns in more places ([93dfb11](https://github.com/imagekit-developer/imagekit-go/commit/93dfb117b673e0fbb123d47862bd48f7e685bfdd))
+* remove unnecessary error check for url parsing ([7517de5](https://github.com/imagekit-developer/imagekit-go/commit/7517de5c74a9c6cc7bab2ed0fa6c48278558d1b5))
+* **tests:** update webhook tests ([f3ef31e](https://github.com/imagekit-developer/imagekit-go/commit/f3ef31e396305fb69fa7905821fd2e94258f3b18))
+* update docs for api:"required" ([d5de86f](https://github.com/imagekit-developer/imagekit-go/commit/d5de86f78052cefc4c28da6049f66980d7f79112))
+* update mock server docs ([1ba9e87](https://github.com/imagekit-developer/imagekit-go/commit/1ba9e87f6b30e3992999808434dd39298de4d0a0))
+* update placeholder string ([a783267](https://github.com/imagekit-developer/imagekit-go/commit/a7832673f2d1d19e5c1d87b2ab3ad3b152288f73))
+
## 2.2.0 (2026-02-02)
Full Changelog: [v2.1.1...v2.2.0](https://github.com/imagekit-developer/imagekit-go/compare/v2.1.1...v2.2.0)
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 0635957..00f7743 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -46,13 +46,6 @@ $ go mod edit -replace github.com/imagekit-developer/imagekit-go=/path/to/imagek
## Running tests
-Most tests require you to [set up a mock server](https://github.com/stoplightio/prism) against the OpenAPI spec to run the tests.
-
-```sh
-# you will need npm installed
-$ npx prism mock path/to/your/openapi.yml
-```
-
```sh
$ ./scripts/test
```
diff --git a/README.md b/README.md
index ffc95e0..b41c73f 100644
--- a/README.md
+++ b/README.md
@@ -59,7 +59,7 @@ Or to pin the version:
```sh
-go get -u 'github.com/imagekit-developer/imagekit-go/v2@v2.2.0'
+go get -u 'github.com/imagekit-developer/imagekit-go/v2@v2.3.0'
```
@@ -112,7 +112,7 @@ func main() {
The imagekit library uses the [`omitzero`](https://tip.golang.org/doc/go1.24#encodingjsonpkgencodingjson)
semantics from the Go 1.24+ `encoding/json` release for request fields.
-Required primitive fields (`int64`, `string`, etc.) feature the tag \`json:"...,required"\`. These
+Required primitive fields (`int64`, `string`, etc.) feature the tag \`api:"required"\`. These
fields are always serialized, even their zero values.
Optional primitive types are wrapped in a `param.Opt[T]`. These fields can be set with the provided constructors, `imagekit.String(string)`, `imagekit.Int(int64)`, etc.
diff --git a/accountorigin.go b/accountorigin.go
index 52888b2..e3db111 100644
--- a/accountorigin.go
+++ b/accountorigin.go
@@ -44,7 +44,7 @@ func (r *AccountOriginService) New(ctx context.Context, body AccountOriginNewPar
opts = slices.Concat(r.Options, opts)
path := "v1/accounts/origins"
err = requestconfig.ExecuteNewRequest(ctx, http.MethodPost, path, body, &res, opts...)
- return
+ return res, err
}
// **Note:** This API is currently in beta.
@@ -53,11 +53,11 @@ func (r *AccountOriginService) Update(ctx context.Context, id string, body Accou
opts = slices.Concat(r.Options, opts)
if id == "" {
err = errors.New("missing required id parameter")
- return
+ return nil, err
}
path := fmt.Sprintf("v1/accounts/origins/%s", id)
err = requestconfig.ExecuteNewRequest(ctx, http.MethodPut, path, body, &res, opts...)
- return
+ return res, err
}
// **Note:** This API is currently in beta.
@@ -66,7 +66,7 @@ func (r *AccountOriginService) List(ctx context.Context, opts ...option.RequestO
opts = slices.Concat(r.Options, opts)
path := "v1/accounts/origins"
err = requestconfig.ExecuteNewRequest(ctx, http.MethodGet, path, nil, &res, opts...)
- return
+ return res, err
}
// **Note:** This API is currently in beta.
@@ -77,11 +77,11 @@ func (r *AccountOriginService) Delete(ctx context.Context, id string, opts ...op
opts = append([]option.RequestOption{option.WithHeader("Accept", "*/*")}, opts...)
if id == "" {
err = errors.New("missing required id parameter")
- return
+ return err
}
path := fmt.Sprintf("v1/accounts/origins/%s", id)
err = requestconfig.ExecuteNewRequest(ctx, http.MethodDelete, path, nil, nil, opts...)
- return
+ return err
}
// **Note:** This API is currently in beta.
@@ -90,11 +90,11 @@ func (r *AccountOriginService) Get(ctx context.Context, id string, opts ...optio
opts = slices.Concat(r.Options, opts)
if id == "" {
err = errors.New("missing required id parameter")
- return
+ return nil, err
}
path := fmt.Sprintf("v1/accounts/origins/%s", id)
err = requestconfig.ExecuteNewRequest(ctx, http.MethodGet, path, nil, &res, opts...)
- return
+ return res, err
}
func OriginRequestParamOfWebFolder(baseURL string, name string) OriginRequestUnionParam {
@@ -425,13 +425,13 @@ func init() {
// The properties AccessKey, Bucket, Name, SecretKey, Type are required.
type OriginRequestS3Param struct {
// Access key for the bucket.
- AccessKey string `json:"accessKey,required"`
+ AccessKey string `json:"accessKey" api:"required"`
// S3 bucket name.
- Bucket string `json:"bucket,required"`
+ Bucket string `json:"bucket" api:"required"`
// Display name of the origin.
- Name string `json:"name,required"`
+ Name string `json:"name" api:"required"`
// Secret key for the bucket.
- SecretKey string `json:"secretKey,required"`
+ SecretKey string `json:"secretKey" api:"required"`
// URL used in the Canonical header (if enabled).
BaseURLForCanonicalHeader param.Opt[string] `json:"baseUrlForCanonicalHeader,omitzero" format:"uri"`
// Whether to send a Canonical header.
@@ -439,7 +439,7 @@ type OriginRequestS3Param struct {
// Path prefix inside the bucket.
Prefix param.Opt[string] `json:"prefix,omitzero"`
// This field can be elided, and will marshal its zero value as "S3".
- Type constant.S3 `json:"type,required"`
+ Type constant.S3 `json:"type" default:"S3"`
paramObj
}
@@ -454,15 +454,15 @@ func (r *OriginRequestS3Param) UnmarshalJSON(data []byte) error {
// The properties AccessKey, Bucket, Endpoint, Name, SecretKey, Type are required.
type OriginRequestS3CompatibleParam struct {
// Access key for the bucket.
- AccessKey string `json:"accessKey,required"`
+ AccessKey string `json:"accessKey" api:"required"`
// S3 bucket name.
- Bucket string `json:"bucket,required"`
+ Bucket string `json:"bucket" api:"required"`
// Custom S3-compatible endpoint.
- Endpoint string `json:"endpoint,required" format:"uri"`
+ Endpoint string `json:"endpoint" api:"required" format:"uri"`
// Display name of the origin.
- Name string `json:"name,required"`
+ Name string `json:"name" api:"required"`
// Secret key for the bucket.
- SecretKey string `json:"secretKey,required"`
+ SecretKey string `json:"secretKey" api:"required"`
// URL used in the Canonical header (if enabled).
BaseURLForCanonicalHeader param.Opt[string] `json:"baseUrlForCanonicalHeader,omitzero" format:"uri"`
// Whether to send a Canonical header.
@@ -472,7 +472,7 @@ type OriginRequestS3CompatibleParam struct {
// Use path-style S3 URLs?
S3ForcePathStyle param.Opt[bool] `json:"s3ForcePathStyle,omitzero"`
// This field can be elided, and will marshal its zero value as "S3_COMPATIBLE".
- Type constant.S3Compatible `json:"type,required"`
+ Type constant.S3Compatible `json:"type" default:"S3_COMPATIBLE"`
paramObj
}
@@ -487,13 +487,13 @@ func (r *OriginRequestS3CompatibleParam) UnmarshalJSON(data []byte) error {
// The properties AccessKey, Bucket, Name, SecretKey, Type are required.
type OriginRequestCloudinaryBackupParam struct {
// Access key for the bucket.
- AccessKey string `json:"accessKey,required"`
+ AccessKey string `json:"accessKey" api:"required"`
// S3 bucket name.
- Bucket string `json:"bucket,required"`
+ Bucket string `json:"bucket" api:"required"`
// Display name of the origin.
- Name string `json:"name,required"`
+ Name string `json:"name" api:"required"`
// Secret key for the bucket.
- SecretKey string `json:"secretKey,required"`
+ SecretKey string `json:"secretKey" api:"required"`
// URL used in the Canonical header (if enabled).
BaseURLForCanonicalHeader param.Opt[string] `json:"baseUrlForCanonicalHeader,omitzero" format:"uri"`
// Whether to send a Canonical header.
@@ -502,7 +502,7 @@ type OriginRequestCloudinaryBackupParam struct {
Prefix param.Opt[string] `json:"prefix,omitzero"`
// This field can be elided, and will marshal its zero value as
// "CLOUDINARY_BACKUP".
- Type constant.CloudinaryBackup `json:"type,required"`
+ Type constant.CloudinaryBackup `json:"type" default:"CLOUDINARY_BACKUP"`
paramObj
}
@@ -517,9 +517,9 @@ func (r *OriginRequestCloudinaryBackupParam) UnmarshalJSON(data []byte) error {
// The properties BaseURL, Name, Type are required.
type OriginRequestWebFolderParam struct {
// Root URL for the web folder origin.
- BaseURL string `json:"baseUrl,required" format:"uri"`
+ BaseURL string `json:"baseUrl" api:"required" format:"uri"`
// Display name of the origin.
- Name string `json:"name,required"`
+ Name string `json:"name" api:"required"`
// URL used in the Canonical header (if enabled).
BaseURLForCanonicalHeader param.Opt[string] `json:"baseUrlForCanonicalHeader,omitzero" format:"uri"`
// Forward the Host header to origin?
@@ -527,7 +527,7 @@ type OriginRequestWebFolderParam struct {
// Whether to send a Canonical header.
IncludeCanonicalHeader param.Opt[bool] `json:"includeCanonicalHeader,omitzero"`
// This field can be elided, and will marshal its zero value as "WEB_FOLDER".
- Type constant.WebFolder `json:"type,required"`
+ Type constant.WebFolder `json:"type" default:"WEB_FOLDER"`
paramObj
}
@@ -542,13 +542,13 @@ func (r *OriginRequestWebFolderParam) UnmarshalJSON(data []byte) error {
// The properties Name, Type are required.
type OriginRequestWebProxyParam struct {
// Display name of the origin.
- Name string `json:"name,required"`
+ Name string `json:"name" api:"required"`
// URL used in the Canonical header (if enabled).
BaseURLForCanonicalHeader param.Opt[string] `json:"baseUrlForCanonicalHeader,omitzero" format:"uri"`
// Whether to send a Canonical header.
IncludeCanonicalHeader param.Opt[bool] `json:"includeCanonicalHeader,omitzero"`
// This field can be elided, and will marshal its zero value as "WEB_PROXY".
- Type constant.WebProxy `json:"type,required"`
+ Type constant.WebProxy `json:"type" default:"WEB_PROXY"`
paramObj
}
@@ -562,18 +562,18 @@ func (r *OriginRequestWebProxyParam) UnmarshalJSON(data []byte) error {
// The properties Bucket, ClientEmail, Name, PrivateKey, Type are required.
type OriginRequestGcsParam struct {
- Bucket string `json:"bucket,required"`
- ClientEmail string `json:"clientEmail,required" format:"email"`
+ Bucket string `json:"bucket" api:"required"`
+ ClientEmail string `json:"clientEmail" api:"required" format:"email"`
// Display name of the origin.
- Name string `json:"name,required"`
- PrivateKey string `json:"privateKey,required"`
+ Name string `json:"name" api:"required"`
+ PrivateKey string `json:"privateKey" api:"required"`
// URL used in the Canonical header (if enabled).
BaseURLForCanonicalHeader param.Opt[string] `json:"baseUrlForCanonicalHeader,omitzero" format:"uri"`
// Whether to send a Canonical header.
IncludeCanonicalHeader param.Opt[bool] `json:"includeCanonicalHeader,omitzero"`
Prefix param.Opt[string] `json:"prefix,omitzero"`
// This field can be elided, and will marshal its zero value as "GCS".
- Type constant.Gcs `json:"type,required"`
+ Type constant.Gcs `json:"type" default:"GCS"`
paramObj
}
@@ -587,18 +587,18 @@ func (r *OriginRequestGcsParam) UnmarshalJSON(data []byte) error {
// The properties AccountName, Container, Name, SasToken, Type are required.
type OriginRequestAzureBlobParam struct {
- AccountName string `json:"accountName,required"`
- Container string `json:"container,required"`
+ AccountName string `json:"accountName" api:"required"`
+ Container string `json:"container" api:"required"`
// Display name of the origin.
- Name string `json:"name,required"`
- SasToken string `json:"sasToken,required"`
+ Name string `json:"name" api:"required"`
+ SasToken string `json:"sasToken" api:"required"`
// URL used in the Canonical header (if enabled).
BaseURLForCanonicalHeader param.Opt[string] `json:"baseUrlForCanonicalHeader,omitzero" format:"uri"`
// Whether to send a Canonical header.
IncludeCanonicalHeader param.Opt[bool] `json:"includeCanonicalHeader,omitzero"`
Prefix param.Opt[string] `json:"prefix,omitzero"`
// This field can be elided, and will marshal its zero value as "AZURE_BLOB".
- Type constant.AzureBlob `json:"type,required"`
+ Type constant.AzureBlob `json:"type" default:"AZURE_BLOB"`
paramObj
}
@@ -614,23 +614,23 @@ func (r *OriginRequestAzureBlobParam) UnmarshalJSON(data []byte) error {
// are required.
type OriginRequestAkeneoPimParam struct {
// Akeneo instance base URL.
- BaseURL string `json:"baseUrl,required" format:"uri"`
+ BaseURL string `json:"baseUrl" api:"required" format:"uri"`
// Akeneo API client ID.
- ClientID string `json:"clientId,required"`
+ ClientID string `json:"clientId" api:"required"`
// Akeneo API client secret.
- ClientSecret string `json:"clientSecret,required"`
+ ClientSecret string `json:"clientSecret" api:"required"`
// Display name of the origin.
- Name string `json:"name,required"`
+ Name string `json:"name" api:"required"`
// Akeneo API password.
- Password string `json:"password,required"`
+ Password string `json:"password" api:"required"`
// Akeneo API username.
- Username string `json:"username,required"`
+ Username string `json:"username" api:"required"`
// URL used in the Canonical header (if enabled).
BaseURLForCanonicalHeader param.Opt[string] `json:"baseUrlForCanonicalHeader,omitzero" format:"uri"`
// Whether to send a Canonical header.
IncludeCanonicalHeader param.Opt[bool] `json:"includeCanonicalHeader,omitzero"`
// This field can be elided, and will marshal its zero value as "AKENEO_PIM".
- Type constant.AkeneoPim `json:"type,required"`
+ Type constant.AkeneoPim `json:"type" default:"AKENEO_PIM"`
paramObj
}
@@ -794,16 +794,16 @@ func (r *OriginResponseUnion) UnmarshalJSON(data []byte) error {
type OriginResponseS3 struct {
// Unique identifier for the origin. This is generated by ImageKit when you create
// a new origin.
- ID string `json:"id,required"`
+ ID string `json:"id" api:"required"`
// S3 bucket name.
- Bucket string `json:"bucket,required"`
+ Bucket string `json:"bucket" api:"required"`
// Whether to send a Canonical header.
- IncludeCanonicalHeader bool `json:"includeCanonicalHeader,required"`
+ IncludeCanonicalHeader bool `json:"includeCanonicalHeader" api:"required"`
// Display name of the origin.
- Name string `json:"name,required"`
+ Name string `json:"name" api:"required"`
// Path prefix inside the bucket.
- Prefix string `json:"prefix,required"`
- Type constant.S3 `json:"type,required"`
+ Prefix string `json:"prefix" api:"required"`
+ Type constant.S3 `json:"type" default:"S3"`
// URL used in the Canonical header (if enabled).
BaseURLForCanonicalHeader string `json:"baseUrlForCanonicalHeader" format:"uri"`
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
@@ -829,20 +829,20 @@ func (r *OriginResponseS3) UnmarshalJSON(data []byte) error {
type OriginResponseS3Compatible struct {
// Unique identifier for the origin. This is generated by ImageKit when you create
// a new origin.
- ID string `json:"id,required"`
+ ID string `json:"id" api:"required"`
// S3 bucket name.
- Bucket string `json:"bucket,required"`
+ Bucket string `json:"bucket" api:"required"`
// Custom S3-compatible endpoint.
- Endpoint string `json:"endpoint,required" format:"uri"`
+ Endpoint string `json:"endpoint" api:"required" format:"uri"`
// Whether to send a Canonical header.
- IncludeCanonicalHeader bool `json:"includeCanonicalHeader,required"`
+ IncludeCanonicalHeader bool `json:"includeCanonicalHeader" api:"required"`
// Display name of the origin.
- Name string `json:"name,required"`
+ Name string `json:"name" api:"required"`
// Path prefix inside the bucket.
- Prefix string `json:"prefix,required"`
+ Prefix string `json:"prefix" api:"required"`
// Use path-style S3 URLs?
- S3ForcePathStyle bool `json:"s3ForcePathStyle,required"`
- Type constant.S3Compatible `json:"type,required"`
+ S3ForcePathStyle bool `json:"s3ForcePathStyle" api:"required"`
+ Type constant.S3Compatible `json:"type" default:"S3_COMPATIBLE"`
// URL used in the Canonical header (if enabled).
BaseURLForCanonicalHeader string `json:"baseUrlForCanonicalHeader" format:"uri"`
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
@@ -870,16 +870,16 @@ func (r *OriginResponseS3Compatible) UnmarshalJSON(data []byte) error {
type OriginResponseCloudinaryBackup struct {
// Unique identifier for the origin. This is generated by ImageKit when you create
// a new origin.
- ID string `json:"id,required"`
+ ID string `json:"id" api:"required"`
// S3 bucket name.
- Bucket string `json:"bucket,required"`
+ Bucket string `json:"bucket" api:"required"`
// Whether to send a Canonical header.
- IncludeCanonicalHeader bool `json:"includeCanonicalHeader,required"`
+ IncludeCanonicalHeader bool `json:"includeCanonicalHeader" api:"required"`
// Display name of the origin.
- Name string `json:"name,required"`
+ Name string `json:"name" api:"required"`
// Path prefix inside the bucket.
- Prefix string `json:"prefix,required"`
- Type constant.CloudinaryBackup `json:"type,required"`
+ Prefix string `json:"prefix" api:"required"`
+ Type constant.CloudinaryBackup `json:"type" default:"CLOUDINARY_BACKUP"`
// URL used in the Canonical header (if enabled).
BaseURLForCanonicalHeader string `json:"baseUrlForCanonicalHeader" format:"uri"`
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
@@ -905,16 +905,16 @@ func (r *OriginResponseCloudinaryBackup) UnmarshalJSON(data []byte) error {
type OriginResponseWebFolder struct {
// Unique identifier for the origin. This is generated by ImageKit when you create
// a new origin.
- ID string `json:"id,required"`
+ ID string `json:"id" api:"required"`
// Root URL for the web folder origin.
- BaseURL string `json:"baseUrl,required" format:"uri"`
+ BaseURL string `json:"baseUrl" api:"required" format:"uri"`
// Forward the Host header to origin?
- ForwardHostHeaderToOrigin bool `json:"forwardHostHeaderToOrigin,required"`
+ ForwardHostHeaderToOrigin bool `json:"forwardHostHeaderToOrigin" api:"required"`
// Whether to send a Canonical header.
- IncludeCanonicalHeader bool `json:"includeCanonicalHeader,required"`
+ IncludeCanonicalHeader bool `json:"includeCanonicalHeader" api:"required"`
// Display name of the origin.
- Name string `json:"name,required"`
- Type constant.WebFolder `json:"type,required"`
+ Name string `json:"name" api:"required"`
+ Type constant.WebFolder `json:"type" default:"WEB_FOLDER"`
// URL used in the Canonical header (if enabled).
BaseURLForCanonicalHeader string `json:"baseUrlForCanonicalHeader" format:"uri"`
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
@@ -940,12 +940,12 @@ func (r *OriginResponseWebFolder) UnmarshalJSON(data []byte) error {
type OriginResponseWebProxy struct {
// Unique identifier for the origin. This is generated by ImageKit when you create
// a new origin.
- ID string `json:"id,required"`
+ ID string `json:"id" api:"required"`
// Whether to send a Canonical header.
- IncludeCanonicalHeader bool `json:"includeCanonicalHeader,required"`
+ IncludeCanonicalHeader bool `json:"includeCanonicalHeader" api:"required"`
// Display name of the origin.
- Name string `json:"name,required"`
- Type constant.WebProxy `json:"type,required"`
+ Name string `json:"name" api:"required"`
+ Type constant.WebProxy `json:"type" default:"WEB_PROXY"`
// URL used in the Canonical header (if enabled).
BaseURLForCanonicalHeader string `json:"baseUrlForCanonicalHeader" format:"uri"`
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
@@ -969,15 +969,15 @@ func (r *OriginResponseWebProxy) UnmarshalJSON(data []byte) error {
type OriginResponseGcs struct {
// Unique identifier for the origin. This is generated by ImageKit when you create
// a new origin.
- ID string `json:"id,required"`
- Bucket string `json:"bucket,required"`
- ClientEmail string `json:"clientEmail,required" format:"email"`
+ ID string `json:"id" api:"required"`
+ Bucket string `json:"bucket" api:"required"`
+ ClientEmail string `json:"clientEmail" api:"required" format:"email"`
// Whether to send a Canonical header.
- IncludeCanonicalHeader bool `json:"includeCanonicalHeader,required"`
+ IncludeCanonicalHeader bool `json:"includeCanonicalHeader" api:"required"`
// Display name of the origin.
- Name string `json:"name,required"`
- Prefix string `json:"prefix,required"`
- Type constant.Gcs `json:"type,required"`
+ Name string `json:"name" api:"required"`
+ Prefix string `json:"prefix" api:"required"`
+ Type constant.Gcs `json:"type" default:"GCS"`
// URL used in the Canonical header (if enabled).
BaseURLForCanonicalHeader string `json:"baseUrlForCanonicalHeader" format:"uri"`
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
@@ -1004,15 +1004,15 @@ func (r *OriginResponseGcs) UnmarshalJSON(data []byte) error {
type OriginResponseAzureBlob struct {
// Unique identifier for the origin. This is generated by ImageKit when you create
// a new origin.
- ID string `json:"id,required"`
- AccountName string `json:"accountName,required"`
- Container string `json:"container,required"`
+ ID string `json:"id" api:"required"`
+ AccountName string `json:"accountName" api:"required"`
+ Container string `json:"container" api:"required"`
// Whether to send a Canonical header.
- IncludeCanonicalHeader bool `json:"includeCanonicalHeader,required"`
+ IncludeCanonicalHeader bool `json:"includeCanonicalHeader" api:"required"`
// Display name of the origin.
- Name string `json:"name,required"`
- Prefix string `json:"prefix,required"`
- Type constant.AzureBlob `json:"type,required"`
+ Name string `json:"name" api:"required"`
+ Prefix string `json:"prefix" api:"required"`
+ Type constant.AzureBlob `json:"type" default:"AZURE_BLOB"`
// URL used in the Canonical header (if enabled).
BaseURLForCanonicalHeader string `json:"baseUrlForCanonicalHeader" format:"uri"`
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
@@ -1039,14 +1039,14 @@ func (r *OriginResponseAzureBlob) UnmarshalJSON(data []byte) error {
type OriginResponseAkeneoPim struct {
// Unique identifier for the origin. This is generated by ImageKit when you create
// a new origin.
- ID string `json:"id,required"`
+ ID string `json:"id" api:"required"`
// Akeneo instance base URL.
- BaseURL string `json:"baseUrl,required" format:"uri"`
+ BaseURL string `json:"baseUrl" api:"required" format:"uri"`
// Whether to send a Canonical header.
- IncludeCanonicalHeader bool `json:"includeCanonicalHeader,required"`
+ IncludeCanonicalHeader bool `json:"includeCanonicalHeader" api:"required"`
// Display name of the origin.
- Name string `json:"name,required"`
- Type constant.AkeneoPim `json:"type,required"`
+ Name string `json:"name" api:"required"`
+ Type constant.AkeneoPim `json:"type" default:"AKENEO_PIM"`
// URL used in the Canonical header (if enabled).
BaseURLForCanonicalHeader string `json:"baseUrlForCanonicalHeader" format:"uri"`
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
@@ -1078,7 +1078,7 @@ func (r AccountOriginNewParams) MarshalJSON() (data []byte, err error) {
return shimjson.Marshal(r.OriginRequest)
}
func (r *AccountOriginNewParams) UnmarshalJSON(data []byte) error {
- return json.Unmarshal(data, &r.OriginRequest)
+ return apijson.UnmarshalRoot(data, r)
}
type AccountOriginUpdateParams struct {
@@ -1091,5 +1091,5 @@ func (r AccountOriginUpdateParams) MarshalJSON() (data []byte, err error) {
return shimjson.Marshal(r.OriginRequest)
}
func (r *AccountOriginUpdateParams) UnmarshalJSON(data []byte) error {
- return json.Unmarshal(data, &r.OriginRequest)
+ return apijson.UnmarshalRoot(data, r)
}
diff --git a/accountorigin_test.go b/accountorigin_test.go
index 350726b..3161145 100644
--- a/accountorigin_test.go
+++ b/accountorigin_test.go
@@ -14,7 +14,7 @@ import (
)
func TestAccountOriginNewWithOptionalParams(t *testing.T) {
- t.Skip("Prism tests are disabled")
+ t.Skip("Mock server tests are disabled")
baseURL := "http://localhost:4010"
if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok {
baseURL = envURL
@@ -50,7 +50,7 @@ func TestAccountOriginNewWithOptionalParams(t *testing.T) {
}
func TestAccountOriginUpdateWithOptionalParams(t *testing.T) {
- t.Skip("Prism tests are disabled")
+ t.Skip("Mock server tests are disabled")
baseURL := "http://localhost:4010"
if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok {
baseURL = envURL
@@ -90,7 +90,7 @@ func TestAccountOriginUpdateWithOptionalParams(t *testing.T) {
}
func TestAccountOriginList(t *testing.T) {
- t.Skip("Prism tests are disabled")
+ t.Skip("Mock server tests are disabled")
baseURL := "http://localhost:4010"
if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok {
baseURL = envURL
@@ -114,7 +114,7 @@ func TestAccountOriginList(t *testing.T) {
}
func TestAccountOriginDelete(t *testing.T) {
- t.Skip("Prism tests are disabled")
+ t.Skip("Mock server tests are disabled")
baseURL := "http://localhost:4010"
if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok {
baseURL = envURL
@@ -138,7 +138,7 @@ func TestAccountOriginDelete(t *testing.T) {
}
func TestAccountOriginGet(t *testing.T) {
- t.Skip("Prism tests are disabled")
+ t.Skip("Mock server tests are disabled")
baseURL := "http://localhost:4010"
if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok {
baseURL = envURL
diff --git a/accounturlendpoint.go b/accounturlendpoint.go
index dbd0224..35d40b7 100644
--- a/accounturlendpoint.go
+++ b/accounturlendpoint.go
@@ -44,7 +44,7 @@ func (r *AccountURLEndpointService) New(ctx context.Context, body AccountURLEndp
opts = slices.Concat(r.Options, opts)
path := "v1/accounts/url-endpoints"
err = requestconfig.ExecuteNewRequest(ctx, http.MethodPost, path, body, &res, opts...)
- return
+ return res, err
}
// **Note:** This API is currently in beta.
@@ -53,11 +53,11 @@ func (r *AccountURLEndpointService) Update(ctx context.Context, id string, body
opts = slices.Concat(r.Options, opts)
if id == "" {
err = errors.New("missing required id parameter")
- return
+ return nil, err
}
path := fmt.Sprintf("v1/accounts/url-endpoints/%s", id)
err = requestconfig.ExecuteNewRequest(ctx, http.MethodPut, path, body, &res, opts...)
- return
+ return res, err
}
// **Note:** This API is currently in beta.
@@ -67,7 +67,7 @@ func (r *AccountURLEndpointService) List(ctx context.Context, opts ...option.Req
opts = slices.Concat(r.Options, opts)
path := "v1/accounts/url-endpoints"
err = requestconfig.ExecuteNewRequest(ctx, http.MethodGet, path, nil, &res, opts...)
- return
+ return res, err
}
// **Note:** This API is currently in beta.
@@ -78,11 +78,11 @@ func (r *AccountURLEndpointService) Delete(ctx context.Context, id string, opts
opts = append([]option.RequestOption{option.WithHeader("Accept", "*/*")}, opts...)
if id == "" {
err = errors.New("missing required id parameter")
- return
+ return err
}
path := fmt.Sprintf("v1/accounts/url-endpoints/%s", id)
err = requestconfig.ExecuteNewRequest(ctx, http.MethodDelete, path, nil, nil, opts...)
- return
+ return err
}
// **Note:** This API is currently in beta.
@@ -91,11 +91,11 @@ func (r *AccountURLEndpointService) Get(ctx context.Context, id string, opts ...
opts = slices.Concat(r.Options, opts)
if id == "" {
err = errors.New("missing required id parameter")
- return
+ return nil, err
}
path := fmt.Sprintf("v1/accounts/url-endpoints/%s", id)
err = requestconfig.ExecuteNewRequest(ctx, http.MethodGet, path, nil, &res, opts...)
- return
+ return res, err
}
// Schema for URL endpoint resource.
@@ -103,7 +103,7 @@ func (r *AccountURLEndpointService) Get(ctx context.Context, id string, opts ...
// The property Description is required.
type URLEndpointRequestParam struct {
// Description of the URL endpoint.
- Description string `json:"description,required"`
+ Description string `json:"description" api:"required"`
// Path segment appended to your base URL to form the endpoint (letters, digits,
// and hyphens only — or empty for the default endpoint).
URLPrefix param.Opt[string] `json:"urlPrefix,omitzero"`
@@ -186,7 +186,7 @@ type URLEndpointRequestURLRewriterCloudinaryParam struct {
// Whether to preserve `/` in the rewritten URL.
PreserveAssetDeliveryTypes param.Opt[bool] `json:"preserveAssetDeliveryTypes,omitzero"`
// This field can be elided, and will marshal its zero value as "CLOUDINARY".
- Type constant.Cloudinary `json:"type,required"`
+ Type constant.Cloudinary `json:"type" default:"CLOUDINARY"`
paramObj
}
@@ -207,7 +207,7 @@ func NewURLEndpointRequestURLRewriterImgixParam() URLEndpointRequestURLRewriterI
// This struct has a constant value, construct it with
// [NewURLEndpointRequestURLRewriterImgixParam].
type URLEndpointRequestURLRewriterImgixParam struct {
- Type constant.Imgix `json:"type,required"`
+ Type constant.Imgix `json:"type" default:"IMGIX"`
paramObj
}
@@ -228,7 +228,7 @@ func NewURLEndpointRequestURLRewriterAkamaiParam() URLEndpointRequestURLRewriter
// This struct has a constant value, construct it with
// [NewURLEndpointRequestURLRewriterAkamaiParam].
type URLEndpointRequestURLRewriterAkamaiParam struct {
- Type constant.Akamai `json:"type,required"`
+ Type constant.Akamai `json:"type" default:"AKAMAI"`
paramObj
}
@@ -245,16 +245,16 @@ type URLEndpointResponse struct {
// Unique identifier for the URL-endpoint. This is generated by ImageKit when you
// create a new URL-endpoint. For the default URL-endpoint, this is always
// `default`.
- ID string `json:"id,required"`
+ ID string `json:"id" api:"required"`
// Description of the URL endpoint.
- Description string `json:"description,required"`
+ Description string `json:"description" api:"required"`
// Ordered list of origin IDs to try when the file isn’t in the Media Library;
// ImageKit checks them in the sequence provided. Origin must be created before it
// can be used in a URL endpoint.
- Origins []string `json:"origins,required"`
+ Origins []string `json:"origins" api:"required"`
// Path segment appended to your base URL to form the endpoint (letters, digits,
// and hyphens only — or empty for the default endpoint).
- URLPrefix string `json:"urlPrefix,required"`
+ URLPrefix string `json:"urlPrefix" api:"required"`
// Configuration for third-party URL rewriting.
URLRewriter URLEndpointResponseURLRewriterUnion `json:"urlRewriter"`
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
@@ -351,8 +351,8 @@ func (r *URLEndpointResponseURLRewriterUnion) UnmarshalJSON(data []byte) error {
type URLEndpointResponseURLRewriterCloudinary struct {
// Whether to preserve `/` in the rewritten URL.
- PreserveAssetDeliveryTypes bool `json:"preserveAssetDeliveryTypes,required"`
- Type constant.Cloudinary `json:"type,required"`
+ PreserveAssetDeliveryTypes bool `json:"preserveAssetDeliveryTypes" api:"required"`
+ Type constant.Cloudinary `json:"type" default:"CLOUDINARY"`
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
JSON struct {
PreserveAssetDeliveryTypes respjson.Field
@@ -369,7 +369,7 @@ func (r *URLEndpointResponseURLRewriterCloudinary) UnmarshalJSON(data []byte) er
}
type URLEndpointResponseURLRewriterImgix struct {
- Type constant.Imgix `json:"type,required"`
+ Type constant.Imgix `json:"type" default:"IMGIX"`
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
JSON struct {
Type respjson.Field
@@ -385,7 +385,7 @@ func (r *URLEndpointResponseURLRewriterImgix) UnmarshalJSON(data []byte) error {
}
type URLEndpointResponseURLRewriterAkamai struct {
- Type constant.Akamai `json:"type,required"`
+ Type constant.Akamai `json:"type" default:"AKAMAI"`
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
JSON struct {
Type respjson.Field
@@ -410,7 +410,7 @@ func (r AccountURLEndpointNewParams) MarshalJSON() (data []byte, err error) {
return shimjson.Marshal(r.URLEndpointRequest)
}
func (r *AccountURLEndpointNewParams) UnmarshalJSON(data []byte) error {
- return json.Unmarshal(data, &r.URLEndpointRequest)
+ return apijson.UnmarshalRoot(data, r)
}
type AccountURLEndpointUpdateParams struct {
@@ -423,5 +423,5 @@ func (r AccountURLEndpointUpdateParams) MarshalJSON() (data []byte, err error) {
return shimjson.Marshal(r.URLEndpointRequest)
}
func (r *AccountURLEndpointUpdateParams) UnmarshalJSON(data []byte) error {
- return json.Unmarshal(data, &r.URLEndpointRequest)
+ return apijson.UnmarshalRoot(data, r)
}
diff --git a/accounturlendpoint_test.go b/accounturlendpoint_test.go
index 06c9c66..716ef33 100644
--- a/accounturlendpoint_test.go
+++ b/accounturlendpoint_test.go
@@ -14,7 +14,7 @@ import (
)
func TestAccountURLEndpointNewWithOptionalParams(t *testing.T) {
- t.Skip("Prism tests are disabled")
+ t.Skip("Mock server tests are disabled")
baseURL := "http://localhost:4010"
if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok {
baseURL = envURL
@@ -49,7 +49,7 @@ func TestAccountURLEndpointNewWithOptionalParams(t *testing.T) {
}
func TestAccountURLEndpointUpdateWithOptionalParams(t *testing.T) {
- t.Skip("Prism tests are disabled")
+ t.Skip("Mock server tests are disabled")
baseURL := "http://localhost:4010"
if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok {
baseURL = envURL
@@ -88,7 +88,7 @@ func TestAccountURLEndpointUpdateWithOptionalParams(t *testing.T) {
}
func TestAccountURLEndpointList(t *testing.T) {
- t.Skip("Prism tests are disabled")
+ t.Skip("Mock server tests are disabled")
baseURL := "http://localhost:4010"
if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok {
baseURL = envURL
@@ -112,7 +112,7 @@ func TestAccountURLEndpointList(t *testing.T) {
}
func TestAccountURLEndpointDelete(t *testing.T) {
- t.Skip("Prism tests are disabled")
+ t.Skip("Mock server tests are disabled")
baseURL := "http://localhost:4010"
if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok {
baseURL = envURL
@@ -136,7 +136,7 @@ func TestAccountURLEndpointDelete(t *testing.T) {
}
func TestAccountURLEndpointGet(t *testing.T) {
- t.Skip("Prism tests are disabled")
+ t.Skip("Mock server tests are disabled")
baseURL := "http://localhost:4010"
if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok {
baseURL = envURL
diff --git a/accountusage.go b/accountusage.go
index dadef4a..9fea667 100644
--- a/accountusage.go
+++ b/accountusage.go
@@ -43,7 +43,7 @@ func (r *AccountUsageService) Get(ctx context.Context, query AccountUsageGetPara
opts = slices.Concat(r.Options, opts)
path := "v1/accounts/usage"
err = requestconfig.ExecuteNewRequest(ctx, http.MethodGet, path, query, &res, opts...)
- return
+ return res, err
}
type AccountUsageGetResponse struct {
@@ -78,10 +78,10 @@ func (r *AccountUsageGetResponse) UnmarshalJSON(data []byte) error {
type AccountUsageGetParams struct {
// Specify a `endDate` in `YYYY-MM-DD` format. It should be after the `startDate`.
// The difference between `startDate` and `endDate` should be less than 90 days.
- EndDate time.Time `query:"endDate,required" format:"date" json:"-"`
+ EndDate time.Time `query:"endDate" api:"required" format:"date" json:"-"`
// Specify a `startDate` in `YYYY-MM-DD` format. It should be before the `endDate`.
// The difference between `startDate` and `endDate` should be less than 90 days.
- StartDate time.Time `query:"startDate,required" format:"date" json:"-"`
+ StartDate time.Time `query:"startDate" api:"required" format:"date" json:"-"`
paramObj
}
diff --git a/accountusage_test.go b/accountusage_test.go
index a206f36..dcfd282 100644
--- a/accountusage_test.go
+++ b/accountusage_test.go
@@ -15,7 +15,7 @@ import (
)
func TestAccountUsageGet(t *testing.T) {
- t.Skip("Prism tests are disabled")
+ t.Skip("Mock server tests are disabled")
baseURL := "http://localhost:4010"
if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok {
baseURL = envURL
diff --git a/aliases.go b/aliases.go
index a960812..9368547 100644
--- a/aliases.go
+++ b/aliases.go
@@ -370,8 +370,43 @@ type OverlayUnionParam = shared.OverlayUnionParam
// This is an alias to an internal type.
type OverlayPositionParam = shared.OverlayPositionParam
-// Specifies the position of the overlay relative to the parent image or video.
-// Maps to `lfo` in the URL.
+// Sets the anchor point on the base asset from which the overlay offset is
+// calculated. The default value is `top_left`. Maps to `lap` in the URL. Can only
+// be used with one or more of `x`, `y`, `xCenter`, or `yCenter`.
+//
+// This is an alias to an internal type.
+type OverlayPositionAnchorPoint = shared.OverlayPositionAnchorPoint
+
+// Equals "top"
+const OverlayPositionAnchorPointTop = shared.OverlayPositionAnchorPointTop
+
+// Equals "left"
+const OverlayPositionAnchorPointLeft = shared.OverlayPositionAnchorPointLeft
+
+// Equals "right"
+const OverlayPositionAnchorPointRight = shared.OverlayPositionAnchorPointRight
+
+// Equals "bottom"
+const OverlayPositionAnchorPointBottom = shared.OverlayPositionAnchorPointBottom
+
+// Equals "top_left"
+const OverlayPositionAnchorPointTopLeft = shared.OverlayPositionAnchorPointTopLeft
+
+// Equals "top_right"
+const OverlayPositionAnchorPointTopRight = shared.OverlayPositionAnchorPointTopRight
+
+// Equals "bottom_left"
+const OverlayPositionAnchorPointBottomLeft = shared.OverlayPositionAnchorPointBottomLeft
+
+// Equals "bottom_right"
+const OverlayPositionAnchorPointBottomRight = shared.OverlayPositionAnchorPointBottomRight
+
+// Equals "center"
+const OverlayPositionAnchorPointCenter = shared.OverlayPositionAnchorPointCenter
+
+// Specifies the position of the overlay relative to the parent image or video. If
+// one or more of `x`, `y`, `xCenter`, or `yCenter` parameters are specified, this
+// parameter is ignored. Maps to `lfo` in the URL.
//
// This is an alias to an internal type.
type OverlayPositionFocus = shared.OverlayPositionFocus
@@ -412,6 +447,15 @@ const OverlayPositionFocusBottomRight = shared.OverlayPositionFocusBottomRight
// This is an alias to an internal type.
type OverlayPositionXUnionParam = shared.OverlayPositionXUnionParam
+// Specifies the x-coordinate on the base asset where the overlay's center will be
+// positioned. It also accepts arithmetic expressions such as `bw_mul_0.4` or
+// `bw_sub_cw`. Maps to `lxc` in the URL. Cannot be used together with `x`, but can
+// be used with `y`. Learn about
+// [Arithmetic expressions](https://imagekit.io/docs/arithmetic-expressions-in-transformations).
+//
+// This is an alias to an internal type.
+type OverlayPositionXCenterUnionParam = shared.OverlayPositionXCenterUnionParam
+
// Specifies the y-coordinate of the top-left corner of the base asset where the
// overlay's top-left corner will be positioned. It also accepts arithmetic
// expressions such as `bh_mul_0.4` or `bh_sub_ch`. Maps to `ly` in the URL. Learn
@@ -421,6 +465,15 @@ type OverlayPositionXUnionParam = shared.OverlayPositionXUnionParam
// This is an alias to an internal type.
type OverlayPositionYUnionParam = shared.OverlayPositionYUnionParam
+// Specifies the y-coordinate on the base asset where the overlay's center will be
+// positioned. It also accepts arithmetic expressions such as `bh_mul_0.4` or
+// `bh_sub_ch`. Maps to `lyc` in the URL. Cannot be used together with `y`, but can
+// be used with `x`. Learn about
+// [Arithmetic expressions](https://imagekit.io/docs/arithmetic-expressions-in-transformations).
+//
+// This is an alias to an internal type.
+type OverlayPositionYCenterUnionParam = shared.OverlayPositionYCenterUnionParam
+
// This is an alias to an internal type.
type OverlayTimingParam = shared.OverlayTimingParam
diff --git a/api.md b/api.md
index 30966e3..ef24b6d 100644
--- a/api.md
+++ b/api.md
@@ -26,6 +26,8 @@
- shared.ExtensionConfigUnion
- shared.SavedExtension
+- shared.StreamingResolution
+- shared.TransformationPosition
# CustomMetadataFields
diff --git a/asset.go b/asset.go
index ff95c4e..e5deffb 100644
--- a/asset.go
+++ b/asset.go
@@ -45,7 +45,7 @@ func (r *AssetService) List(ctx context.Context, query AssetListParams, opts ...
opts = slices.Concat(r.Options, opts)
path := "v1/files"
err = requestconfig.ExecuteNewRequest(ctx, http.MethodGet, path, query, &res, opts...)
- return
+ return res, err
}
// AssetListResponseUnion contains all possible properties and values from [File],
diff --git a/asset_test.go b/asset_test.go
index d479ff3..f1fd203 100644
--- a/asset_test.go
+++ b/asset_test.go
@@ -14,7 +14,7 @@ import (
)
func TestAssetListWithOptionalParams(t *testing.T) {
- t.Skip("Prism tests are disabled")
+ t.Skip("Mock server tests are disabled")
baseURL := "http://localhost:4010"
if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok {
baseURL = envURL
diff --git a/betav2file.go b/betav2file.go
index 5417572..293eeed 100644
--- a/betav2file.go
+++ b/betav2file.go
@@ -53,10 +53,11 @@ func NewBetaV2FileService(opts ...option.RequestOption) (r BetaV2FileService) {
// about how to implement secure client-side file upload.
//
// **File size limit** \
-// On the free plan, the maximum upload file sizes are 20MB for images, audio, and raw
-// files, and 100MB for videos. On the paid plan, these limits increase to 40MB for
-// images, audio, and raw files, and 2GB for videos. These limits can be further increased
-// with higher-tier plans.
+// On the free plan, the maximum upload file sizes are 25MB for images, audio, and raw
+// files, and 100MB for videos. On the Lite paid plan, these limits increase to 40MB
+// for images, audio, and raw files and 300MB for videos, whereas on the Pro paid plan,
+// these limits increase to 50MB for images, audio, and raw files and 2GB for videos.
+// These limits can be further increased with enterprise plans.
//
// **Version limit** \
// A file can have a maximum of 100 versions.
@@ -74,13 +75,13 @@ func (r *BetaV2FileService) Upload(ctx context.Context, body BetaV2FileUploadPar
opts = append([]option.RequestOption{option.WithBaseURL("https://upload.imagekit.io/")}, opts...)
path := "api/v2/files/upload"
err = requestconfig.ExecuteNewRequest(ctx, http.MethodPost, path, body, &res, opts...)
- return
+ return res, err
}
// Object containing details of a successful upload.
type BetaV2FileUploadResponse struct {
// An array of tags assigned to the uploaded file by auto tagging.
- AITags []BetaV2FileUploadResponseAITag `json:"AITags,nullable"`
+ AITags []BetaV2FileUploadResponseAITag `json:"AITags" api:"nullable"`
// The audio codec used in the video (only for video).
AudioCodec string `json:"audioCodec"`
// The bit rate of the video in kbps (only for video).
@@ -89,7 +90,7 @@ type BetaV2FileUploadResponse struct {
// `x,y,width,height`. If `customCoordinates` are not defined, then it is `null`.
// Send `customCoordinates` in `responseFields` in API request to get the value of
// this field.
- CustomCoordinates string `json:"customCoordinates,nullable"`
+ CustomCoordinates string `json:"customCoordinates" api:"nullable"`
// A key-value data associated with the asset. Use `responseField` in API request
// to get `customMetadata` in the upload API response. Before setting any custom
// metadata on an asset, you have to create the field using custom metadata fields
@@ -151,7 +152,7 @@ type BetaV2FileUploadResponse struct {
// The array of tags associated with the asset. If no tags are set, it will be
// `null`. Send `tags` in `responseFields` in API request to get the value of this
// field.
- Tags []string `json:"tags,nullable"`
+ Tags []string `json:"tags" api:"nullable"`
// In the case of an image, a small thumbnail URL.
ThumbnailURL string `json:"thumbnailUrl"`
// A publicly accessible URL of the file.
@@ -268,7 +269,7 @@ type BetaV2FileUploadResponseSelectedFieldsSchema struct {
//
// Any of "Text", "Textarea", "Number", "Date", "Boolean", "SingleSelect",
// "MultiSelect".
- Type string `json:"type,required"`
+ Type string `json:"type" api:"required"`
// The default value for this custom metadata field. The value should match the
// `type` of custom metadata field.
DefaultValue BetaV2FileUploadResponseSelectedFieldsSchemaDefaultValueUnion `json:"defaultValue"`
@@ -569,7 +570,7 @@ type BetaV2FileUploadParams struct {
// *bytes.Reader, *bytes.Buffer, *strings.Reader, or any stream).
File io.Reader `json:"file,omitzero,required" format:"binary"`
// The name with which the file has to be uploaded.
- FileName string `json:"fileName,required"`
+ FileName string `json:"fileName" api:"required"`
// This is the client-generated JSON Web Token (JWT). The ImageKit.io server uses
// it to authenticate and check that the upload request parameters have not been
// tampered with after the token has been generated. Learn how to create the token
@@ -880,11 +881,11 @@ func init() {
type BetaV2FileUploadParamsTransformationPostTransformation struct {
// Transformation string (e.g. `w-200,h-200`).
// Same syntax as ImageKit URL-based transformations.
- Value string `json:"value,required"`
+ Value string `json:"value" api:"required"`
// Transformation type.
//
// This field can be elided, and will marshal its zero value as "transformation".
- Type constant.Transformation `json:"type,required"`
+ Type constant.Transformation `json:"type" default:"transformation"`
paramObj
}
@@ -904,7 +905,7 @@ type BetaV2FileUploadParamsTransformationPostGifToVideo struct {
// Converts an animated GIF into an MP4.
//
// This field can be elided, and will marshal its zero value as "gif-to-video".
- Type constant.GifToVideo `json:"type,required"`
+ Type constant.GifToVideo `json:"type" default:"gif-to-video"`
paramObj
}
@@ -924,7 +925,7 @@ type BetaV2FileUploadParamsTransformationPostThumbnail struct {
// Generates a thumbnail image.
//
// This field can be elided, and will marshal its zero value as "thumbnail".
- Type constant.Thumbnail `json:"type,required"`
+ Type constant.Thumbnail `json:"type" default:"thumbnail"`
paramObj
}
@@ -941,13 +942,13 @@ type BetaV2FileUploadParamsTransformationPostAbs struct {
// Streaming protocol to use (`hls` or `dash`).
//
// Any of "hls", "dash".
- Protocol string `json:"protocol,omitzero,required"`
+ Protocol string `json:"protocol,omitzero" api:"required"`
// List of different representations you want to create separated by an underscore.
- Value string `json:"value,required"`
+ Value string `json:"value" api:"required"`
// Adaptive Bitrate Streaming (ABS) setup.
//
// This field can be elided, and will marshal its zero value as "abs".
- Type constant.Abs `json:"type,required"`
+ Type constant.Abs `json:"type" default:"abs"`
paramObj
}
diff --git a/betav2file_test.go b/betav2file_test.go
index 8f52587..45edf51 100644
--- a/betav2file_test.go
+++ b/betav2file_test.go
@@ -17,7 +17,7 @@ import (
)
func TestBetaV2FileUploadWithOptionalParams(t *testing.T) {
- t.Skip("Prism tests are disabled")
+ t.Skip("Mock server tests are disabled")
baseURL := "http://localhost:4010"
if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok {
baseURL = envURL
@@ -31,7 +31,7 @@ func TestBetaV2FileUploadWithOptionalParams(t *testing.T) {
option.WithPassword("My Password"),
)
_, err := client.Beta.V2.Files.Upload(context.TODO(), imagekit.BetaV2FileUploadParams{
- File: io.Reader(bytes.NewBuffer([]byte("some file contents"))),
+ File: io.Reader(bytes.NewBuffer([]byte("Example data"))),
FileName: "fileName",
Token: imagekit.String("token"),
Checks: imagekit.String("\"request.folder\" : \"marketing/\"\n"),
diff --git a/cacheinvalidation.go b/cacheinvalidation.go
index 8e24626..524c80c 100644
--- a/cacheinvalidation.go
+++ b/cacheinvalidation.go
@@ -42,7 +42,7 @@ func (r *CacheInvalidationService) New(ctx context.Context, body CacheInvalidati
opts = slices.Concat(r.Options, opts)
path := "v1/files/purge"
err = requestconfig.ExecuteNewRequest(ctx, http.MethodPost, path, body, &res, opts...)
- return
+ return res, err
}
// This API returns the status of a purge cache request.
@@ -50,11 +50,11 @@ func (r *CacheInvalidationService) Get(ctx context.Context, requestID string, op
opts = slices.Concat(r.Options, opts)
if requestID == "" {
err = errors.New("missing required requestId parameter")
- return
+ return nil, err
}
path := fmt.Sprintf("v1/files/purge/%s", requestID)
err = requestconfig.ExecuteNewRequest(ctx, http.MethodGet, path, nil, &res, opts...)
- return
+ return res, err
}
type CacheInvalidationNewResponse struct {
@@ -104,7 +104,7 @@ const (
type CacheInvalidationNewParams struct {
// The full URL of the file to be purged.
- URL string `json:"url,required" format:"uri"`
+ URL string `json:"url" api:"required" format:"uri"`
paramObj
}
diff --git a/cacheinvalidation_test.go b/cacheinvalidation_test.go
index 2e12514..ac4ecc1 100644
--- a/cacheinvalidation_test.go
+++ b/cacheinvalidation_test.go
@@ -14,7 +14,7 @@ import (
)
func TestCacheInvalidationNew(t *testing.T) {
- t.Skip("Prism tests are disabled")
+ t.Skip("Mock server tests are disabled")
baseURL := "http://localhost:4010"
if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok {
baseURL = envURL
@@ -40,7 +40,7 @@ func TestCacheInvalidationNew(t *testing.T) {
}
func TestCacheInvalidationGet(t *testing.T) {
- t.Skip("Prism tests are disabled")
+ t.Skip("Mock server tests are disabled")
baseURL := "http://localhost:4010"
if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok {
baseURL = envURL
diff --git a/client_test.go b/client_test.go
index 1392578..9f7e535 100644
--- a/client_test.go
+++ b/client_test.go
@@ -41,7 +41,7 @@ func TestUserAgentHeader(t *testing.T) {
},
}),
)
- client.Files.Upload(context.Background(), imagekit.FileUploadParams{
+ _, _ = client.Files.Upload(context.Background(), imagekit.FileUploadParams{
File: io.Reader(bytes.NewBuffer([]byte("https://www.example.com/public-url.jpg"))),
FileName: "file-name.jpg",
})
diff --git a/custommetadatafield.go b/custommetadatafield.go
index eb701f8..964eba4 100644
--- a/custommetadatafield.go
+++ b/custommetadatafield.go
@@ -46,7 +46,7 @@ func (r *CustomMetadataFieldService) New(ctx context.Context, body CustomMetadat
opts = slices.Concat(r.Options, opts)
path := "v1/customMetadataFields"
err = requestconfig.ExecuteNewRequest(ctx, http.MethodPost, path, body, &res, opts...)
- return
+ return res, err
}
// This API updates the label or schema of an existing custom metadata field.
@@ -54,11 +54,11 @@ func (r *CustomMetadataFieldService) Update(ctx context.Context, id string, body
opts = slices.Concat(r.Options, opts)
if id == "" {
err = errors.New("missing required id parameter")
- return
+ return nil, err
}
path := fmt.Sprintf("v1/customMetadataFields/%s", id)
err = requestconfig.ExecuteNewRequest(ctx, http.MethodPatch, path, body, &res, opts...)
- return
+ return res, err
}
// This API returns the array of created custom metadata field objects. By default
@@ -73,7 +73,7 @@ func (r *CustomMetadataFieldService) List(ctx context.Context, query CustomMetad
opts = slices.Concat(r.Options, opts)
path := "v1/customMetadataFields"
err = requestconfig.ExecuteNewRequest(ctx, http.MethodGet, path, query, &res, opts...)
- return
+ return res, err
}
// This API deletes a custom metadata field. Even after deleting a custom metadata
@@ -82,26 +82,26 @@ func (r *CustomMetadataFieldService) Delete(ctx context.Context, id string, opts
opts = slices.Concat(r.Options, opts)
if id == "" {
err = errors.New("missing required id parameter")
- return
+ return nil, err
}
path := fmt.Sprintf("v1/customMetadataFields/%s", id)
err = requestconfig.ExecuteNewRequest(ctx, http.MethodDelete, path, nil, &res, opts...)
- return
+ return res, err
}
// Object containing details of a custom metadata field.
type CustomMetadataField struct {
// Unique identifier for the custom metadata field. Use this to update the field.
- ID string `json:"id,required"`
+ ID string `json:"id" api:"required"`
// Human readable name of the custom metadata field. This name is displayed as form
// field label to the users while setting field value on the asset in the media
// library UI.
- Label string `json:"label,required"`
+ Label string `json:"label" api:"required"`
// API name of the custom metadata field. This becomes the key while setting
// `customMetadata` (key-value object) for an asset using upload or update API.
- Name string `json:"name,required"`
+ Name string `json:"name" api:"required"`
// An object that describes the rules for the custom metadata field value.
- Schema CustomMetadataFieldSchema `json:"schema,required"`
+ Schema CustomMetadataFieldSchema `json:"schema" api:"required"`
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
JSON struct {
ID respjson.Field
@@ -125,7 +125,7 @@ type CustomMetadataFieldSchema struct {
//
// Any of "Text", "Textarea", "Number", "Date", "Boolean", "SingleSelect",
// "MultiSelect".
- Type string `json:"type,required"`
+ Type string `json:"type" api:"required"`
// The default value for this custom metadata field. Data type of default value
// depends on the field type.
DefaultValue CustomMetadataFieldSchemaDefaultValueUnion `json:"defaultValue"`
@@ -399,11 +399,11 @@ type CustomMetadataFieldNewParams struct {
// all non deleted custom metadata fields. This name is displayed as form field
// label to the users while setting field value on an asset in the media library
// UI.
- Label string `json:"label,required"`
+ Label string `json:"label" api:"required"`
// API name of the custom metadata field. This should be unique across all
// (including deleted) custom metadata fields.
- Name string `json:"name,required"`
- Schema CustomMetadataFieldNewParamsSchema `json:"schema,omitzero,required"`
+ Name string `json:"name" api:"required"`
+ Schema CustomMetadataFieldNewParamsSchema `json:"schema,omitzero" api:"required"`
paramObj
}
@@ -421,7 +421,7 @@ type CustomMetadataFieldNewParamsSchema struct {
//
// Any of "Text", "Textarea", "Number", "Date", "Boolean", "SingleSelect",
// "MultiSelect".
- Type string `json:"type,omitzero,required"`
+ Type string `json:"type,omitzero" api:"required"`
// Sets this custom metadata field as required. Setting custom metadata fields on
// an asset will throw error if the value for all required fields are not present
// in upload or update asset API request body.
diff --git a/custommetadatafield_test.go b/custommetadatafield_test.go
index c3cb073..ca9bbbc 100644
--- a/custommetadatafield_test.go
+++ b/custommetadatafield_test.go
@@ -14,7 +14,7 @@ import (
)
func TestCustomMetadataFieldNewWithOptionalParams(t *testing.T) {
- t.Skip("Prism tests are disabled")
+ t.Skip("Mock server tests are disabled")
baseURL := "http://localhost:4010"
if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok {
baseURL = envURL
@@ -69,7 +69,7 @@ func TestCustomMetadataFieldNewWithOptionalParams(t *testing.T) {
}
func TestCustomMetadataFieldUpdateWithOptionalParams(t *testing.T) {
- t.Skip("Prism tests are disabled")
+ t.Skip("Mock server tests are disabled")
baseURL := "http://localhost:4010"
if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok {
baseURL = envURL
@@ -126,7 +126,7 @@ func TestCustomMetadataFieldUpdateWithOptionalParams(t *testing.T) {
}
func TestCustomMetadataFieldListWithOptionalParams(t *testing.T) {
- t.Skip("Prism tests are disabled")
+ t.Skip("Mock server tests are disabled")
baseURL := "http://localhost:4010"
if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok {
baseURL = envURL
@@ -153,7 +153,7 @@ func TestCustomMetadataFieldListWithOptionalParams(t *testing.T) {
}
func TestCustomMetadataFieldDelete(t *testing.T) {
- t.Skip("Prism tests are disabled")
+ t.Skip("Mock server tests are disabled")
baseURL := "http://localhost:4010"
if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok {
baseURL = envURL
diff --git a/dummy.go b/dummy.go
index 5af366d..1391d11 100644
--- a/dummy.go
+++ b/dummy.go
@@ -41,7 +41,7 @@ func (r *DummyService) New(ctx context.Context, body DummyNewParams, opts ...opt
opts = append([]option.RequestOption{option.WithHeader("Accept", "*/*")}, opts...)
path := "v1/dummy/test"
err = requestconfig.ExecuteNewRequest(ctx, http.MethodPost, path, body, nil, opts...)
- return
+ return err
}
type DummyNewParams struct {
diff --git a/dummy_test.go b/dummy_test.go
index 2ffd02b..95c415e 100644
--- a/dummy_test.go
+++ b/dummy_test.go
@@ -16,7 +16,7 @@ import (
)
func TestDummyNewWithOptionalParams(t *testing.T) {
- t.Skip("Prism tests are disabled")
+ t.Skip("Mock server tests are disabled")
baseURL := "http://localhost:4010"
if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok {
baseURL = envURL
@@ -33,13 +33,20 @@ func TestDummyNewWithOptionalParams(t *testing.T) {
BaseOverlay: shared.BaseOverlayParam{
LayerMode: shared.BaseOverlayLayerModeMultiply,
Position: shared.OverlayPositionParam{
- Focus: shared.OverlayPositionFocusCenter,
+ AnchorPoint: shared.OverlayPositionAnchorPointTop,
+ Focus: shared.OverlayPositionFocusCenter,
X: shared.OverlayPositionXUnionParam{
OfFloat: imagekit.Float(0),
},
+ XCenter: shared.OverlayPositionXCenterUnionParam{
+ OfFloat: imagekit.Float(0),
+ },
Y: shared.OverlayPositionYUnionParam{
OfFloat: imagekit.Float(0),
},
+ YCenter: shared.OverlayPositionYCenterUnionParam{
+ OfFloat: imagekit.Float(0),
+ },
},
Timing: shared.OverlayTimingParam{
Duration: shared.OverlayTimingDurationUnionParam{
@@ -200,13 +207,20 @@ func TestDummyNewWithOptionalParams(t *testing.T) {
BaseOverlayParam: shared.BaseOverlayParam{
LayerMode: shared.BaseOverlayLayerModeMultiply,
Position: shared.OverlayPositionParam{
- Focus: shared.OverlayPositionFocusCenter,
+ AnchorPoint: shared.OverlayPositionAnchorPointTop,
+ Focus: shared.OverlayPositionFocusCenter,
X: shared.OverlayPositionXUnionParam{
OfFloat: imagekit.Float(0),
},
+ XCenter: shared.OverlayPositionXCenterUnionParam{
+ OfFloat: imagekit.Float(0),
+ },
Y: shared.OverlayPositionYUnionParam{
OfFloat: imagekit.Float(0),
},
+ YCenter: shared.OverlayPositionYCenterUnionParam{
+ OfFloat: imagekit.Float(0),
+ },
},
Timing: shared.OverlayTimingParam{
Duration: shared.OverlayTimingDurationUnionParam{
@@ -308,13 +322,20 @@ func TestDummyNewWithOptionalParams(t *testing.T) {
BaseOverlayParam: shared.BaseOverlayParam{
LayerMode: shared.BaseOverlayLayerModeMultiply,
Position: shared.OverlayPositionParam{
- Focus: shared.OverlayPositionFocusCenter,
+ AnchorPoint: shared.OverlayPositionAnchorPointTop,
+ Focus: shared.OverlayPositionFocusCenter,
X: shared.OverlayPositionXUnionParam{
OfFloat: imagekit.Float(0),
},
+ XCenter: shared.OverlayPositionXCenterUnionParam{
+ OfFloat: imagekit.Float(0),
+ },
Y: shared.OverlayPositionYUnionParam{
OfFloat: imagekit.Float(0),
},
+ YCenter: shared.OverlayPositionYCenterUnionParam{
+ OfFloat: imagekit.Float(0),
+ },
},
Timing: shared.OverlayTimingParam{
Duration: shared.OverlayTimingDurationUnionParam{
@@ -382,13 +403,20 @@ func TestDummyNewWithOptionalParams(t *testing.T) {
BaseOverlayParam: shared.BaseOverlayParam{
LayerMode: shared.BaseOverlayLayerModeMultiply,
Position: shared.OverlayPositionParam{
- Focus: shared.OverlayPositionFocusCenter,
+ AnchorPoint: shared.OverlayPositionAnchorPointTop,
+ Focus: shared.OverlayPositionFocusCenter,
X: shared.OverlayPositionXUnionParam{
OfFloat: imagekit.Float(0),
},
+ XCenter: shared.OverlayPositionXCenterUnionParam{
+ OfFloat: imagekit.Float(0),
+ },
Y: shared.OverlayPositionYUnionParam{
OfFloat: imagekit.Float(0),
},
+ YCenter: shared.OverlayPositionYCenterUnionParam{
+ OfFloat: imagekit.Float(0),
+ },
},
Timing: shared.OverlayTimingParam{
Duration: shared.OverlayTimingDurationUnionParam{
@@ -485,13 +513,20 @@ func TestDummyNewWithOptionalParams(t *testing.T) {
BaseOverlayParam: shared.BaseOverlayParam{
LayerMode: shared.BaseOverlayLayerModeMultiply,
Position: shared.OverlayPositionParam{
- Focus: shared.OverlayPositionFocusCenter,
+ AnchorPoint: shared.OverlayPositionAnchorPointTop,
+ Focus: shared.OverlayPositionFocusCenter,
X: shared.OverlayPositionXUnionParam{
OfFloat: imagekit.Float(0),
},
+ XCenter: shared.OverlayPositionXCenterUnionParam{
+ OfFloat: imagekit.Float(0),
+ },
Y: shared.OverlayPositionYUnionParam{
OfFloat: imagekit.Float(0),
},
+ YCenter: shared.OverlayPositionYCenterUnionParam{
+ OfFloat: imagekit.Float(0),
+ },
},
Timing: shared.OverlayTimingParam{
Duration: shared.OverlayTimingDurationUnionParam{
@@ -537,13 +572,20 @@ func TestDummyNewWithOptionalParams(t *testing.T) {
},
},
OverlayPosition: shared.OverlayPositionParam{
- Focus: shared.OverlayPositionFocusCenter,
+ AnchorPoint: shared.OverlayPositionAnchorPointTop,
+ Focus: shared.OverlayPositionFocusCenter,
X: shared.OverlayPositionXUnionParam{
OfFloat: imagekit.Float(0),
},
+ XCenter: shared.OverlayPositionXCenterUnionParam{
+ OfFloat: imagekit.Float(0),
+ },
Y: shared.OverlayPositionYUnionParam{
OfFloat: imagekit.Float(0),
},
+ YCenter: shared.OverlayPositionYCenterUnionParam{
+ OfFloat: imagekit.Float(0),
+ },
},
OverlayTiming: shared.OverlayTimingParam{
Duration: shared.OverlayTimingDurationUnionParam{
@@ -583,13 +625,20 @@ func TestDummyNewWithOptionalParams(t *testing.T) {
BaseOverlayParam: shared.BaseOverlayParam{
LayerMode: shared.BaseOverlayLayerModeMultiply,
Position: shared.OverlayPositionParam{
- Focus: shared.OverlayPositionFocusCenter,
+ AnchorPoint: shared.OverlayPositionAnchorPointTop,
+ Focus: shared.OverlayPositionFocusCenter,
X: shared.OverlayPositionXUnionParam{
OfFloat: imagekit.Float(0),
},
+ XCenter: shared.OverlayPositionXCenterUnionParam{
+ OfFloat: imagekit.Float(0),
+ },
Y: shared.OverlayPositionYUnionParam{
OfFloat: imagekit.Float(0),
},
+ YCenter: shared.OverlayPositionYCenterUnionParam{
+ OfFloat: imagekit.Float(0),
+ },
},
Timing: shared.OverlayTimingParam{
Duration: shared.OverlayTimingDurationUnionParam{
@@ -697,13 +746,20 @@ func TestDummyNewWithOptionalParams(t *testing.T) {
BaseOverlayParam: shared.BaseOverlayParam{
LayerMode: shared.BaseOverlayLayerModeMultiply,
Position: shared.OverlayPositionParam{
- Focus: shared.OverlayPositionFocusCenter,
+ AnchorPoint: shared.OverlayPositionAnchorPointTop,
+ Focus: shared.OverlayPositionFocusCenter,
X: shared.OverlayPositionXUnionParam{
OfFloat: imagekit.Float(0),
},
+ XCenter: shared.OverlayPositionXCenterUnionParam{
+ OfFloat: imagekit.Float(0),
+ },
Y: shared.OverlayPositionYUnionParam{
OfFloat: imagekit.Float(0),
},
+ YCenter: shared.OverlayPositionYCenterUnionParam{
+ OfFloat: imagekit.Float(0),
+ },
},
Timing: shared.OverlayTimingParam{
Duration: shared.OverlayTimingDurationUnionParam{
@@ -801,13 +857,20 @@ func TestDummyNewWithOptionalParams(t *testing.T) {
BaseOverlayParam: shared.BaseOverlayParam{
LayerMode: shared.BaseOverlayLayerModeMultiply,
Position: shared.OverlayPositionParam{
- Focus: shared.OverlayPositionFocusCenter,
+ AnchorPoint: shared.OverlayPositionAnchorPointTop,
+ Focus: shared.OverlayPositionFocusCenter,
X: shared.OverlayPositionXUnionParam{
OfFloat: imagekit.Float(0),
},
+ XCenter: shared.OverlayPositionXCenterUnionParam{
+ OfFloat: imagekit.Float(0),
+ },
Y: shared.OverlayPositionYUnionParam{
OfFloat: imagekit.Float(0),
},
+ YCenter: shared.OverlayPositionYCenterUnionParam{
+ OfFloat: imagekit.Float(0),
+ },
},
Timing: shared.OverlayTimingParam{
Duration: shared.OverlayTimingDurationUnionParam{
@@ -846,13 +909,20 @@ func TestDummyNewWithOptionalParams(t *testing.T) {
BaseOverlayParam: shared.BaseOverlayParam{
LayerMode: shared.BaseOverlayLayerModeMultiply,
Position: shared.OverlayPositionParam{
- Focus: shared.OverlayPositionFocusCenter,
+ AnchorPoint: shared.OverlayPositionAnchorPointTop,
+ Focus: shared.OverlayPositionFocusCenter,
X: shared.OverlayPositionXUnionParam{
OfFloat: imagekit.Float(0),
},
+ XCenter: shared.OverlayPositionXCenterUnionParam{
+ OfFloat: imagekit.Float(0),
+ },
Y: shared.OverlayPositionYUnionParam{
OfFloat: imagekit.Float(0),
},
+ YCenter: shared.OverlayPositionYCenterUnionParam{
+ OfFloat: imagekit.Float(0),
+ },
},
Timing: shared.OverlayTimingParam{
Duration: shared.OverlayTimingDurationUnionParam{
@@ -975,13 +1045,20 @@ func TestDummyNewWithOptionalParams(t *testing.T) {
BaseOverlayParam: shared.BaseOverlayParam{
LayerMode: shared.BaseOverlayLayerModeMultiply,
Position: shared.OverlayPositionParam{
- Focus: shared.OverlayPositionFocusCenter,
+ AnchorPoint: shared.OverlayPositionAnchorPointTop,
+ Focus: shared.OverlayPositionFocusCenter,
X: shared.OverlayPositionXUnionParam{
OfFloat: imagekit.Float(0),
},
+ XCenter: shared.OverlayPositionXCenterUnionParam{
+ OfFloat: imagekit.Float(0),
+ },
Y: shared.OverlayPositionYUnionParam{
OfFloat: imagekit.Float(0),
},
+ YCenter: shared.OverlayPositionYCenterUnionParam{
+ OfFloat: imagekit.Float(0),
+ },
},
Timing: shared.OverlayTimingParam{
Duration: shared.OverlayTimingDurationUnionParam{
@@ -1077,13 +1154,20 @@ func TestDummyNewWithOptionalParams(t *testing.T) {
BaseOverlayParam: shared.BaseOverlayParam{
LayerMode: shared.BaseOverlayLayerModeMultiply,
Position: shared.OverlayPositionParam{
- Focus: shared.OverlayPositionFocusCenter,
+ AnchorPoint: shared.OverlayPositionAnchorPointTop,
+ Focus: shared.OverlayPositionFocusCenter,
X: shared.OverlayPositionXUnionParam{
OfFloat: imagekit.Float(0),
},
+ XCenter: shared.OverlayPositionXCenterUnionParam{
+ OfFloat: imagekit.Float(0),
+ },
Y: shared.OverlayPositionYUnionParam{
OfFloat: imagekit.Float(0),
},
+ YCenter: shared.OverlayPositionYCenterUnionParam{
+ OfFloat: imagekit.Float(0),
+ },
},
Timing: shared.OverlayTimingParam{
Duration: shared.OverlayTimingDurationUnionParam{
@@ -1151,13 +1235,20 @@ func TestDummyNewWithOptionalParams(t *testing.T) {
BaseOverlayParam: shared.BaseOverlayParam{
LayerMode: shared.BaseOverlayLayerModeMultiply,
Position: shared.OverlayPositionParam{
- Focus: shared.OverlayPositionFocusCenter,
+ AnchorPoint: shared.OverlayPositionAnchorPointTop,
+ Focus: shared.OverlayPositionFocusCenter,
X: shared.OverlayPositionXUnionParam{
OfFloat: imagekit.Float(0),
},
+ XCenter: shared.OverlayPositionXCenterUnionParam{
+ OfFloat: imagekit.Float(0),
+ },
Y: shared.OverlayPositionYUnionParam{
OfFloat: imagekit.Float(0),
},
+ YCenter: shared.OverlayPositionYCenterUnionParam{
+ OfFloat: imagekit.Float(0),
+ },
},
Timing: shared.OverlayTimingParam{
Duration: shared.OverlayTimingDurationUnionParam{
diff --git a/file.go b/file.go
index bbd0f90..71d4826 100644
--- a/file.go
+++ b/file.go
@@ -58,11 +58,11 @@ func (r *FileService) Update(ctx context.Context, fileID string, body FileUpdate
opts = slices.Concat(r.Options, opts)
if fileID == "" {
err = errors.New("missing required fileId parameter")
- return
+ return nil, err
}
path := fmt.Sprintf("v1/files/%s/details", fileID)
err = requestconfig.ExecuteNewRequest(ctx, http.MethodPatch, path, body, &res, opts...)
- return
+ return res, err
}
// This API deletes the file and all its file versions permanently.
@@ -75,11 +75,11 @@ func (r *FileService) Delete(ctx context.Context, fileID string, opts ...option.
opts = append([]option.RequestOption{option.WithHeader("Accept", "*/*")}, opts...)
if fileID == "" {
err = errors.New("missing required fileId parameter")
- return
+ return err
}
path := fmt.Sprintf("v1/files/%s", fileID)
err = requestconfig.ExecuteNewRequest(ctx, http.MethodDelete, path, nil, nil, opts...)
- return
+ return err
}
// This will copy a file from one folder to another.
@@ -91,7 +91,7 @@ func (r *FileService) Copy(ctx context.Context, body FileCopyParams, opts ...opt
opts = slices.Concat(r.Options, opts)
path := "v1/files/copy"
err = requestconfig.ExecuteNewRequest(ctx, http.MethodPost, path, body, &res, opts...)
- return
+ return res, err
}
// This API returns an object with details or attributes about the current version
@@ -100,11 +100,11 @@ func (r *FileService) Get(ctx context.Context, fileID string, opts ...option.Req
opts = slices.Concat(r.Options, opts)
if fileID == "" {
err = errors.New("missing required fileId parameter")
- return
+ return nil, err
}
path := fmt.Sprintf("v1/files/%s/details", fileID)
err = requestconfig.ExecuteNewRequest(ctx, http.MethodGet, path, nil, &res, opts...)
- return
+ return res, err
}
// This will move a file and all its versions from one folder to another.
@@ -115,7 +115,7 @@ func (r *FileService) Move(ctx context.Context, body FileMoveParams, opts ...opt
opts = slices.Concat(r.Options, opts)
path := "v1/files/move"
err = requestconfig.ExecuteNewRequest(ctx, http.MethodPost, path, body, &res, opts...)
- return
+ return res, err
}
// You can rename an already existing file in the media library using rename file
@@ -127,7 +127,7 @@ func (r *FileService) Rename(ctx context.Context, body FileRenameParams, opts ..
opts = slices.Concat(r.Options, opts)
path := "v1/files/rename"
err = requestconfig.ExecuteNewRequest(ctx, http.MethodPut, path, body, &res, opts...)
- return
+ return res, err
}
// ImageKit.io allows you to upload files directly from both the server and client
@@ -141,10 +141,11 @@ func (r *FileService) Rename(ctx context.Context, body FileRenameParams, opts ..
// by verifying the entire payload using JWT.
//
// **File size limit** \
-// On the free plan, the maximum upload file sizes are 20MB for images, audio, and raw
-// files and 100MB for videos. On the paid plan, these limits increase to 40MB for images,
-// audio, and raw files and 2GB for videos. These limits can be further increased with
-// higher-tier plans.
+// On the free plan, the maximum upload file sizes are 25MB for images, audio, and raw
+// files and 100MB for videos. On the Lite paid plan, these limits increase to 40MB
+// for images, audio, and raw files and 300MB for videos, whereas on the Pro paid plan,
+// these limits increase to 50MB for images, audio, and raw files and 2GB for videos.
+// These limits can be further increased with enterprise plans.
//
// **Version limit** \
// A file can have a maximum of 100 versions.
@@ -162,13 +163,13 @@ func (r *FileService) Upload(ctx context.Context, body FileUploadParams, opts ..
opts = append([]option.RequestOption{option.WithBaseURL("https://upload.imagekit.io/")}, opts...)
path := "api/v1/files/upload"
err = requestconfig.ExecuteNewRequest(ctx, http.MethodPost, path, body, &res, opts...)
- return
+ return res, err
}
// Object containing details of a file or file version.
type File struct {
// An array of tags assigned to the file by auto tagging.
- AITags []FileAITag `json:"AITags,nullable"`
+ AITags []FileAITag `json:"AITags" api:"nullable"`
// The audio codec used in the video (only for video/audio).
AudioCodec string `json:"audioCodec"`
// The bit rate of the video in kbps (only for video).
@@ -177,7 +178,7 @@ type File struct {
// format.
CreatedAt time.Time `json:"createdAt" format:"date-time"`
// An string with custom coordinates of the file.
- CustomCoordinates string `json:"customCoordinates,nullable"`
+ CustomCoordinates string `json:"customCoordinates" api:"nullable"`
// An object with custom metadata for the file.
CustomMetadata map[string]any `json:"customMetadata"`
// Optional text to describe the contents of the file. Can be set by the user or
@@ -221,7 +222,7 @@ type File struct {
Size float64 `json:"size"`
// An array of tags assigned to the file. Tags are used to search files in the
// media library.
- Tags []string `json:"tags,nullable"`
+ Tags []string `json:"tags" api:"nullable"`
// URL of the thumbnail image. This URL is used to access the thumbnail image of
// the file in the media library.
Thumbnail string `json:"thumbnail" format:"uri"`
@@ -310,7 +311,7 @@ type FileSelectedFieldsSchema struct {
//
// Any of "Text", "Textarea", "Number", "Date", "Boolean", "SingleSelect",
// "MultiSelect".
- Type string `json:"type,required"`
+ Type string `json:"type" api:"required"`
// The default value for this custom metadata field. The value should match the
// `type` of custom metadata field.
DefaultValue FileSelectedFieldsSchemaDefaultValueUnion `json:"defaultValue"`
@@ -1018,7 +1019,7 @@ func (r *UpdateFileRequestChangePublicationStatusParam) UnmarshalJSON(data []byt
// The property IsPublished is required.
type UpdateFileRequestChangePublicationStatusPublishParam struct {
// Set to `true` to publish the file. Set to `false` to unpublish the file.
- IsPublished bool `json:"isPublished,required"`
+ IsPublished bool `json:"isPublished" api:"required"`
// Set to `true` to publish/unpublish all versions of the file. Set to `false` to
// publish/unpublish only the current version of the file.
IncludeFileVersions param.Opt[bool] `json:"includeFileVersions,omitzero"`
@@ -1129,7 +1130,7 @@ func (r *FileRenameResponse) UnmarshalJSON(data []byte) error {
// Object containing details of a successful upload.
type FileUploadResponse struct {
// An array of tags assigned to the uploaded file by auto tagging.
- AITags []FileUploadResponseAITag `json:"AITags,nullable"`
+ AITags []FileUploadResponseAITag `json:"AITags" api:"nullable"`
// The audio codec used in the video (only for video).
AudioCodec string `json:"audioCodec"`
// The bit rate of the video in kbps (only for video).
@@ -1138,7 +1139,7 @@ type FileUploadResponse struct {
// `x,y,width,height`. If `customCoordinates` are not defined, then it is `null`.
// Send `customCoordinates` in `responseFields` in API request to get the value of
// this field.
- CustomCoordinates string `json:"customCoordinates,nullable"`
+ CustomCoordinates string `json:"customCoordinates" api:"nullable"`
// A key-value data associated with the asset. Use `responseField` in API request
// to get `customMetadata` in the upload API response. Before setting any custom
// metadata on an asset, you have to create the field using custom metadata fields
@@ -1200,7 +1201,7 @@ type FileUploadResponse struct {
// The array of tags associated with the asset. If no tags are set, it will be
// `null`. Send `tags` in `responseFields` in API request to get the value of this
// field.
- Tags []string `json:"tags,nullable"`
+ Tags []string `json:"tags" api:"nullable"`
// In the case of an image, a small thumbnail URL.
ThumbnailURL string `json:"thumbnailUrl"`
// A publicly accessible URL of the file.
@@ -1317,7 +1318,7 @@ type FileUploadResponseSelectedFieldsSchema struct {
//
// Any of "Text", "Textarea", "Number", "Date", "Boolean", "SingleSelect",
// "MultiSelect".
- Type string `json:"type,required"`
+ Type string `json:"type" api:"required"`
// The default value for this custom metadata field. The value should match the
// `type` of custom metadata field.
DefaultValue FileUploadResponseSelectedFieldsSchemaDefaultValueUnion `json:"defaultValue"`
@@ -1615,14 +1616,14 @@ func (r FileUpdateParams) MarshalJSON() (data []byte, err error) {
return shimjson.Marshal(r.UpdateFileRequest)
}
func (r *FileUpdateParams) UnmarshalJSON(data []byte) error {
- return json.Unmarshal(data, &r.UpdateFileRequest)
+ return apijson.UnmarshalRoot(data, r)
}
type FileCopyParams struct {
// Full path to the folder you want to copy the above file into.
- DestinationPath string `json:"destinationPath,required"`
+ DestinationPath string `json:"destinationPath" api:"required"`
// The full path of the file you want to copy.
- SourceFilePath string `json:"sourceFilePath,required"`
+ SourceFilePath string `json:"sourceFilePath" api:"required"`
// Option to copy all versions of a file. By default, only the current version of
// the file is copied. When set to true, all versions of the file will be copied.
// Default value - `false`.
@@ -1640,9 +1641,9 @@ func (r *FileCopyParams) UnmarshalJSON(data []byte) error {
type FileMoveParams struct {
// Full path to the folder you want to move the above file into.
- DestinationPath string `json:"destinationPath,required"`
+ DestinationPath string `json:"destinationPath" api:"required"`
// The full path of the file you want to move.
- SourceFilePath string `json:"sourceFilePath,required"`
+ SourceFilePath string `json:"sourceFilePath" api:"required"`
paramObj
}
@@ -1656,14 +1657,14 @@ func (r *FileMoveParams) UnmarshalJSON(data []byte) error {
type FileRenameParams struct {
// The full path of the file you want to rename.
- FilePath string `json:"filePath,required"`
+ FilePath string `json:"filePath" api:"required"`
// The new name of the file. A filename can contain:
//
// Alphanumeric Characters: `a-z`, `A-Z`, `0-9` (including Unicode letters, marks,
// and numerals in other languages). Special Characters: `.`, `_`, and `-`.
//
// Any other character, including space, will be replaced by `_`.
- NewFileName string `json:"newFileName,required"`
+ NewFileName string `json:"newFileName" api:"required"`
// Option to purge cache for the old file and its versions' URLs.
//
// When set to true, it will internally issue a purge cache request on CDN to
@@ -1702,7 +1703,7 @@ type FileUploadParams struct {
// - Special Characters: `.`, `-`
//
// Any other character including space will be replaced by `_`
- FileName string `json:"fileName,required"`
+ FileName string `json:"fileName" api:"required"`
// A unique value that the ImageKit.io server will use to recognize and prevent
// subsequent retries for the same request. We suggest using V4 UUIDs, or another
// random string with enough entropy to avoid collisions. This field is only
@@ -2029,11 +2030,11 @@ func init() {
type FileUploadParamsTransformationPostTransformation struct {
// Transformation string (e.g. `w-200,h-200`).
// Same syntax as ImageKit URL-based transformations.
- Value string `json:"value,required"`
+ Value string `json:"value" api:"required"`
// Transformation type.
//
// This field can be elided, and will marshal its zero value as "transformation".
- Type constant.Transformation `json:"type,required"`
+ Type constant.Transformation `json:"type" default:"transformation"`
paramObj
}
@@ -2053,7 +2054,7 @@ type FileUploadParamsTransformationPostGifToVideo struct {
// Converts an animated GIF into an MP4.
//
// This field can be elided, and will marshal its zero value as "gif-to-video".
- Type constant.GifToVideo `json:"type,required"`
+ Type constant.GifToVideo `json:"type" default:"gif-to-video"`
paramObj
}
@@ -2073,7 +2074,7 @@ type FileUploadParamsTransformationPostThumbnail struct {
// Generates a thumbnail image.
//
// This field can be elided, and will marshal its zero value as "thumbnail".
- Type constant.Thumbnail `json:"type,required"`
+ Type constant.Thumbnail `json:"type" default:"thumbnail"`
paramObj
}
@@ -2090,13 +2091,13 @@ type FileUploadParamsTransformationPostAbs struct {
// Streaming protocol to use (`hls` or `dash`).
//
// Any of "hls", "dash".
- Protocol string `json:"protocol,omitzero,required"`
+ Protocol string `json:"protocol,omitzero" api:"required"`
// List of different representations you want to create separated by an underscore.
- Value string `json:"value,required"`
+ Value string `json:"value" api:"required"`
// Adaptive Bitrate Streaming (ABS) setup.
//
// This field can be elided, and will marshal its zero value as "abs".
- Type constant.Abs `json:"type,required"`
+ Type constant.Abs `json:"type" default:"abs"`
paramObj
}
diff --git a/file_test.go b/file_test.go
index 6b57c74..6bd7ed9 100644
--- a/file_test.go
+++ b/file_test.go
@@ -17,7 +17,7 @@ import (
)
func TestFileUpdateWithOptionalParams(t *testing.T) {
- t.Skip("Prism tests are disabled")
+ t.Skip("Mock server tests are disabled")
baseURL := "http://localhost:4010"
if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok {
baseURL = envURL
@@ -100,7 +100,7 @@ func TestFileUpdateWithOptionalParams(t *testing.T) {
}
func TestFileDelete(t *testing.T) {
- t.Skip("Prism tests are disabled")
+ t.Skip("Mock server tests are disabled")
baseURL := "http://localhost:4010"
if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok {
baseURL = envURL
@@ -124,7 +124,7 @@ func TestFileDelete(t *testing.T) {
}
func TestFileCopyWithOptionalParams(t *testing.T) {
- t.Skip("Prism tests are disabled")
+ t.Skip("Mock server tests are disabled")
baseURL := "http://localhost:4010"
if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok {
baseURL = envURL
@@ -152,7 +152,7 @@ func TestFileCopyWithOptionalParams(t *testing.T) {
}
func TestFileGet(t *testing.T) {
- t.Skip("Prism tests are disabled")
+ t.Skip("Mock server tests are disabled")
baseURL := "http://localhost:4010"
if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok {
baseURL = envURL
@@ -176,7 +176,7 @@ func TestFileGet(t *testing.T) {
}
func TestFileMove(t *testing.T) {
- t.Skip("Prism tests are disabled")
+ t.Skip("Mock server tests are disabled")
baseURL := "http://localhost:4010"
if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok {
baseURL = envURL
@@ -203,7 +203,7 @@ func TestFileMove(t *testing.T) {
}
func TestFileRenameWithOptionalParams(t *testing.T) {
- t.Skip("Prism tests are disabled")
+ t.Skip("Mock server tests are disabled")
baseURL := "http://localhost:4010"
if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok {
baseURL = envURL
@@ -231,7 +231,7 @@ func TestFileRenameWithOptionalParams(t *testing.T) {
}
func TestFileUploadWithOptionalParams(t *testing.T) {
- t.Skip("Prism tests are disabled")
+ t.Skip("Mock server tests are disabled")
baseURL := "http://localhost:4010"
if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok {
baseURL = envURL
@@ -245,7 +245,7 @@ func TestFileUploadWithOptionalParams(t *testing.T) {
option.WithPassword("My Password"),
)
_, err := client.Files.Upload(context.TODO(), imagekit.FileUploadParams{
- File: io.Reader(bytes.NewBuffer([]byte("some file contents"))),
+ File: io.Reader(bytes.NewBuffer([]byte("Example data"))),
FileName: "fileName",
Token: imagekit.String("token"),
Checks: imagekit.String("\"request.folder\" : \"marketing/\"\n"),
diff --git a/filebulk.go b/filebulk.go
index 76b76f6..7b1a172 100644
--- a/filebulk.go
+++ b/filebulk.go
@@ -44,7 +44,7 @@ func (r *FileBulkService) Delete(ctx context.Context, body FileBulkDeleteParams,
opts = slices.Concat(r.Options, opts)
path := "v1/files/batch/deleteByFileIds"
err = requestconfig.ExecuteNewRequest(ctx, http.MethodPost, path, body, &res, opts...)
- return
+ return res, err
}
// This API adds tags to multiple files in bulk. A maximum of 50 files can be
@@ -53,7 +53,7 @@ func (r *FileBulkService) AddTags(ctx context.Context, body FileBulkAddTagsParam
opts = slices.Concat(r.Options, opts)
path := "v1/files/addTags"
err = requestconfig.ExecuteNewRequest(ctx, http.MethodPost, path, body, &res, opts...)
- return
+ return res, err
}
// This API removes AITags from multiple files in bulk. A maximum of 50 files can
@@ -62,7 +62,7 @@ func (r *FileBulkService) RemoveAITags(ctx context.Context, body FileBulkRemoveA
opts = slices.Concat(r.Options, opts)
path := "v1/files/removeAITags"
err = requestconfig.ExecuteNewRequest(ctx, http.MethodPost, path, body, &res, opts...)
- return
+ return res, err
}
// This API removes tags from multiple files in bulk. A maximum of 50 files can be
@@ -71,7 +71,7 @@ func (r *FileBulkService) RemoveTags(ctx context.Context, body FileBulkRemoveTag
opts = slices.Concat(r.Options, opts)
path := "v1/files/removeTags"
err = requestconfig.ExecuteNewRequest(ctx, http.MethodPost, path, body, &res, opts...)
- return
+ return res, err
}
type FileBulkDeleteResponse struct {
@@ -144,7 +144,7 @@ func (r *FileBulkRemoveTagsResponse) UnmarshalJSON(data []byte) error {
type FileBulkDeleteParams struct {
// An array of fileIds which you want to delete.
- FileIDs []string `json:"fileIds,omitzero,required"`
+ FileIDs []string `json:"fileIds,omitzero" api:"required"`
paramObj
}
@@ -158,9 +158,9 @@ func (r *FileBulkDeleteParams) UnmarshalJSON(data []byte) error {
type FileBulkAddTagsParams struct {
// An array of fileIds to which you want to add tags.
- FileIDs []string `json:"fileIds,omitzero,required"`
+ FileIDs []string `json:"fileIds,omitzero" api:"required"`
// An array of tags that you want to add to the files.
- Tags []string `json:"tags,omitzero,required"`
+ Tags []string `json:"tags,omitzero" api:"required"`
paramObj
}
@@ -174,9 +174,9 @@ func (r *FileBulkAddTagsParams) UnmarshalJSON(data []byte) error {
type FileBulkRemoveAITagsParams struct {
// An array of AITags that you want to remove from the files.
- AITags []string `json:"AITags,omitzero,required"`
+ AITags []string `json:"AITags,omitzero" api:"required"`
// An array of fileIds from which you want to remove AITags.
- FileIDs []string `json:"fileIds,omitzero,required"`
+ FileIDs []string `json:"fileIds,omitzero" api:"required"`
paramObj
}
@@ -190,9 +190,9 @@ func (r *FileBulkRemoveAITagsParams) UnmarshalJSON(data []byte) error {
type FileBulkRemoveTagsParams struct {
// An array of fileIds from which you want to remove tags.
- FileIDs []string `json:"fileIds,omitzero,required"`
+ FileIDs []string `json:"fileIds,omitzero" api:"required"`
// An array of tags that you want to remove from the files.
- Tags []string `json:"tags,omitzero,required"`
+ Tags []string `json:"tags,omitzero" api:"required"`
paramObj
}
diff --git a/filebulk_test.go b/filebulk_test.go
index 1cb0db1..5da35a6 100644
--- a/filebulk_test.go
+++ b/filebulk_test.go
@@ -14,7 +14,7 @@ import (
)
func TestFileBulkDelete(t *testing.T) {
- t.Skip("Prism tests are disabled")
+ t.Skip("Mock server tests are disabled")
baseURL := "http://localhost:4010"
if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok {
baseURL = envURL
@@ -40,7 +40,7 @@ func TestFileBulkDelete(t *testing.T) {
}
func TestFileBulkAddTags(t *testing.T) {
- t.Skip("Prism tests are disabled")
+ t.Skip("Mock server tests are disabled")
baseURL := "http://localhost:4010"
if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok {
baseURL = envURL
@@ -67,7 +67,7 @@ func TestFileBulkAddTags(t *testing.T) {
}
func TestFileBulkRemoveAITags(t *testing.T) {
- t.Skip("Prism tests are disabled")
+ t.Skip("Mock server tests are disabled")
baseURL := "http://localhost:4010"
if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok {
baseURL = envURL
@@ -94,7 +94,7 @@ func TestFileBulkRemoveAITags(t *testing.T) {
}
func TestFileBulkRemoveTags(t *testing.T) {
- t.Skip("Prism tests are disabled")
+ t.Skip("Mock server tests are disabled")
baseURL := "http://localhost:4010"
if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok {
baseURL = envURL
diff --git a/filemetadata.go b/filemetadata.go
index 07f7b05..6d221c1 100644
--- a/filemetadata.go
+++ b/filemetadata.go
@@ -43,11 +43,11 @@ func (r *FileMetadataService) Get(ctx context.Context, fileID string, opts ...op
opts = slices.Concat(r.Options, opts)
if fileID == "" {
err = errors.New("missing required fileId parameter")
- return
+ return nil, err
}
path := fmt.Sprintf("v1/files/%s/metadata", fileID)
err = requestconfig.ExecuteNewRequest(ctx, http.MethodGet, path, nil, &res, opts...)
- return
+ return res, err
}
// Get image EXIF, pHash, and other metadata from ImageKit.io powered remote URL
@@ -56,13 +56,13 @@ func (r *FileMetadataService) GetFromURL(ctx context.Context, query FileMetadata
opts = slices.Concat(r.Options, opts)
path := "v1/metadata"
err = requestconfig.ExecuteNewRequest(ctx, http.MethodGet, path, query, &res, opts...)
- return
+ return res, err
}
type FileMetadataGetFromURLParams struct {
// Should be a valid file URL. It should be accessible using your ImageKit.io
// account.
- URL string `query:"url,required" format:"uri" json:"-"`
+ URL string `query:"url" api:"required" format:"uri" json:"-"`
paramObj
}
diff --git a/filemetadata_test.go b/filemetadata_test.go
index 0245da8..d5f2771 100644
--- a/filemetadata_test.go
+++ b/filemetadata_test.go
@@ -14,7 +14,7 @@ import (
)
func TestFileMetadataGet(t *testing.T) {
- t.Skip("Prism tests are disabled")
+ t.Skip("Mock server tests are disabled")
baseURL := "http://localhost:4010"
if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok {
baseURL = envURL
@@ -38,7 +38,7 @@ func TestFileMetadataGet(t *testing.T) {
}
func TestFileMetadataGetFromURL(t *testing.T) {
- t.Skip("Prism tests are disabled")
+ t.Skip("Mock server tests are disabled")
baseURL := "http://localhost:4010"
if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok {
baseURL = envURL
diff --git a/fileversion.go b/fileversion.go
index 6a07b1d..57a490b 100644
--- a/fileversion.go
+++ b/fileversion.go
@@ -39,11 +39,11 @@ func (r *FileVersionService) List(ctx context.Context, fileID string, opts ...op
opts = slices.Concat(r.Options, opts)
if fileID == "" {
err = errors.New("missing required fileId parameter")
- return
+ return nil, err
}
path := fmt.Sprintf("v1/files/%s/versions", fileID)
err = requestconfig.ExecuteNewRequest(ctx, http.MethodGet, path, nil, &res, opts...)
- return
+ return res, err
}
// This API deletes a non-current file version permanently. The API returns an
@@ -54,15 +54,15 @@ func (r *FileVersionService) Delete(ctx context.Context, versionID string, body
opts = slices.Concat(r.Options, opts)
if body.FileID == "" {
err = errors.New("missing required fileId parameter")
- return
+ return nil, err
}
if versionID == "" {
err = errors.New("missing required versionId parameter")
- return
+ return nil, err
}
path := fmt.Sprintf("v1/files/%s/versions/%s", body.FileID, versionID)
err = requestconfig.ExecuteNewRequest(ctx, http.MethodDelete, path, nil, &res, opts...)
- return
+ return res, err
}
// This API returns an object with details or attributes of a file version.
@@ -70,15 +70,15 @@ func (r *FileVersionService) Get(ctx context.Context, versionID string, query Fi
opts = slices.Concat(r.Options, opts)
if query.FileID == "" {
err = errors.New("missing required fileId parameter")
- return
+ return nil, err
}
if versionID == "" {
err = errors.New("missing required versionId parameter")
- return
+ return nil, err
}
path := fmt.Sprintf("v1/files/%s/versions/%s", query.FileID, versionID)
err = requestconfig.ExecuteNewRequest(ctx, http.MethodGet, path, nil, &res, opts...)
- return
+ return res, err
}
// This API restores a file version as the current file version.
@@ -86,15 +86,15 @@ func (r *FileVersionService) Restore(ctx context.Context, versionID string, body
opts = slices.Concat(r.Options, opts)
if body.FileID == "" {
err = errors.New("missing required fileId parameter")
- return
+ return nil, err
}
if versionID == "" {
err = errors.New("missing required versionId parameter")
- return
+ return nil, err
}
path := fmt.Sprintf("v1/files/%s/versions/%s/restore", body.FileID, versionID)
err = requestconfig.ExecuteNewRequest(ctx, http.MethodPut, path, nil, &res, opts...)
- return
+ return res, err
}
type FileVersionDeleteResponse struct {
@@ -112,16 +112,16 @@ func (r *FileVersionDeleteResponse) UnmarshalJSON(data []byte) error {
}
type FileVersionDeleteParams struct {
- FileID string `path:"fileId,required" json:"-"`
+ FileID string `path:"fileId" api:"required" json:"-"`
paramObj
}
type FileVersionGetParams struct {
- FileID string `path:"fileId,required" json:"-"`
+ FileID string `path:"fileId" api:"required" json:"-"`
paramObj
}
type FileVersionRestoreParams struct {
- FileID string `path:"fileId,required" json:"-"`
+ FileID string `path:"fileId" api:"required" json:"-"`
paramObj
}
diff --git a/fileversion_test.go b/fileversion_test.go
index e6d5499..80d6d42 100644
--- a/fileversion_test.go
+++ b/fileversion_test.go
@@ -14,7 +14,7 @@ import (
)
func TestFileVersionList(t *testing.T) {
- t.Skip("Prism tests are disabled")
+ t.Skip("Mock server tests are disabled")
baseURL := "http://localhost:4010"
if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok {
baseURL = envURL
@@ -38,7 +38,7 @@ func TestFileVersionList(t *testing.T) {
}
func TestFileVersionDelete(t *testing.T) {
- t.Skip("Prism tests are disabled")
+ t.Skip("Mock server tests are disabled")
baseURL := "http://localhost:4010"
if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok {
baseURL = envURL
@@ -68,7 +68,7 @@ func TestFileVersionDelete(t *testing.T) {
}
func TestFileVersionGet(t *testing.T) {
- t.Skip("Prism tests are disabled")
+ t.Skip("Mock server tests are disabled")
baseURL := "http://localhost:4010"
if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok {
baseURL = envURL
@@ -98,7 +98,7 @@ func TestFileVersionGet(t *testing.T) {
}
func TestFileVersionRestore(t *testing.T) {
- t.Skip("Prism tests are disabled")
+ t.Skip("Mock server tests are disabled")
baseURL := "http://localhost:4010"
if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok {
baseURL = envURL
diff --git a/folder.go b/folder.go
index e21c026..3fecf68 100644
--- a/folder.go
+++ b/folder.go
@@ -41,7 +41,7 @@ func (r *FolderService) New(ctx context.Context, body FolderNewParams, opts ...o
opts = slices.Concat(r.Options, opts)
path := "v1/folder"
err = requestconfig.ExecuteNewRequest(ctx, http.MethodPost, path, body, &res, opts...)
- return
+ return res, err
}
// This will delete a folder and all its contents permanently. The API returns an
@@ -50,7 +50,7 @@ func (r *FolderService) Delete(ctx context.Context, body FolderDeleteParams, opt
opts = slices.Concat(r.Options, opts)
path := "v1/folder"
err = requestconfig.ExecuteNewRequest(ctx, http.MethodDelete, path, body, &res, opts...)
- return
+ return res, err
}
// This will copy one folder into another. The selected folder, its nested folders,
@@ -62,7 +62,7 @@ func (r *FolderService) Copy(ctx context.Context, body FolderCopyParams, opts ..
opts = slices.Concat(r.Options, opts)
path := "v1/bulkJobs/copyFolder"
err = requestconfig.ExecuteNewRequest(ctx, http.MethodPost, path, body, &res, opts...)
- return
+ return res, err
}
// This will move one folder into another. The selected folder, its nested folders,
@@ -73,7 +73,7 @@ func (r *FolderService) Move(ctx context.Context, body FolderMoveParams, opts ..
opts = slices.Concat(r.Options, opts)
path := "v1/bulkJobs/moveFolder"
err = requestconfig.ExecuteNewRequest(ctx, http.MethodPost, path, body, &res, opts...)
- return
+ return res, err
}
// This API allows you to rename an existing folder. The folder and all its nested
@@ -83,7 +83,7 @@ func (r *FolderService) Rename(ctx context.Context, body FolderRenameParams, opt
opts = slices.Concat(r.Options, opts)
path := "v1/bulkJobs/renameFolder"
err = requestconfig.ExecuteNewRequest(ctx, http.MethodPost, path, body, &res, opts...)
- return
+ return res, err
}
type FolderNewResponse struct {
@@ -118,7 +118,7 @@ func (r *FolderDeleteResponse) UnmarshalJSON(data []byte) error {
type FolderCopyResponse struct {
// Unique identifier of the bulk job. This can be used to check the status of the
// bulk job.
- JobID string `json:"jobId,required"`
+ JobID string `json:"jobId" api:"required"`
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
JSON struct {
JobID respjson.Field
@@ -137,7 +137,7 @@ func (r *FolderCopyResponse) UnmarshalJSON(data []byte) error {
type FolderMoveResponse struct {
// Unique identifier of the bulk job. This can be used to check the status of the
// bulk job.
- JobID string `json:"jobId,required"`
+ JobID string `json:"jobId" api:"required"`
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
JSON struct {
JobID respjson.Field
@@ -156,7 +156,7 @@ func (r *FolderMoveResponse) UnmarshalJSON(data []byte) error {
type FolderRenameResponse struct {
// Unique identifier of the bulk job. This can be used to check the status of the
// bulk job.
- JobID string `json:"jobId,required"`
+ JobID string `json:"jobId" api:"required"`
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
JSON struct {
JobID respjson.Field
@@ -177,7 +177,7 @@ type FolderNewParams struct {
// All characters except alphabets and numbers (inclusive of unicode letters,
// marks, and numerals in other languages) will be replaced by an underscore i.e.
// `_`.
- FolderName string `json:"folderName,required"`
+ FolderName string `json:"folderName" api:"required"`
// The folder where the new folder should be created, for root use `/` else the
// path e.g. `containing/folder/`.
//
@@ -185,7 +185,7 @@ type FolderNewParams struct {
// be automatically created. For example, if you pass `/product/images/summer`,
// then `product`, `images`, and `summer` folders will be created if they don't
// already exist.
- ParentFolderPath string `json:"parentFolderPath,required"`
+ ParentFolderPath string `json:"parentFolderPath" api:"required"`
paramObj
}
@@ -199,7 +199,7 @@ func (r *FolderNewParams) UnmarshalJSON(data []byte) error {
type FolderDeleteParams struct {
// Full path to the folder you want to delete. For example `/folder/to/delete/`.
- FolderPath string `json:"folderPath,required"`
+ FolderPath string `json:"folderPath" api:"required"`
paramObj
}
@@ -214,9 +214,9 @@ func (r *FolderDeleteParams) UnmarshalJSON(data []byte) error {
type FolderCopyParams struct {
// Full path to the destination folder where you want to copy the source folder
// into.
- DestinationPath string `json:"destinationPath,required"`
+ DestinationPath string `json:"destinationPath" api:"required"`
// The full path to the source folder you want to copy.
- SourceFolderPath string `json:"sourceFolderPath,required"`
+ SourceFolderPath string `json:"sourceFolderPath" api:"required"`
// Option to copy all versions of files that are nested inside the selected folder.
// By default, only the current version of each file will be copied. When set to
// true, all versions of each file will be copied. Default value - `false`.
@@ -235,9 +235,9 @@ func (r *FolderCopyParams) UnmarshalJSON(data []byte) error {
type FolderMoveParams struct {
// Full path to the destination folder where you want to move the source folder
// into.
- DestinationPath string `json:"destinationPath,required"`
+ DestinationPath string `json:"destinationPath" api:"required"`
// The full path to the source folder you want to move.
- SourceFolderPath string `json:"sourceFolderPath,required"`
+ SourceFolderPath string `json:"sourceFolderPath" api:"required"`
paramObj
}
@@ -251,13 +251,13 @@ func (r *FolderMoveParams) UnmarshalJSON(data []byte) error {
type FolderRenameParams struct {
// The full path to the folder you want to rename.
- FolderPath string `json:"folderPath,required"`
+ FolderPath string `json:"folderPath" api:"required"`
// The new name for the folder.
//
// All characters except alphabets and numbers (inclusive of unicode letters,
// marks, and numerals in other languages) and `-` will be replaced by an
// underscore i.e. `_`.
- NewFolderName string `json:"newFolderName,required"`
+ NewFolderName string `json:"newFolderName" api:"required"`
// Option to purge cache for the old nested files and their versions' URLs.
//
// When set to true, it will internally issue a purge cache request on CDN to
diff --git a/folder_test.go b/folder_test.go
index b891101..ec03029 100644
--- a/folder_test.go
+++ b/folder_test.go
@@ -14,7 +14,7 @@ import (
)
func TestFolderNew(t *testing.T) {
- t.Skip("Prism tests are disabled")
+ t.Skip("Mock server tests are disabled")
baseURL := "http://localhost:4010"
if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok {
baseURL = envURL
@@ -41,7 +41,7 @@ func TestFolderNew(t *testing.T) {
}
func TestFolderDelete(t *testing.T) {
- t.Skip("Prism tests are disabled")
+ t.Skip("Mock server tests are disabled")
baseURL := "http://localhost:4010"
if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok {
baseURL = envURL
@@ -67,7 +67,7 @@ func TestFolderDelete(t *testing.T) {
}
func TestFolderCopyWithOptionalParams(t *testing.T) {
- t.Skip("Prism tests are disabled")
+ t.Skip("Mock server tests are disabled")
baseURL := "http://localhost:4010"
if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok {
baseURL = envURL
@@ -95,7 +95,7 @@ func TestFolderCopyWithOptionalParams(t *testing.T) {
}
func TestFolderMove(t *testing.T) {
- t.Skip("Prism tests are disabled")
+ t.Skip("Mock server tests are disabled")
baseURL := "http://localhost:4010"
if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok {
baseURL = envURL
@@ -122,7 +122,7 @@ func TestFolderMove(t *testing.T) {
}
func TestFolderRenameWithOptionalParams(t *testing.T) {
- t.Skip("Prism tests are disabled")
+ t.Skip("Mock server tests are disabled")
baseURL := "http://localhost:4010"
if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok {
baseURL = envURL
diff --git a/folderjob.go b/folderjob.go
index 8253935..b0eb5df 100644
--- a/folderjob.go
+++ b/folderjob.go
@@ -39,11 +39,11 @@ func (r *FolderJobService) Get(ctx context.Context, jobID string, opts ...option
opts = slices.Concat(r.Options, opts)
if jobID == "" {
err = errors.New("missing required jobId parameter")
- return
+ return nil, err
}
path := fmt.Sprintf("v1/bulkJobs/%s", jobID)
err = requestconfig.ExecuteNewRequest(ctx, http.MethodGet, path, nil, &res, opts...)
- return
+ return res, err
}
type FolderJobGetResponse struct {
diff --git a/folderjob_test.go b/folderjob_test.go
index a4c9541..f03c188 100644
--- a/folderjob_test.go
+++ b/folderjob_test.go
@@ -14,7 +14,7 @@ import (
)
func TestFolderJobGet(t *testing.T) {
- t.Skip("Prism tests are disabled")
+ t.Skip("Mock server tests are disabled")
baseURL := "http://localhost:4010"
if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok {
baseURL = envURL
diff --git a/go.mod b/go.mod
index f306eb5..12b1fb0 100644
--- a/go.mod
+++ b/go.mod
@@ -3,7 +3,7 @@ module github.com/imagekit-developer/imagekit-go/v2
go 1.22
require (
- github.com/standard-webhooks/standard-webhooks/libraries v0.0.0-20260114220421-3f69fd681bb0
+ github.com/standard-webhooks/standard-webhooks/libraries v0.0.0-20260309172517-425968d811b9
github.com/tidwall/gjson v1.18.0
github.com/tidwall/sjson v1.2.5
)
diff --git a/go.sum b/go.sum
index b09e3fe..ff28d75 100644
--- a/go.sum
+++ b/go.sum
@@ -1,5 +1,5 @@
-github.com/standard-webhooks/standard-webhooks/libraries v0.0.0-20260114220421-3f69fd681bb0 h1:EZXYkItlI9VXF+3x/VFkP8JKa6ibJVZAMjHGfdjzHC8=
-github.com/standard-webhooks/standard-webhooks/libraries v0.0.0-20260114220421-3f69fd681bb0/go.mod h1:L1MQhA6x4dn9r007T033lsaZMv9EmBAdXyU/+EF40fo=
+github.com/standard-webhooks/standard-webhooks/libraries v0.0.0-20260309172517-425968d811b9 h1:3Bb7YLURYzIPwqxoBpfhHaA/wu7zUNaHa2W6DJ1zD6s=
+github.com/standard-webhooks/standard-webhooks/libraries v0.0.0-20260309172517-425968d811b9/go.mod h1:L1MQhA6x4dn9r007T033lsaZMv9EmBAdXyU/+EF40fo=
github.com/tidwall/gjson v1.14.2/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
github.com/tidwall/gjson v1.18.0 h1:FIDeeyB800efLX89e5a8Y0BNH+LOngJyGrIWxG2FKQY=
github.com/tidwall/gjson v1.18.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
diff --git a/internal/apiform/encoder.go b/internal/apiform/encoder.go
index 58f5621..ab31015 100644
--- a/internal/apiform/encoder.go
+++ b/internal/apiform/encoder.go
@@ -183,6 +183,18 @@ func (e *encoder) newPrimitiveTypeEncoder(t reflect.Type) encoderFunc {
func (e *encoder) newArrayTypeEncoder(t reflect.Type) encoderFunc {
itemEncoder := e.typeEncoder(t.Elem())
keyFn := e.arrayKeyEncoder()
+ if e.arrayFmt == "comma" {
+ return func(key string, v reflect.Value, writer *multipart.Writer) error {
+ if v.Len() == 0 {
+ return nil
+ }
+ elements := make([]string, v.Len())
+ for i := 0; i < v.Len(); i++ {
+ elements[i] = fmt.Sprint(v.Index(i).Interface())
+ }
+ return writer.WriteField(key, strings.Join(elements, ","))
+ }
+ }
return func(key string, v reflect.Value, writer *multipart.Writer) error {
if keyFn == nil {
return fmt.Errorf("apiform: unsupported array format")
@@ -265,6 +277,14 @@ func (e *encoder) newStructTypeEncoder(t reflect.Type) encoderFunc {
}
return typeEncoderFn(key, value, writer)
}
+ } else if ptag.defaultValue != nil {
+ typeEncoderFn := e.typeEncoder(field.Type)
+ encoderFn = func(key string, value reflect.Value, writer *multipart.Writer) error {
+ if value.IsZero() {
+ return typeEncoderFn(key, reflect.ValueOf(ptag.defaultValue), writer)
+ }
+ return typeEncoderFn(key, value, writer)
+ }
} else {
encoderFn = e.typeEncoder(field.Type)
}
@@ -469,5 +489,5 @@ func WriteExtras(writer *multipart.Writer, extras map[string]any) (err error) {
break
}
}
- return
+ return err
}
diff --git a/internal/apiform/form_test.go b/internal/apiform/form_test.go
index 86cb43d..1751e27 100644
--- a/internal/apiform/form_test.go
+++ b/internal/apiform/form_test.go
@@ -48,18 +48,18 @@ type DateTime struct {
type AdditionalProperties struct {
A bool `form:"a"`
- Extras map[string]any `form:"-,extras"`
+ Extras map[string]any `form:"-" api:"extrafields"`
}
type TypedAdditionalProperties struct {
A bool `form:"a"`
- Extras map[string]int `form:"-,extras"`
+ Extras map[string]int `form:"-" api:"extrafields"`
}
type EmbeddedStructs struct {
AdditionalProperties
A *int `form:"number2"`
- Extras map[string]any `form:"-,extras"`
+ Extras map[string]any `form:"-" api:"extrafields"`
}
type Recursive struct {
@@ -123,6 +123,11 @@ type StructUnion struct {
param.APIUnion
}
+type ConstantStruct struct {
+ Anchor string `form:"anchor" default:"created_at"`
+ Seconds int `form:"seconds"`
+}
+
type MultipartMarshalerParent struct {
Middle MultipartMarshalerMiddleNext `form:"middle"`
}
@@ -554,6 +559,37 @@ Content-Disposition: form-data; name="union"
Union: UnionTime(time.Date(2010, 05, 23, 0, 0, 0, 0, time.UTC)),
},
},
+ "constant_zero_value": {
+ `--xxx
+Content-Disposition: form-data; name="anchor"
+
+created_at
+--xxx
+Content-Disposition: form-data; name="seconds"
+
+3600
+--xxx--
+`,
+ ConstantStruct{
+ Seconds: 3600,
+ },
+ },
+ "constant_explicit_value": {
+ `--xxx
+Content-Disposition: form-data; name="anchor"
+
+created_at_override
+--xxx
+Content-Disposition: form-data; name="seconds"
+
+3600
+--xxx--
+`,
+ ConstantStruct{
+ Anchor: "created_at_override",
+ Seconds: 3600,
+ },
+ },
"deeply-nested-struct,brackets": {
`--xxx
Content-Disposition: form-data; name="middle[middleNext][child]"
@@ -585,14 +621,17 @@ func TestEncode(t *testing.T) {
t.Run(name, func(t *testing.T) {
buf := bytes.NewBuffer(nil)
writer := multipart.NewWriter(buf)
- writer.SetBoundary("xxx")
+ err := writer.SetBoundary("xxx")
+ if err != nil {
+ t.Errorf("setting boundary for %v failed with error %v", test.val, err)
+ }
- var arrayFmt string = "indices:dots"
+ arrayFmt := "indices:dots"
if tags := strings.Split(name, ","); len(tags) > 1 {
arrayFmt = tags[1]
}
- err := MarshalWithSettings(test.val, writer, arrayFmt)
+ err = MarshalWithSettings(test.val, writer, arrayFmt)
if err != nil {
t.Errorf("serialization of %v failed with error %v", test.val, err)
}
diff --git a/internal/apiform/tag.go b/internal/apiform/tag.go
index 736fc1e..f0c9d14 100644
--- a/internal/apiform/tag.go
+++ b/internal/apiform/tag.go
@@ -5,16 +5,19 @@ import (
"strings"
)
+const apiStructTag = "api"
const jsonStructTag = "json"
const formStructTag = "form"
const formatStructTag = "format"
+const defaultStructTag = "default"
type parsedStructTag struct {
- name string
- required bool
- extras bool
- metadata bool
- omitzero bool
+ name string
+ required bool
+ extras bool
+ metadata bool
+ omitzero bool
+ defaultValue any
}
func parseFormStructTag(field reflect.StructField) (tag parsedStructTag, ok bool) {
@@ -23,7 +26,7 @@ func parseFormStructTag(field reflect.StructField) (tag parsedStructTag, ok bool
raw, ok = field.Tag.Lookup(jsonStructTag)
}
if !ok {
- return
+ return tag, ok
}
parts := strings.Split(raw, ",")
if len(parts) == 0 {
@@ -42,10 +45,44 @@ func parseFormStructTag(field reflect.StructField) (tag parsedStructTag, ok bool
tag.omitzero = true
}
}
- return
+
+ parseApiStructTag(field, &tag)
+ parseDefaultStructTag(field, &tag)
+ return tag, ok
+}
+
+func parseDefaultStructTag(field reflect.StructField, tag *parsedStructTag) {
+ if field.Type.Kind() != reflect.String {
+ // Only strings are currently supported
+ return
+ }
+
+ raw, ok := field.Tag.Lookup(defaultStructTag)
+ if !ok {
+ return
+ }
+ tag.defaultValue = raw
+}
+
+func parseApiStructTag(field reflect.StructField, tag *parsedStructTag) {
+ raw, ok := field.Tag.Lookup(apiStructTag)
+ if !ok {
+ return
+ }
+ parts := strings.Split(raw, ",")
+ for _, part := range parts {
+ switch part {
+ case "extrafields":
+ tag.extras = true
+ case "required":
+ tag.required = true
+ case "metadata":
+ tag.metadata = true
+ }
+ }
}
func parseFormatStructTag(field reflect.StructField) (format string, ok bool) {
format, ok = field.Tag.Lookup(formatStructTag)
- return
+ return format, ok
}
diff --git a/internal/apijson/decodeparam_test.go b/internal/apijson/decodeparam_test.go
index be371d0..198136d 100644
--- a/internal/apijson/decodeparam_test.go
+++ b/internal/apijson/decodeparam_test.go
@@ -50,10 +50,10 @@ func TestOptionalDecoders(t *testing.T) {
type paramObject = param.APIObject
type BasicObject struct {
- ReqInt int64 `json:"req_int,required"`
- ReqFloat float64 `json:"req_float,required"`
- ReqString string `json:"req_string,required"`
- ReqBool bool `json:"req_bool,required"`
+ ReqInt int64 `json:"req_int" api:"required"`
+ ReqFloat float64 `json:"req_float" api:"required"`
+ ReqString string `json:"req_string" api:"required"`
+ ReqBool bool `json:"req_bool" api:"required"`
OptInt param.Opt[int64] `json:"opt_int"`
OptFloat param.Opt[float64] `json:"opt_float"`
@@ -110,7 +110,7 @@ func TestBasicObject(t *testing.T) {
}
type ComplexObject struct {
- Basic BasicObject `json:"basic,required"`
+ Basic BasicObject `json:"basic" api:"required"`
Enum string `json:"enum"`
paramObject
}
@@ -152,29 +152,29 @@ func TestComplexObject(t *testing.T) {
type paramUnion = param.APIUnion
type MemberA struct {
- Name string `json:"name,required"`
- Age int `json:"age,required"`
+ Name string `json:"name" api:"required"`
+ Age int `json:"age" api:"required"`
}
type MemberB struct {
- Name string `json:"name,required"`
- Age string `json:"age,required"`
+ Name string `json:"name" api:"required"`
+ Age string `json:"age" api:"required"`
}
type MemberC struct {
- Name string `json:"name,required"`
- Age int `json:"age,required"`
+ Name string `json:"name" api:"required"`
+ Age int `json:"age" api:"required"`
Status string `json:"status"`
}
type MemberD struct {
- Cost int `json:"cost,required"`
- Status string `json:"status,required"`
+ Cost int `json:"cost" api:"required"`
+ Status string `json:"status" api:"required"`
}
type MemberE struct {
- Cost int `json:"cost,required"`
- Status string `json:"status,required"`
+ Cost int `json:"cost" api:"required"`
+ Status string `json:"status" api:"required"`
}
type MemberF struct {
@@ -318,21 +318,21 @@ func (c ConstantB) Default() string { return "B" }
func (c ConstantC) Default() string { return "C" }
type DiscVariantA struct {
- Name string `json:"name,required"`
- Age int `json:"age,required"`
- Type ConstantA `json:"type,required"`
+ Name string `json:"name" api:"required"`
+ Age int `json:"age" api:"required"`
+ Type ConstantA `json:"type" api:"required"`
}
type DiscVariantB struct {
- Name string `json:"name,required"`
- Age int `json:"age,required"`
- Type ConstantB `json:"type,required"`
+ Name string `json:"name" api:"required"`
+ Age int `json:"age" api:"required"`
+ Type ConstantB `json:"type" api:"required"`
}
type DiscVariantC struct {
- Name string `json:"name,required"`
- Age float64 `json:"age,required"`
- Type ConstantC `json:"type,required"`
+ Name string `json:"name" api:"required"`
+ Age float64 `json:"age" api:"required"`
+ Type ConstantC `json:"type" api:"required"`
}
type DiscriminatedUnion struct {
@@ -352,13 +352,13 @@ func init() {
}
type FooVariant struct {
- Type string `json:"type,required"`
- Value string `json:"value,required"`
+ Type string `json:"type" api:"required"`
+ Value string `json:"value" api:"required"`
}
type BarVariant struct {
- Type string `json:"type,required"`
- Enable bool `json:"enable,required"`
+ Type string `json:"type" api:"required"`
+ Enable bool `json:"enable" api:"required"`
}
type MultiDiscriminatorUnion struct {
diff --git a/internal/apijson/decoder.go b/internal/apijson/decoder.go
index b9729db..44ffc9a 100644
--- a/internal/apijson/decoder.go
+++ b/internal/apijson/decoder.go
@@ -393,7 +393,7 @@ func (d *decoderBuilder) newStructTypeDecoder(t reflect.Type) decoderFunc {
for _, decoder := range anonymousDecoders {
// ignore errors
- decoder.fn(node, value.FieldByIndex(decoder.idx), state)
+ _ = decoder.fn(node, value.FieldByIndex(decoder.idx), state)
}
for _, inlineDecoder := range inlineDecoders {
@@ -462,7 +462,7 @@ func (d *decoderBuilder) newStructTypeDecoder(t reflect.Type) decoderFunc {
// Handle null [param.Opt]
if itemNode.Type == gjson.Null && dest.IsValid() && dest.Type().Implements(reflect.TypeOf((*param.Optional)(nil)).Elem()) {
- dest.Addr().Interface().(json.Unmarshaler).UnmarshalJSON([]byte(itemNode.Raw))
+ _ = dest.Addr().Interface().(json.Unmarshaler).UnmarshalJSON([]byte(itemNode.Raw))
continue
}
@@ -684,8 +684,5 @@ func guardUnknown(state *decoderState, v reflect.Value) bool {
constantString, ok := v.Interface().(interface{ Default() string })
named := v.Type() != stringType
- if guardStrict(state, ok && named && v.Equal(reflect.ValueOf(constantString.Default()))) {
- return true
- }
- return false
+ return guardStrict(state, ok && named && v.Equal(reflect.ValueOf(constantString.Default())))
}
diff --git a/internal/apijson/decoderesp_test.go b/internal/apijson/decoderesp_test.go
index ca22fba..f467265 100644
--- a/internal/apijson/decoderesp_test.go
+++ b/internal/apijson/decoderesp_test.go
@@ -8,7 +8,7 @@ import (
)
type StructWithNullExtraField struct {
- Results []string `json:"results,required"`
+ Results []string `json:"results" api:"required"`
JSON struct {
Results respjson.Field
ExtraFields map[string]respjson.Field
diff --git a/internal/apijson/encoder.go b/internal/apijson/encoder.go
index ab7a3c1..7c71153 100644
--- a/internal/apijson/encoder.go
+++ b/internal/apijson/encoder.go
@@ -12,6 +12,8 @@ import (
"time"
"github.com/tidwall/sjson"
+
+ shimjson "github.com/imagekit-developer/imagekit-go/v2/internal/encoding/json"
)
var encoders sync.Map // map[encoderEntry]encoderFunc
@@ -271,6 +273,12 @@ func (e *encoder) newStructTypeEncoder(t reflect.Type) encoderFunc {
if err != nil {
return nil, err
}
+ if ef.tag.defaultValue != nil && (!field.IsValid() || field.IsZero()) {
+ encoded, err = shimjson.Marshal(ef.tag.defaultValue)
+ if err != nil {
+ return nil, err
+ }
+ }
if encoded == nil {
continue
}
@@ -286,28 +294,7 @@ func (e *encoder) newStructTypeEncoder(t reflect.Type) encoderFunc {
return nil, err
}
}
- return
- }
-}
-
-func (e *encoder) newFieldTypeEncoder(t reflect.Type) encoderFunc {
- f, _ := t.FieldByName("Value")
- enc := e.typeEncoder(f.Type)
-
- return func(value reflect.Value) (json []byte, err error) {
- present := value.FieldByName("Present")
- if !present.Bool() {
- return nil, nil
- }
- null := value.FieldByName("Null")
- if null.Bool() {
- return []byte("null"), nil
- }
- raw := value.FieldByName("Raw")
- if !raw.IsNil() {
- return e.typeEncoder(raw.Type())(raw)
- }
- return enc(value.FieldByName("Value"))
+ return json, err
}
}
diff --git a/internal/apijson/enum.go b/internal/apijson/enum.go
index 5bef11c..a1626a5 100644
--- a/internal/apijson/enum.go
+++ b/internal/apijson/enum.go
@@ -4,7 +4,6 @@ import (
"fmt"
"reflect"
"slices"
- "sync"
"github.com/tidwall/gjson"
)
@@ -15,7 +14,6 @@ import (
type validationEntry struct {
field reflect.StructField
- required bool
legalValues struct {
strings []string
// 1 represents true, 0 represents false, -1 represents either
@@ -24,9 +22,6 @@ type validationEntry struct {
}
}
-type validatorFunc func(reflect.Value) exactness
-
-var validators sync.Map
var validationRegistry = map[reflect.Type][]validationEntry{}
func RegisterFieldValidator[T any, V string | bool | int | float64](fieldName string, values ...V) {
@@ -111,9 +106,9 @@ func (state *decoderState) validateBool(v reflect.Value) {
return
}
b := v.Bool()
- if state.validator.legalValues.bools == 1 && b == false {
+ if state.validator.legalValues.bools == 1 && !b {
state.exactness = loose
- } else if state.validator.legalValues.bools == 0 && b == true {
+ } else if state.validator.legalValues.bools == 0 && b {
state.exactness = loose
}
}
diff --git a/internal/apijson/json_test.go b/internal/apijson/json_test.go
index 02904d2..2853bf9 100644
--- a/internal/apijson/json_test.go
+++ b/internal/apijson/json_test.go
@@ -40,12 +40,12 @@ type DateTime struct {
type AdditionalProperties struct {
A bool `json:"a"`
- ExtraFields map[string]any `json:"-,extras"`
+ ExtraFields map[string]any `json:"-" api:"extrafields"`
}
type TypedAdditionalProperties struct {
A bool `json:"a"`
- ExtraFields map[string]int `json:"-,extras"`
+ ExtraFields map[string]int `json:"-" api:"extrafields"`
}
type EmbeddedStruct struct {
@@ -65,7 +65,7 @@ type EmbeddedStructJSON struct {
type EmbeddedStructs struct {
EmbeddedStruct
A *int `json:"a"`
- ExtraFields map[string]any `json:"-,extras"`
+ ExtraFields map[string]any `json:"-" api:"extrafields"`
JSON EmbeddedStructsJSON
}
@@ -86,8 +86,8 @@ type JSONFieldStruct struct {
B int64 `json:"b"`
C string `json:"c"`
D string `json:"d"`
- ExtraFields map[string]int64 `json:",extras"`
- JSON JSONFieldStructJSON `json:",metadata"`
+ ExtraFields map[string]int64 `json:"" api:"extrafields"`
+ JSON JSONFieldStructJSON `json:"-" api:"metadata"`
}
type JSONFieldStructJSON struct {
@@ -113,12 +113,12 @@ type Union interface {
type Inline struct {
InlineField Primitives `json:",inline"`
- JSON InlineJSON `json:",metadata"`
+ JSON InlineJSON `json:"-" api:"metadata"`
}
type InlineArray struct {
InlineField []string `json:",inline"`
- JSON InlineJSON `json:",metadata"`
+ JSON InlineJSON `json:"-" api:"metadata"`
}
type InlineJSON struct {
@@ -268,7 +268,7 @@ type MarshallingUnionStruct struct {
func (r *MarshallingUnionStruct) UnmarshalJSON(data []byte) (err error) {
*r = MarshallingUnionStruct{}
err = UnmarshalRoot(data, &r.Union)
- return
+ return err
}
func (r MarshallingUnionStruct) MarshalJSON() (data []byte, err error) {
@@ -614,3 +614,20 @@ func TestEncode(t *testing.T) {
})
}
}
+
+type StructWithDefault struct {
+ Type string `json:"type" default:"foo"`
+}
+
+func TestDefault(t *testing.T) {
+ value := StructWithDefault{}
+ expected := `{"type":"foo"}`
+
+ raw, err := Marshal(value)
+ if err != nil {
+ t.Fatalf("serialization of %v failed with error %v", value, err)
+ }
+ if string(raw) != expected {
+ t.Fatalf("expected %+#v to serialize to %s but got %s", value, expected, string(raw))
+ }
+}
diff --git a/internal/apijson/tag.go b/internal/apijson/tag.go
index 812fb3c..efcaf8c 100644
--- a/internal/apijson/tag.go
+++ b/internal/apijson/tag.go
@@ -5,21 +5,24 @@ import (
"strings"
)
+const apiStructTag = "api"
const jsonStructTag = "json"
const formatStructTag = "format"
+const defaultStructTag = "default"
type parsedStructTag struct {
- name string
- required bool
- extras bool
- metadata bool
- inline bool
+ name string
+ required bool
+ extras bool
+ metadata bool
+ inline bool
+ defaultValue any
}
func parseJSONStructTag(field reflect.StructField) (tag parsedStructTag, ok bool) {
raw, ok := field.Tag.Lookup(jsonStructTag)
if !ok {
- return
+ return tag, ok
}
parts := strings.Split(raw, ",")
if len(parts) == 0 {
@@ -38,10 +41,45 @@ func parseJSONStructTag(field reflect.StructField) (tag parsedStructTag, ok bool
tag.inline = true
}
}
- return
+
+ // the `api` struct tag is only used alongside `json` for custom behaviour
+ parseApiStructTag(field, &tag)
+ parseDefaultStructTag(field, &tag)
+ return tag, ok
+}
+
+func parseDefaultStructTag(field reflect.StructField, tag *parsedStructTag) {
+ if field.Type.Kind() != reflect.String {
+ // Only strings are currently supported
+ return
+ }
+
+ raw, ok := field.Tag.Lookup(defaultStructTag)
+ if !ok {
+ return
+ }
+ tag.defaultValue = raw
+}
+
+func parseApiStructTag(field reflect.StructField, tag *parsedStructTag) {
+ raw, ok := field.Tag.Lookup(apiStructTag)
+ if !ok {
+ return
+ }
+ parts := strings.Split(raw, ",")
+ for _, part := range parts {
+ switch part {
+ case "extrafields":
+ tag.extras = true
+ case "required":
+ tag.required = true
+ case "metadata":
+ tag.metadata = true
+ }
+ }
}
func parseFormatStructTag(field reflect.StructField) (format string, ok bool) {
format, ok = field.Tag.Lookup(formatStructTag)
- return
+ return format, ok
}
diff --git a/internal/apiquery/encoder.go b/internal/apiquery/encoder.go
index 93d9637..7e4f49d 100644
--- a/internal/apiquery/encoder.go
+++ b/internal/apiquery/encoder.go
@@ -103,7 +103,7 @@ func (e *encoder) newTypeEncoder(t reflect.Type) encoderFunc {
encoder := e.typeEncoder(t.Elem())
return func(key string, value reflect.Value) (pairs []Pair, err error) {
if !value.IsValid() || value.IsNil() {
- return
+ return pairs, err
}
return encoder(key, value.Elem())
}
@@ -193,7 +193,7 @@ func (e *encoder) newStructTypeEncoder(t reflect.Type) encoderFunc {
return func(key string, value reflect.Value) (pairs []Pair, err error) {
for _, ef := range encoderFields {
- var subkey string = e.renderKeyPath(key, ef.tag.name)
+ subkey := e.renderKeyPath(key, ef.tag.name)
if ef.tag.inline {
subkey = key
}
@@ -205,7 +205,7 @@ func (e *encoder) newStructTypeEncoder(t reflect.Type) encoderFunc {
}
pairs = append(pairs, subpairs...)
}
- return
+ return pairs, err
}
}
@@ -256,7 +256,7 @@ func (e *encoder) newMapEncoder(t reflect.Type) encoderFunc {
}
pairs = append(pairs, subpairs...)
}
- return
+ return pairs, err
}
}
@@ -300,7 +300,7 @@ func (e *encoder) newArrayTypeEncoder(t reflect.Type) encoderFunc {
}
pairs = append(pairs, subpairs...)
}
- return
+ return pairs, err
}
case ArrayQueryFormatIndices:
panic("The array indices format is not supported yet")
@@ -315,7 +315,7 @@ func (e *encoder) newArrayTypeEncoder(t reflect.Type) encoderFunc {
}
pairs = append(pairs, subpairs...)
}
- return
+ return pairs, err
}
default:
panic(fmt.Sprintf("Unknown ArrayFormat value: %d", e.settings.ArrayFormat))
@@ -372,27 +372,6 @@ func (e *encoder) newPrimitiveTypeEncoder(t reflect.Type) encoderFunc {
}
}
-func (e *encoder) newFieldTypeEncoder(t reflect.Type) encoderFunc {
- f, _ := t.FieldByName("Value")
- enc := e.typeEncoder(f.Type)
-
- return func(key string, value reflect.Value) ([]Pair, error) {
- present := value.FieldByName("Present")
- if !present.Bool() {
- return nil, nil
- }
- null := value.FieldByName("Null")
- if null.Bool() {
- return nil, fmt.Errorf("apiquery: field cannot be null")
- }
- raw := value.FieldByName("Raw")
- if !raw.IsNil() {
- return e.typeEncoder(raw.Type())(key, raw)
- }
- return enc(key, value.FieldByName("Value"))
- }
-}
-
func (e *encoder) newTimeTypeEncoder(_ reflect.Type) encoderFunc {
format := e.dateFormat
return func(key string, value reflect.Value) ([]Pair, error) {
diff --git a/internal/apiquery/tag.go b/internal/apiquery/tag.go
index 772c40e..9e413ad 100644
--- a/internal/apiquery/tag.go
+++ b/internal/apiquery/tag.go
@@ -18,7 +18,7 @@ type parsedStructTag struct {
func parseQueryStructTag(field reflect.StructField) (tag parsedStructTag, ok bool) {
raw, ok := field.Tag.Lookup(queryStructTag)
if !ok {
- return
+ return tag, ok
}
parts := strings.Split(raw, ",")
if len(parts) == 0 {
@@ -35,10 +35,10 @@ func parseQueryStructTag(field reflect.StructField) (tag parsedStructTag, ok boo
tag.inline = true
}
}
- return
+ return tag, ok
}
func parseFormatStructTag(field reflect.StructField) (format string, ok bool) {
format, ok = field.Tag.Lookup(formatStructTag)
- return
+ return format, ok
}
diff --git a/internal/requestconfig/requestconfig.go b/internal/requestconfig/requestconfig.go
index 75e05ff..4807d71 100644
--- a/internal/requestconfig/requestconfig.go
+++ b/internal/requestconfig/requestconfig.go
@@ -121,7 +121,13 @@ func NewRequestConfig(ctx context.Context, method string, u string, body any, ds
}
params := q.Encode()
if params != "" {
- u = u + "?" + params
+ parsed, _ := url.Parse(u)
+ if parsed.RawQuery != "" {
+ parsed.RawQuery = parsed.RawQuery + "&" + params
+ u = parsed.String()
+ } else {
+ u = u + "?" + params
+ }
}
}
if body, ok := body.([]byte); ok {
@@ -357,11 +363,9 @@ func (b *bodyWithTimeout) Close() error {
}
func retryDelay(res *http.Response, retryCount int) time.Duration {
- // If the API asks us to wait a certain amount of time (and it's a reasonable amount),
- // just do what it says.
-
- if retryAfterDelay, ok := parseRetryAfterHeader(res); ok && 0 <= retryAfterDelay && retryAfterDelay < time.Minute {
- return retryAfterDelay
+ // If the backend tells us to wait a certain amount of time, use that value
+ if retryAfterDelay, ok := parseRetryAfterHeader(res); ok {
+ return max(0, retryAfterDelay)
}
maxDelay := 8 * time.Second
@@ -465,10 +469,14 @@ func (cfg *RequestConfig) Execute() (err error) {
// Close the response body before retrying to prevent connection leaks
if res != nil && res.Body != nil {
- res.Body.Close()
+ _ = res.Body.Close()
}
- time.Sleep(retryDelay(res, retryCount))
+ select {
+ case <-ctx.Done():
+ return ctx.Err()
+ case <-time.After(retryDelay(res, retryCount)):
+ }
}
// Save *http.Response if it is requested to, even if there was an error making the request. This is
@@ -489,7 +497,7 @@ func (cfg *RequestConfig) Execute() (err error) {
if res.StatusCode >= 400 {
contents, err := io.ReadAll(res.Body)
- res.Body.Close()
+ _ = res.Body.Close()
if err != nil {
return err
}
@@ -520,7 +528,7 @@ func (cfg *RequestConfig) Execute() (err error) {
}
contents, err := io.ReadAll(res.Body)
- res.Body.Close()
+ _ = res.Body.Close()
if err != nil {
return fmt.Errorf("error reading response body: %w", err)
}
diff --git a/internal/testutil/testutil.go b/internal/testutil/testutil.go
index 826d266..31103e9 100644
--- a/internal/testutil/testutil.go
+++ b/internal/testutil/testutil.go
@@ -16,10 +16,10 @@ func CheckTestServer(t *testing.T, url string) bool {
t.Fatalf("strconv.ParseBool(os.LookupEnv(%s)) failed: %s", SKIP_MOCK_TESTS, err)
}
if skip {
- t.Skip("The test will not run without a mock Prism server running against your OpenAPI spec")
+ t.Skip("The test will not run without a mock server running against your OpenAPI spec")
return false
}
- t.Errorf("The test will not run without a mock Prism server running against your OpenAPI spec. You can set the environment variable %s to true to skip running any tests that require the mock server", SKIP_MOCK_TESTS)
+ t.Errorf("The test will not run without a mock server running against your OpenAPI spec. You can set the environment variable %s to true to skip running any tests that require the mock server", SKIP_MOCK_TESTS)
return false
}
}
diff --git a/internal/version.go b/internal/version.go
index 0759deb..ebb76be 100644
--- a/internal/version.go
+++ b/internal/version.go
@@ -2,4 +2,4 @@
package internal
-const PackageVersion = "2.2.0" // x-release-please-version
+const PackageVersion = "2.3.0" // x-release-please-version
diff --git a/lib/helper.go b/lib/helper.go
index ea38f91..aeae510 100644
--- a/lib/helper.go
+++ b/lib/helper.go
@@ -618,6 +618,22 @@ func (r *HelperService) processOverlay(overlay shared.OverlayUnionParam) string
entries = append(entries, fmt.Sprintf("ly-%s", position.Y.OfString.Value))
}
+ if !param.IsOmitted(position.XCenter.OfFloat) {
+ entries = append(entries, fmt.Sprintf("lxc-%g", position.XCenter.OfFloat.Value))
+ } else if !param.IsOmitted(position.XCenter.OfString) {
+ entries = append(entries, fmt.Sprintf("lxc-%s", position.XCenter.OfString.Value))
+ }
+
+ if !param.IsOmitted(position.YCenter.OfFloat) {
+ entries = append(entries, fmt.Sprintf("lyc-%g", position.YCenter.OfFloat.Value))
+ } else if !param.IsOmitted(position.YCenter.OfString) {
+ entries = append(entries, fmt.Sprintf("lyc-%s", position.YCenter.OfString.Value))
+ }
+
+ if position.AnchorPoint != "" {
+ entries = append(entries, fmt.Sprintf("lap-%s", position.AnchorPoint))
+ }
+
if position.Focus != "" {
entries = append(entries, fmt.Sprintf("lfo-%s", position.Focus))
}
diff --git a/packages/param/encoder.go b/packages/param/encoder.go
index b0410be..631e780 100644
--- a/packages/param/encoder.go
+++ b/packages/param/encoder.go
@@ -83,6 +83,9 @@ func MarshalUnion[T ParamStruct](metadata T, variants ...any) ([]byte, error) {
}
}
if nPresent == 0 || presentIdx == -1 {
+ if metadata.null() {
+ return []byte("null"), nil
+ }
if ovr, ok := metadata.Overrides(); ok {
return shimjson.Marshal(ovr)
}
diff --git a/packages/param/encoder_test.go b/packages/param/encoder_test.go
index a86612f..eed22a0 100644
--- a/packages/param/encoder_test.go
+++ b/packages/param/encoder_test.go
@@ -363,3 +363,15 @@ func TestOverriddenUnion(t *testing.T) {
})
}
}
+
+func TestNullStructUnion(t *testing.T) {
+ nullUnion := param.NullStruct[PrimitiveUnion]()
+
+ b, err := json.Marshal(nullUnion)
+ if err != nil {
+ t.Fatalf("didn't expect error %v", err)
+ }
+ if string(b) != "null" {
+ t.Fatalf("expected null, received %s", string(b))
+ }
+}
diff --git a/packages/respjson/decoder_test.go b/packages/respjson/decoder_test.go
index ef5219c..665a6a8 100644
--- a/packages/respjson/decoder_test.go
+++ b/packages/respjson/decoder_test.go
@@ -30,7 +30,7 @@ func (r *UnionOfStringIntOrObject) UnmarshalJSON(data []byte) error {
type SubFields struct {
OfBool bool `json:",inline"`
- Name string `json:"name,required"`
+ Name string `json:"name" api:"required"`
JSON struct {
OfBool rj.Field
Name rj.Field
diff --git a/savedextension.go b/savedextension.go
index 1999c24..35f38ac 100644
--- a/savedextension.go
+++ b/savedextension.go
@@ -45,7 +45,7 @@ func (r *SavedExtensionService) New(ctx context.Context, body SavedExtensionNewP
opts = slices.Concat(r.Options, opts)
path := "v1/saved-extensions"
err = requestconfig.ExecuteNewRequest(ctx, http.MethodPost, path, body, &res, opts...)
- return
+ return res, err
}
// This API updates an existing saved extension. You can update the name,
@@ -54,11 +54,11 @@ func (r *SavedExtensionService) Update(ctx context.Context, id string, body Save
opts = slices.Concat(r.Options, opts)
if id == "" {
err = errors.New("missing required id parameter")
- return
+ return nil, err
}
path := fmt.Sprintf("v1/saved-extensions/%s", id)
err = requestconfig.ExecuteNewRequest(ctx, http.MethodPatch, path, body, &res, opts...)
- return
+ return res, err
}
// This API returns an array of all saved extensions for your account. Saved
@@ -68,7 +68,7 @@ func (r *SavedExtensionService) List(ctx context.Context, opts ...option.Request
opts = slices.Concat(r.Options, opts)
path := "v1/saved-extensions"
err = requestconfig.ExecuteNewRequest(ctx, http.MethodGet, path, nil, &res, opts...)
- return
+ return res, err
}
// This API deletes a saved extension permanently.
@@ -77,11 +77,11 @@ func (r *SavedExtensionService) Delete(ctx context.Context, id string, opts ...o
opts = append([]option.RequestOption{option.WithHeader("Accept", "*/*")}, opts...)
if id == "" {
err = errors.New("missing required id parameter")
- return
+ return err
}
path := fmt.Sprintf("v1/saved-extensions/%s", id)
err = requestconfig.ExecuteNewRequest(ctx, http.MethodDelete, path, nil, nil, opts...)
- return
+ return err
}
// This API returns details of a specific saved extension by ID.
@@ -89,21 +89,21 @@ func (r *SavedExtensionService) Get(ctx context.Context, id string, opts ...opti
opts = slices.Concat(r.Options, opts)
if id == "" {
err = errors.New("missing required id parameter")
- return
+ return nil, err
}
path := fmt.Sprintf("v1/saved-extensions/%s", id)
err = requestconfig.ExecuteNewRequest(ctx, http.MethodGet, path, nil, &res, opts...)
- return
+ return res, err
}
type SavedExtensionNewParams struct {
// Configuration object for an extension (base extensions only, not saved extension
// references).
- Config shared.ExtensionConfigUnionParam `json:"config,omitzero,required"`
+ Config shared.ExtensionConfigUnionParam `json:"config,omitzero" api:"required"`
// Description of what the saved extension does.
- Description string `json:"description,required"`
+ Description string `json:"description" api:"required"`
// Name of the saved extension.
- Name string `json:"name,required"`
+ Name string `json:"name" api:"required"`
paramObj
}
diff --git a/savedextension_test.go b/savedextension_test.go
index effbeaf..1149d86 100644
--- a/savedextension_test.go
+++ b/savedextension_test.go
@@ -15,7 +15,7 @@ import (
)
func TestSavedExtensionNewWithOptionalParams(t *testing.T) {
- t.Skip("Prism tests are disabled")
+ t.Skip("Mock server tests are disabled")
baseURL := "http://localhost:4010"
if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok {
baseURL = envURL
@@ -52,7 +52,7 @@ func TestSavedExtensionNewWithOptionalParams(t *testing.T) {
}
func TestSavedExtensionUpdateWithOptionalParams(t *testing.T) {
- t.Skip("Prism tests are disabled")
+ t.Skip("Mock server tests are disabled")
baseURL := "http://localhost:4010"
if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok {
baseURL = envURL
@@ -93,7 +93,7 @@ func TestSavedExtensionUpdateWithOptionalParams(t *testing.T) {
}
func TestSavedExtensionList(t *testing.T) {
- t.Skip("Prism tests are disabled")
+ t.Skip("Mock server tests are disabled")
baseURL := "http://localhost:4010"
if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok {
baseURL = envURL
@@ -117,7 +117,7 @@ func TestSavedExtensionList(t *testing.T) {
}
func TestSavedExtensionDelete(t *testing.T) {
- t.Skip("Prism tests are disabled")
+ t.Skip("Mock server tests are disabled")
baseURL := "http://localhost:4010"
if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok {
baseURL = envURL
@@ -141,7 +141,7 @@ func TestSavedExtensionDelete(t *testing.T) {
}
func TestSavedExtensionGet(t *testing.T) {
- t.Skip("Prism tests are disabled")
+ t.Skip("Mock server tests are disabled")
baseURL := "http://localhost:4010"
if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok {
baseURL = envURL
diff --git a/scripts/mock b/scripts/mock
deleted file mode 100755
index 0b28f6e..0000000
--- a/scripts/mock
+++ /dev/null
@@ -1,41 +0,0 @@
-#!/usr/bin/env bash
-
-set -e
-
-cd "$(dirname "$0")/.."
-
-if [[ -n "$1" && "$1" != '--'* ]]; then
- URL="$1"
- shift
-else
- URL="$(grep 'openapi_spec_url' .stats.yml | cut -d' ' -f2)"
-fi
-
-# Check if the URL is empty
-if [ -z "$URL" ]; then
- echo "Error: No OpenAPI spec path/url provided or found in .stats.yml"
- exit 1
-fi
-
-echo "==> Starting mock server with URL ${URL}"
-
-# Run prism mock on the given spec
-if [ "$1" == "--daemon" ]; then
- npm exec --package=@stainless-api/prism-cli@5.15.0 -- prism mock "$URL" &> .prism.log &
-
- # Wait for server to come online
- echo -n "Waiting for server"
- while ! grep -q "✖ fatal\|Prism is listening" ".prism.log" ; do
- echo -n "."
- sleep 0.1
- done
-
- if grep -q "✖ fatal" ".prism.log"; then
- cat .prism.log
- exit 1
- fi
-
- echo
-else
- npm exec --package=@stainless-api/prism-cli@5.15.0 -- prism mock "$URL"
-fi
diff --git a/scripts/test b/scripts/test
index c26b122..8704b64 100755
--- a/scripts/test
+++ b/scripts/test
@@ -4,53 +4,7 @@ set -e
cd "$(dirname "$0")/.."
-RED='\033[0;31m'
-GREEN='\033[0;32m'
-YELLOW='\033[0;33m'
-NC='\033[0m' # No Color
-function prism_is_running() {
- curl --silent "http://localhost:4010" >/dev/null 2>&1
-}
-
-kill_server_on_port() {
- pids=$(lsof -t -i tcp:"$1" || echo "")
- if [ "$pids" != "" ]; then
- kill "$pids"
- echo "Stopped $pids."
- fi
-}
-
-function is_overriding_api_base_url() {
- [ -n "$TEST_API_BASE_URL" ]
-}
-
-if ! is_overriding_api_base_url && ! prism_is_running ; then
- # When we exit this script, make sure to kill the background mock server process
- trap 'kill_server_on_port 4010' EXIT
-
- # Start the dev server
- ./scripts/mock --daemon
-fi
-
-if is_overriding_api_base_url ; then
- echo -e "${GREEN}✔ Running tests against ${TEST_API_BASE_URL}${NC}"
- echo
-elif ! prism_is_running ; then
- echo -e "${RED}ERROR:${NC} The test suite will not run without a mock Prism server"
- echo -e "running against your OpenAPI spec."
- echo
- echo -e "To run the server, pass in the path or url of your OpenAPI"
- echo -e "spec to the prism command:"
- echo
- echo -e " \$ ${YELLOW}npm exec --package=@stainless-api/prism-cli@5.15.0 -- prism mock path/to/your.openapi.yml${NC}"
- echo
-
- exit 1
-else
- echo -e "${GREEN}✔ Mock prism server is running with your OpenAPI spec${NC}"
- echo
-fi
echo "==> Running tests"
go test ./... "$@"
diff --git a/scripts/utils/upload-artifact.sh b/scripts/utils/upload-artifact.sh
new file mode 100755
index 0000000..cf87460
--- /dev/null
+++ b/scripts/utils/upload-artifact.sh
@@ -0,0 +1,50 @@
+#!/usr/bin/env bash
+set -exuo pipefail
+
+DIST_DIR="dist"
+FILENAME="source.zip"
+
+mapfile -d '' files < <(
+ find . -type f \
+ \( -name '*.go' -o -name 'go.mod' -o -name 'go.sum' \) \
+ ! -path "./${DIST_DIR}/*" \
+ -print0
+)
+
+if [[ ${#files[@]} -eq 0 ]]; then
+ echo -e "\033[31mNo Go source files found for packaging.\033[0m"
+ exit 1
+fi
+
+mkdir -p "$DIST_DIR"
+rm -f "${DIST_DIR}/${FILENAME}"
+
+relative_files=()
+for file in "${files[@]}"; do
+ relative_files+=("${file#./}")
+done
+
+zip "${DIST_DIR}/${FILENAME}" "${relative_files[@]}"
+
+RESPONSE=$(curl -X POST "$URL?filename=$FILENAME" \
+ -H "Authorization: Bearer $AUTH" \
+ -H "Content-Type: application/json")
+
+SIGNED_URL=$(echo "$RESPONSE" | jq -r '.url')
+
+if [[ "$SIGNED_URL" == "null" ]]; then
+ echo -e "\033[31mFailed to get signed URL.\033[0m"
+ exit 1
+fi
+
+UPLOAD_RESPONSE=$(curl -v -X PUT \
+ -H "Content-Type: application/zip" \
+ --data-binary "@${DIST_DIR}/${FILENAME}" "$SIGNED_URL" 2>&1)
+
+if echo "$UPLOAD_RESPONSE" | grep -q "HTTP/[0-9.]* 200"; then
+ echo -e "\033[32mUploaded build to Stainless storage.\033[0m"
+ echo -e "\033[32mInstallation: Download and unzip: 'https://pkg.stainless.com/s/imagekit-go/$SHA'. Run 'go mod edit -replace github.com/imagekit-developer/imagekit-go/v2=/path/to/unzipped_directory'.\033[0m"
+else
+ echo -e "\033[31mFailed to upload artifact.\033[0m"
+ exit 1
+fi
diff --git a/shared/shared.go b/shared/shared.go
index 1d00baa..3699882 100644
--- a/shared/shared.go
+++ b/shared/shared.go
@@ -155,7 +155,7 @@ func (r ExtensionConfigUnion) ToParam() ExtensionConfigUnionParam {
type ExtensionConfigRemoveBg struct {
// Specifies the background removal extension.
- Name constant.RemoveBg `json:"name,required"`
+ Name constant.RemoveBg `json:"name" default:"remove-bg"`
Options ExtensionConfigRemoveBgOptions `json:"options"`
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
JSON struct {
@@ -205,13 +205,13 @@ func (r *ExtensionConfigRemoveBgOptions) UnmarshalJSON(data []byte) error {
type ExtensionConfigAutoTagging struct {
// Maximum number of tags to attach to the asset.
- MaxTags int64 `json:"maxTags,required"`
+ MaxTags int64 `json:"maxTags" api:"required"`
// Minimum confidence level for tags to be considered valid.
- MinConfidence int64 `json:"minConfidence,required"`
+ MinConfidence int64 `json:"minConfidence" api:"required"`
// Specifies the auto-tagging extension used.
//
// Any of "google-auto-tagging", "aws-auto-tagging".
- Name string `json:"name,required"`
+ Name string `json:"name" api:"required"`
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
JSON struct {
MaxTags respjson.Field
@@ -230,7 +230,7 @@ func (r *ExtensionConfigAutoTagging) UnmarshalJSON(data []byte) error {
type ExtensionConfigAIAutoDescription struct {
// Specifies the auto description extension.
- Name constant.AIAutoDescription `json:"name,required"`
+ Name constant.AIAutoDescription `json:"name" default:"ai-auto-description"`
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
JSON struct {
Name respjson.Field
@@ -247,9 +247,9 @@ func (r *ExtensionConfigAIAutoDescription) UnmarshalJSON(data []byte) error {
type ExtensionConfigAITasks struct {
// Specifies the AI tasks extension for automated image analysis using AI models.
- Name constant.AITasks `json:"name,required"`
+ Name constant.AITasks `json:"name" default:"ai-tasks"`
// Array of task objects defining AI operations to perform on the asset.
- Tasks []ExtensionConfigAITasksTaskUnion `json:"tasks,required"`
+ Tasks []ExtensionConfigAITasksTaskUnion `json:"tasks" api:"required"`
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
JSON struct {
Name respjson.Field
@@ -383,15 +383,17 @@ func (r *ExtensionConfigAITasksTaskUnionVocabulary) UnmarshalJSON(data []byte) e
type ExtensionConfigAITasksTaskSelectTags struct {
// The question or instruction for the AI to analyze the image.
- Instruction string `json:"instruction,required"`
+ Instruction string `json:"instruction" api:"required"`
// Task type that analyzes the image and adds matching tags from a vocabulary.
- Type constant.SelectTags `json:"type,required"`
+ Type constant.SelectTags `json:"type" default:"select_tags"`
// Maximum number of tags to select from the vocabulary.
MaxSelections int64 `json:"max_selections"`
// Minimum number of tags to select from the vocabulary.
MinSelections int64 `json:"min_selections"`
- // Array of possible tag values. Combined length of all strings must not exceed 500
- // characters. Cannot contain the `%` character.
+ // Array of possible tag values. The combined length of all strings must not exceed
+ // 500 characters, and values cannot include the `%` character. When providing
+ // large vocabularies (more than 30 items), the AI may not follow the list
+ // strictly.
Vocabulary []string `json:"vocabulary"`
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
JSON struct {
@@ -415,17 +417,20 @@ func (ExtensionConfigAITasksTaskSelectTags) implExtensionConfigAITasksTaskUnion(
type ExtensionConfigAITasksTaskSelectMetadata struct {
// Name of the custom metadata field to set. The field must exist in your account.
- Field string `json:"field,required"`
+ Field string `json:"field" api:"required"`
// The question or instruction for the AI to analyze the image.
- Instruction string `json:"instruction,required"`
+ Instruction string `json:"instruction" api:"required"`
// Task type that analyzes the image and sets a custom metadata field value from a
// vocabulary.
- Type constant.SelectMetadata `json:"type,required"`
+ Type constant.SelectMetadata `json:"type" default:"select_metadata"`
// Maximum number of values to select from the vocabulary.
MaxSelections int64 `json:"max_selections"`
// Minimum number of values to select from the vocabulary.
MinSelections int64 `json:"min_selections"`
- // Array of possible values matching the custom metadata field type.
+ // An array of possible values matching the custom metadata field type. If not
+ // provided for SingleSelect or MultiSelect field types, all values from the custom
+ // metadata field definition will be used. When providing large vocabularies (above
+ // 30 items), the AI may not strictly adhere to the list.
Vocabulary []ExtensionConfigAITasksTaskSelectMetadataVocabularyUnion `json:"vocabulary"`
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
JSON struct {
@@ -494,9 +499,9 @@ func (r *ExtensionConfigAITasksTaskSelectMetadataVocabularyUnion) UnmarshalJSON(
type ExtensionConfigAITasksTaskYesNo struct {
// The yes/no question for the AI to answer about the image.
- Instruction string `json:"instruction,required"`
+ Instruction string `json:"instruction" api:"required"`
// Task type that asks a yes/no question and executes actions based on the answer.
- Type constant.YesNo `json:"type,required"`
+ Type constant.YesNo `json:"type" default:"yes_no"`
// Actions to execute if the AI answers no.
OnNo ExtensionConfigAITasksTaskYesNoOnNo `json:"on_no"`
// Actions to execute if the AI cannot determine the answer.
@@ -552,10 +557,10 @@ func (r *ExtensionConfigAITasksTaskYesNoOnNo) UnmarshalJSON(data []byte) error {
type ExtensionConfigAITasksTaskYesNoOnNoSetMetadata struct {
// Name of the custom metadata field to set.
- Field string `json:"field,required"`
+ Field string `json:"field" api:"required"`
// Value to set for the custom metadata field. The value type should match the
// custom metadata field type.
- Value ExtensionConfigAITasksTaskYesNoOnNoSetMetadataValueUnion `json:"value,required"`
+ Value ExtensionConfigAITasksTaskYesNoOnNoSetMetadataValueUnion `json:"value" api:"required"`
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
JSON struct {
Field respjson.Field
@@ -674,7 +679,7 @@ func (r *ExtensionConfigAITasksTaskYesNoOnNoSetMetadataValueMixedItemUnion) Unma
type ExtensionConfigAITasksTaskYesNoOnNoUnsetMetadata struct {
// Name of the custom metadata field to remove.
- Field string `json:"field,required"`
+ Field string `json:"field" api:"required"`
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
JSON struct {
Field respjson.Field
@@ -718,10 +723,10 @@ func (r *ExtensionConfigAITasksTaskYesNoOnUnknown) UnmarshalJSON(data []byte) er
type ExtensionConfigAITasksTaskYesNoOnUnknownSetMetadata struct {
// Name of the custom metadata field to set.
- Field string `json:"field,required"`
+ Field string `json:"field" api:"required"`
// Value to set for the custom metadata field. The value type should match the
// custom metadata field type.
- Value ExtensionConfigAITasksTaskYesNoOnUnknownSetMetadataValueUnion `json:"value,required"`
+ Value ExtensionConfigAITasksTaskYesNoOnUnknownSetMetadataValueUnion `json:"value" api:"required"`
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
JSON struct {
Field respjson.Field
@@ -842,7 +847,7 @@ func (r *ExtensionConfigAITasksTaskYesNoOnUnknownSetMetadataValueMixedItemUnion)
type ExtensionConfigAITasksTaskYesNoOnUnknownUnsetMetadata struct {
// Name of the custom metadata field to remove.
- Field string `json:"field,required"`
+ Field string `json:"field" api:"required"`
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
JSON struct {
Field respjson.Field
@@ -886,10 +891,10 @@ func (r *ExtensionConfigAITasksTaskYesNoOnYes) UnmarshalJSON(data []byte) error
type ExtensionConfigAITasksTaskYesNoOnYesSetMetadata struct {
// Name of the custom metadata field to set.
- Field string `json:"field,required"`
+ Field string `json:"field" api:"required"`
// Value to set for the custom metadata field. The value type should match the
// custom metadata field type.
- Value ExtensionConfigAITasksTaskYesNoOnYesSetMetadataValueUnion `json:"value,required"`
+ Value ExtensionConfigAITasksTaskYesNoOnYesSetMetadataValueUnion `json:"value" api:"required"`
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
JSON struct {
Field respjson.Field
@@ -1010,7 +1015,7 @@ func (r *ExtensionConfigAITasksTaskYesNoOnYesSetMetadataValueMixedItemUnion) Unm
type ExtensionConfigAITasksTaskYesNoOnYesUnsetMetadata struct {
// Name of the custom metadata field to remove.
- Field string `json:"field,required"`
+ Field string `json:"field" api:"required"`
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
JSON struct {
Field respjson.Field
@@ -1133,7 +1138,7 @@ type ExtensionConfigRemoveBgParam struct {
// Specifies the background removal extension.
//
// This field can be elided, and will marshal its zero value as "remove-bg".
- Name constant.RemoveBg `json:"name,required"`
+ Name constant.RemoveBg `json:"name" default:"remove-bg"`
paramObj
}
@@ -1173,13 +1178,13 @@ func (r *ExtensionConfigRemoveBgOptionsParam) UnmarshalJSON(data []byte) error {
// The properties MaxTags, MinConfidence, Name are required.
type ExtensionConfigAutoTaggingParam struct {
// Maximum number of tags to attach to the asset.
- MaxTags int64 `json:"maxTags,required"`
+ MaxTags int64 `json:"maxTags" api:"required"`
// Minimum confidence level for tags to be considered valid.
- MinConfidence int64 `json:"minConfidence,required"`
+ MinConfidence int64 `json:"minConfidence" api:"required"`
// Specifies the auto-tagging extension used.
//
// Any of "google-auto-tagging", "aws-auto-tagging".
- Name string `json:"name,omitzero,required"`
+ Name string `json:"name,omitzero" api:"required"`
paramObj
}
@@ -1207,7 +1212,7 @@ func NewExtensionConfigAIAutoDescriptionParam() ExtensionConfigAIAutoDescription
// [NewExtensionConfigAIAutoDescriptionParam].
type ExtensionConfigAIAutoDescriptionParam struct {
// Specifies the auto description extension.
- Name constant.AIAutoDescription `json:"name,required"`
+ Name constant.AIAutoDescription `json:"name" default:"ai-auto-description"`
paramObj
}
@@ -1222,11 +1227,11 @@ func (r *ExtensionConfigAIAutoDescriptionParam) UnmarshalJSON(data []byte) error
// The properties Name, Tasks are required.
type ExtensionConfigAITasksParam struct {
// Array of task objects defining AI operations to perform on the asset.
- Tasks []ExtensionConfigAITasksTaskUnionParam `json:"tasks,omitzero,required"`
+ Tasks []ExtensionConfigAITasksTaskUnionParam `json:"tasks,omitzero" api:"required"`
// Specifies the AI tasks extension for automated image analysis using AI models.
//
// This field can be elided, and will marshal its zero value as "ai-tasks".
- Name constant.AITasks `json:"name,required"`
+ Name constant.AITasks `json:"name" default:"ai-tasks"`
paramObj
}
@@ -1380,18 +1385,20 @@ func init() {
// The properties Instruction, Type are required.
type ExtensionConfigAITasksTaskSelectTagsParam struct {
// The question or instruction for the AI to analyze the image.
- Instruction string `json:"instruction,required"`
+ Instruction string `json:"instruction" api:"required"`
// Maximum number of tags to select from the vocabulary.
MaxSelections param.Opt[int64] `json:"max_selections,omitzero"`
// Minimum number of tags to select from the vocabulary.
MinSelections param.Opt[int64] `json:"min_selections,omitzero"`
- // Array of possible tag values. Combined length of all strings must not exceed 500
- // characters. Cannot contain the `%` character.
+ // Array of possible tag values. The combined length of all strings must not exceed
+ // 500 characters, and values cannot include the `%` character. When providing
+ // large vocabularies (more than 30 items), the AI may not follow the list
+ // strictly.
Vocabulary []string `json:"vocabulary,omitzero"`
// Task type that analyzes the image and adds matching tags from a vocabulary.
//
// This field can be elided, and will marshal its zero value as "select_tags".
- Type constant.SelectTags `json:"type,required"`
+ Type constant.SelectTags `json:"type" default:"select_tags"`
paramObj
}
@@ -1406,20 +1413,23 @@ func (r *ExtensionConfigAITasksTaskSelectTagsParam) UnmarshalJSON(data []byte) e
// The properties Field, Instruction, Type are required.
type ExtensionConfigAITasksTaskSelectMetadataParam struct {
// Name of the custom metadata field to set. The field must exist in your account.
- Field string `json:"field,required"`
+ Field string `json:"field" api:"required"`
// The question or instruction for the AI to analyze the image.
- Instruction string `json:"instruction,required"`
+ Instruction string `json:"instruction" api:"required"`
// Maximum number of values to select from the vocabulary.
MaxSelections param.Opt[int64] `json:"max_selections,omitzero"`
// Minimum number of values to select from the vocabulary.
MinSelections param.Opt[int64] `json:"min_selections,omitzero"`
- // Array of possible values matching the custom metadata field type.
+ // An array of possible values matching the custom metadata field type. If not
+ // provided for SingleSelect or MultiSelect field types, all values from the custom
+ // metadata field definition will be used. When providing large vocabularies (above
+ // 30 items), the AI may not strictly adhere to the list.
Vocabulary []ExtensionConfigAITasksTaskSelectMetadataVocabularyUnionParam `json:"vocabulary,omitzero"`
// Task type that analyzes the image and sets a custom metadata field value from a
// vocabulary.
//
// This field can be elided, and will marshal its zero value as "select_metadata".
- Type constant.SelectMetadata `json:"type,required"`
+ Type constant.SelectMetadata `json:"type" default:"select_metadata"`
paramObj
}
@@ -1462,7 +1472,7 @@ func (u *ExtensionConfigAITasksTaskSelectMetadataVocabularyUnionParam) asAny() a
// The properties Instruction, Type are required.
type ExtensionConfigAITasksTaskYesNoParam struct {
// The yes/no question for the AI to answer about the image.
- Instruction string `json:"instruction,required"`
+ Instruction string `json:"instruction" api:"required"`
// Actions to execute if the AI answers no.
OnNo ExtensionConfigAITasksTaskYesNoOnNoParam `json:"on_no,omitzero"`
// Actions to execute if the AI cannot determine the answer.
@@ -1472,7 +1482,7 @@ type ExtensionConfigAITasksTaskYesNoParam struct {
// Task type that asks a yes/no question and executes actions based on the answer.
//
// This field can be elided, and will marshal its zero value as "yes_no".
- Type constant.YesNo `json:"type,required"`
+ Type constant.YesNo `json:"type" default:"yes_no"`
paramObj
}
@@ -1508,10 +1518,10 @@ func (r *ExtensionConfigAITasksTaskYesNoOnNoParam) UnmarshalJSON(data []byte) er
// The properties Field, Value are required.
type ExtensionConfigAITasksTaskYesNoOnNoSetMetadataParam struct {
// Name of the custom metadata field to set.
- Field string `json:"field,required"`
+ Field string `json:"field" api:"required"`
// Value to set for the custom metadata field. The value type should match the
// custom metadata field type.
- Value ExtensionConfigAITasksTaskYesNoOnNoSetMetadataValueUnionParam `json:"value,omitzero,required"`
+ Value ExtensionConfigAITasksTaskYesNoOnNoSetMetadataValueUnionParam `json:"value,omitzero" api:"required"`
paramObj
}
@@ -1585,7 +1595,7 @@ func (u *ExtensionConfigAITasksTaskYesNoOnNoSetMetadataValueMixedItemUnionParam)
// The property Field is required.
type ExtensionConfigAITasksTaskYesNoOnNoUnsetMetadataParam struct {
// Name of the custom metadata field to remove.
- Field string `json:"field,required"`
+ Field string `json:"field" api:"required"`
paramObj
}
@@ -1621,10 +1631,10 @@ func (r *ExtensionConfigAITasksTaskYesNoOnUnknownParam) UnmarshalJSON(data []byt
// The properties Field, Value are required.
type ExtensionConfigAITasksTaskYesNoOnUnknownSetMetadataParam struct {
// Name of the custom metadata field to set.
- Field string `json:"field,required"`
+ Field string `json:"field" api:"required"`
// Value to set for the custom metadata field. The value type should match the
// custom metadata field type.
- Value ExtensionConfigAITasksTaskYesNoOnUnknownSetMetadataValueUnionParam `json:"value,omitzero,required"`
+ Value ExtensionConfigAITasksTaskYesNoOnUnknownSetMetadataValueUnionParam `json:"value,omitzero" api:"required"`
paramObj
}
@@ -1698,7 +1708,7 @@ func (u *ExtensionConfigAITasksTaskYesNoOnUnknownSetMetadataValueMixedItemUnionP
// The property Field is required.
type ExtensionConfigAITasksTaskYesNoOnUnknownUnsetMetadataParam struct {
// Name of the custom metadata field to remove.
- Field string `json:"field,required"`
+ Field string `json:"field" api:"required"`
paramObj
}
@@ -1734,10 +1744,10 @@ func (r *ExtensionConfigAITasksTaskYesNoOnYesParam) UnmarshalJSON(data []byte) e
// The properties Field, Value are required.
type ExtensionConfigAITasksTaskYesNoOnYesSetMetadataParam struct {
// Name of the custom metadata field to set.
- Field string `json:"field,required"`
+ Field string `json:"field" api:"required"`
// Value to set for the custom metadata field. The value type should match the
// custom metadata field type.
- Value ExtensionConfigAITasksTaskYesNoOnYesSetMetadataValueUnionParam `json:"value,omitzero,required"`
+ Value ExtensionConfigAITasksTaskYesNoOnYesSetMetadataValueUnionParam `json:"value,omitzero" api:"required"`
paramObj
}
@@ -1811,7 +1821,7 @@ func (u *ExtensionConfigAITasksTaskYesNoOnYesSetMetadataValueMixedItemUnionParam
// The property Field is required.
type ExtensionConfigAITasksTaskYesNoOnYesUnsetMetadataParam struct {
// Name of the custom metadata field to remove.
- Field string `json:"field,required"`
+ Field string `json:"field" api:"required"`
paramObj
}
@@ -1937,7 +1947,7 @@ type ExtensionRemoveBgParam struct {
// Specifies the background removal extension.
//
// This field can be elided, and will marshal its zero value as "remove-bg".
- Name constant.RemoveBg `json:"name,required"`
+ Name constant.RemoveBg `json:"name" default:"remove-bg"`
paramObj
}
@@ -1977,13 +1987,13 @@ func (r *ExtensionRemoveBgOptionsParam) UnmarshalJSON(data []byte) error {
// The properties MaxTags, MinConfidence, Name are required.
type ExtensionAutoTaggingParam struct {
// Maximum number of tags to attach to the asset.
- MaxTags int64 `json:"maxTags,required"`
+ MaxTags int64 `json:"maxTags" api:"required"`
// Minimum confidence level for tags to be considered valid.
- MinConfidence int64 `json:"minConfidence,required"`
+ MinConfidence int64 `json:"minConfidence" api:"required"`
// Specifies the auto-tagging extension used.
//
// Any of "google-auto-tagging", "aws-auto-tagging".
- Name string `json:"name,omitzero,required"`
+ Name string `json:"name,omitzero" api:"required"`
paramObj
}
@@ -2011,7 +2021,7 @@ func NewExtensionAIAutoDescriptionParam() ExtensionAIAutoDescriptionParam {
// [NewExtensionAIAutoDescriptionParam].
type ExtensionAIAutoDescriptionParam struct {
// Specifies the auto description extension.
- Name constant.AIAutoDescription `json:"name,required"`
+ Name constant.AIAutoDescription `json:"name" default:"ai-auto-description"`
paramObj
}
@@ -2026,11 +2036,11 @@ func (r *ExtensionAIAutoDescriptionParam) UnmarshalJSON(data []byte) error {
// The properties Name, Tasks are required.
type ExtensionAITasksParam struct {
// Array of task objects defining AI operations to perform on the asset.
- Tasks []ExtensionAITasksTaskUnionParam `json:"tasks,omitzero,required"`
+ Tasks []ExtensionAITasksTaskUnionParam `json:"tasks,omitzero" api:"required"`
// Specifies the AI tasks extension for automated image analysis using AI models.
//
// This field can be elided, and will marshal its zero value as "ai-tasks".
- Name constant.AITasks `json:"name,required"`
+ Name constant.AITasks `json:"name" default:"ai-tasks"`
paramObj
}
@@ -2184,18 +2194,20 @@ func init() {
// The properties Instruction, Type are required.
type ExtensionAITasksTaskSelectTagsParam struct {
// The question or instruction for the AI to analyze the image.
- Instruction string `json:"instruction,required"`
+ Instruction string `json:"instruction" api:"required"`
// Maximum number of tags to select from the vocabulary.
MaxSelections param.Opt[int64] `json:"max_selections,omitzero"`
// Minimum number of tags to select from the vocabulary.
MinSelections param.Opt[int64] `json:"min_selections,omitzero"`
- // Array of possible tag values. Combined length of all strings must not exceed 500
- // characters. Cannot contain the `%` character.
+ // Array of possible tag values. The combined length of all strings must not exceed
+ // 500 characters, and values cannot include the `%` character. When providing
+ // large vocabularies (more than 30 items), the AI may not follow the list
+ // strictly.
Vocabulary []string `json:"vocabulary,omitzero"`
// Task type that analyzes the image and adds matching tags from a vocabulary.
//
// This field can be elided, and will marshal its zero value as "select_tags".
- Type constant.SelectTags `json:"type,required"`
+ Type constant.SelectTags `json:"type" default:"select_tags"`
paramObj
}
@@ -2210,20 +2222,23 @@ func (r *ExtensionAITasksTaskSelectTagsParam) UnmarshalJSON(data []byte) error {
// The properties Field, Instruction, Type are required.
type ExtensionAITasksTaskSelectMetadataParam struct {
// Name of the custom metadata field to set. The field must exist in your account.
- Field string `json:"field,required"`
+ Field string `json:"field" api:"required"`
// The question or instruction for the AI to analyze the image.
- Instruction string `json:"instruction,required"`
+ Instruction string `json:"instruction" api:"required"`
// Maximum number of values to select from the vocabulary.
MaxSelections param.Opt[int64] `json:"max_selections,omitzero"`
// Minimum number of values to select from the vocabulary.
MinSelections param.Opt[int64] `json:"min_selections,omitzero"`
- // Array of possible values matching the custom metadata field type.
+ // An array of possible values matching the custom metadata field type. If not
+ // provided for SingleSelect or MultiSelect field types, all values from the custom
+ // metadata field definition will be used. When providing large vocabularies (above
+ // 30 items), the AI may not strictly adhere to the list.
Vocabulary []ExtensionAITasksTaskSelectMetadataVocabularyUnionParam `json:"vocabulary,omitzero"`
// Task type that analyzes the image and sets a custom metadata field value from a
// vocabulary.
//
// This field can be elided, and will marshal its zero value as "select_metadata".
- Type constant.SelectMetadata `json:"type,required"`
+ Type constant.SelectMetadata `json:"type" default:"select_metadata"`
paramObj
}
@@ -2266,7 +2281,7 @@ func (u *ExtensionAITasksTaskSelectMetadataVocabularyUnionParam) asAny() any {
// The properties Instruction, Type are required.
type ExtensionAITasksTaskYesNoParam struct {
// The yes/no question for the AI to answer about the image.
- Instruction string `json:"instruction,required"`
+ Instruction string `json:"instruction" api:"required"`
// Actions to execute if the AI answers no.
OnNo ExtensionAITasksTaskYesNoOnNoParam `json:"on_no,omitzero"`
// Actions to execute if the AI cannot determine the answer.
@@ -2276,7 +2291,7 @@ type ExtensionAITasksTaskYesNoParam struct {
// Task type that asks a yes/no question and executes actions based on the answer.
//
// This field can be elided, and will marshal its zero value as "yes_no".
- Type constant.YesNo `json:"type,required"`
+ Type constant.YesNo `json:"type" default:"yes_no"`
paramObj
}
@@ -2312,10 +2327,10 @@ func (r *ExtensionAITasksTaskYesNoOnNoParam) UnmarshalJSON(data []byte) error {
// The properties Field, Value are required.
type ExtensionAITasksTaskYesNoOnNoSetMetadataParam struct {
// Name of the custom metadata field to set.
- Field string `json:"field,required"`
+ Field string `json:"field" api:"required"`
// Value to set for the custom metadata field. The value type should match the
// custom metadata field type.
- Value ExtensionAITasksTaskYesNoOnNoSetMetadataValueUnionParam `json:"value,omitzero,required"`
+ Value ExtensionAITasksTaskYesNoOnNoSetMetadataValueUnionParam `json:"value,omitzero" api:"required"`
paramObj
}
@@ -2389,7 +2404,7 @@ func (u *ExtensionAITasksTaskYesNoOnNoSetMetadataValueMixedItemUnionParam) asAny
// The property Field is required.
type ExtensionAITasksTaskYesNoOnNoUnsetMetadataParam struct {
// Name of the custom metadata field to remove.
- Field string `json:"field,required"`
+ Field string `json:"field" api:"required"`
paramObj
}
@@ -2425,10 +2440,10 @@ func (r *ExtensionAITasksTaskYesNoOnUnknownParam) UnmarshalJSON(data []byte) err
// The properties Field, Value are required.
type ExtensionAITasksTaskYesNoOnUnknownSetMetadataParam struct {
// Name of the custom metadata field to set.
- Field string `json:"field,required"`
+ Field string `json:"field" api:"required"`
// Value to set for the custom metadata field. The value type should match the
// custom metadata field type.
- Value ExtensionAITasksTaskYesNoOnUnknownSetMetadataValueUnionParam `json:"value,omitzero,required"`
+ Value ExtensionAITasksTaskYesNoOnUnknownSetMetadataValueUnionParam `json:"value,omitzero" api:"required"`
paramObj
}
@@ -2502,7 +2517,7 @@ func (u *ExtensionAITasksTaskYesNoOnUnknownSetMetadataValueMixedItemUnionParam)
// The property Field is required.
type ExtensionAITasksTaskYesNoOnUnknownUnsetMetadataParam struct {
// Name of the custom metadata field to remove.
- Field string `json:"field,required"`
+ Field string `json:"field" api:"required"`
paramObj
}
@@ -2538,10 +2553,10 @@ func (r *ExtensionAITasksTaskYesNoOnYesParam) UnmarshalJSON(data []byte) error {
// The properties Field, Value are required.
type ExtensionAITasksTaskYesNoOnYesSetMetadataParam struct {
// Name of the custom metadata field to set.
- Field string `json:"field,required"`
+ Field string `json:"field" api:"required"`
// Value to set for the custom metadata field. The value type should match the
// custom metadata field type.
- Value ExtensionAITasksTaskYesNoOnYesSetMetadataValueUnionParam `json:"value,omitzero,required"`
+ Value ExtensionAITasksTaskYesNoOnYesSetMetadataValueUnionParam `json:"value,omitzero" api:"required"`
paramObj
}
@@ -2615,7 +2630,7 @@ func (u *ExtensionAITasksTaskYesNoOnYesSetMetadataValueMixedItemUnionParam) asAn
// The property Field is required.
type ExtensionAITasksTaskYesNoOnYesUnsetMetadataParam struct {
// Name of the custom metadata field to remove.
- Field string `json:"field,required"`
+ Field string `json:"field" api:"required"`
paramObj
}
@@ -2630,11 +2645,11 @@ func (r *ExtensionAITasksTaskYesNoOnYesUnsetMetadataParam) UnmarshalJSON(data []
// The properties ID, Name are required.
type ExtensionSavedExtensionParam struct {
// The unique ID of the saved extension to apply.
- ID string `json:"id,required"`
+ ID string `json:"id" api:"required"`
// Indicates this is a reference to a saved extension.
//
// This field can be elided, and will marshal its zero value as "saved-extension".
- Name constant.SavedExtension `json:"name,required"`
+ Name constant.SavedExtension `json:"name" default:"saved-extension"`
paramObj
}
@@ -2692,8 +2707,8 @@ func (r GetImageAttributesOptionsParam) MarshalJSON() (data []byte, err error) {
type ImageOverlayParam struct {
// Specifies the relative path to the image used as an overlay.
- Input string `json:"input,required"`
- Type constant.Image `json:"type,required"`
+ Input string `json:"input" api:"required"`
+ Type constant.Image `json:"type" default:"image"`
// The input path can be included in the layer as either `i-{input}` or
// `ie-{base64_encoded_input}`. By default, the SDK determines the appropriate
// format automatically. To always use base64 encoding (`ie-{base64}`), set this
@@ -2944,8 +2959,16 @@ func init() {
}
type OverlayPositionParam struct {
- // Specifies the position of the overlay relative to the parent image or video.
- // Maps to `lfo` in the URL.
+ // Sets the anchor point on the base asset from which the overlay offset is
+ // calculated. The default value is `top_left`. Maps to `lap` in the URL. Can only
+ // be used with one or more of `x`, `y`, `xCenter`, or `yCenter`.
+ //
+ // Any of "top", "left", "right", "bottom", "top_left", "top_right", "bottom_left",
+ // "bottom_right", "center".
+ AnchorPoint OverlayPositionAnchorPoint `json:"anchorPoint,omitzero"`
+ // Specifies the position of the overlay relative to the parent image or video. If
+ // one or more of `x`, `y`, `xCenter`, or `yCenter` parameters are specified, this
+ // parameter is ignored. Maps to `lfo` in the URL.
//
// Any of "center", "top", "left", "bottom", "right", "top_left", "top_right",
// "bottom_left", "bottom_right".
@@ -2956,12 +2979,24 @@ type OverlayPositionParam struct {
// about
// [Arithmetic expressions](https://imagekit.io/docs/arithmetic-expressions-in-transformations).
X OverlayPositionXUnionParam `json:"x,omitzero"`
+ // Specifies the x-coordinate on the base asset where the overlay's center will be
+ // positioned. It also accepts arithmetic expressions such as `bw_mul_0.4` or
+ // `bw_sub_cw`. Maps to `lxc` in the URL. Cannot be used together with `x`, but can
+ // be used with `y`. Learn about
+ // [Arithmetic expressions](https://imagekit.io/docs/arithmetic-expressions-in-transformations).
+ XCenter OverlayPositionXCenterUnionParam `json:"xCenter,omitzero"`
// Specifies the y-coordinate of the top-left corner of the base asset where the
// overlay's top-left corner will be positioned. It also accepts arithmetic
// expressions such as `bh_mul_0.4` or `bh_sub_ch`. Maps to `ly` in the URL. Learn
// about
// [Arithmetic expressions](https://imagekit.io/docs/arithmetic-expressions-in-transformations).
Y OverlayPositionYUnionParam `json:"y,omitzero"`
+ // Specifies the y-coordinate on the base asset where the overlay's center will be
+ // positioned. It also accepts arithmetic expressions such as `bh_mul_0.4` or
+ // `bh_sub_ch`. Maps to `lyc` in the URL. Cannot be used together with `y`, but can
+ // be used with `x`. Learn about
+ // [Arithmetic expressions](https://imagekit.io/docs/arithmetic-expressions-in-transformations).
+ YCenter OverlayPositionYCenterUnionParam `json:"yCenter,omitzero"`
paramObj
}
@@ -2973,8 +3008,26 @@ func (r *OverlayPositionParam) UnmarshalJSON(data []byte) error {
return apijson.UnmarshalRoot(data, r)
}
-// Specifies the position of the overlay relative to the parent image or video.
-// Maps to `lfo` in the URL.
+// Sets the anchor point on the base asset from which the overlay offset is
+// calculated. The default value is `top_left`. Maps to `lap` in the URL. Can only
+// be used with one or more of `x`, `y`, `xCenter`, or `yCenter`.
+type OverlayPositionAnchorPoint string
+
+const (
+ OverlayPositionAnchorPointTop OverlayPositionAnchorPoint = "top"
+ OverlayPositionAnchorPointLeft OverlayPositionAnchorPoint = "left"
+ OverlayPositionAnchorPointRight OverlayPositionAnchorPoint = "right"
+ OverlayPositionAnchorPointBottom OverlayPositionAnchorPoint = "bottom"
+ OverlayPositionAnchorPointTopLeft OverlayPositionAnchorPoint = "top_left"
+ OverlayPositionAnchorPointTopRight OverlayPositionAnchorPoint = "top_right"
+ OverlayPositionAnchorPointBottomLeft OverlayPositionAnchorPoint = "bottom_left"
+ OverlayPositionAnchorPointBottomRight OverlayPositionAnchorPoint = "bottom_right"
+ OverlayPositionAnchorPointCenter OverlayPositionAnchorPoint = "center"
+)
+
+// Specifies the position of the overlay relative to the parent image or video. If
+// one or more of `x`, `y`, `xCenter`, or `yCenter` parameters are specified, this
+// parameter is ignored. Maps to `lfo` in the URL.
type OverlayPositionFocus string
const (
@@ -3014,6 +3067,31 @@ func (u *OverlayPositionXUnionParam) asAny() any {
return nil
}
+// Only one field can be non-zero.
+//
+// Use [param.IsOmitted] to confirm if a field is set.
+type OverlayPositionXCenterUnionParam struct {
+ OfFloat param.Opt[float64] `json:",omitzero,inline"`
+ OfString param.Opt[string] `json:",omitzero,inline"`
+ paramUnion
+}
+
+func (u OverlayPositionXCenterUnionParam) MarshalJSON() ([]byte, error) {
+ return param.MarshalUnion(u, u.OfFloat, u.OfString)
+}
+func (u *OverlayPositionXCenterUnionParam) UnmarshalJSON(data []byte) error {
+ return apijson.UnmarshalRoot(data, u)
+}
+
+func (u *OverlayPositionXCenterUnionParam) asAny() any {
+ if !param.IsOmitted(u.OfFloat) {
+ return &u.OfFloat.Value
+ } else if !param.IsOmitted(u.OfString) {
+ return &u.OfString.Value
+ }
+ return nil
+}
+
// Only one field can be non-zero.
//
// Use [param.IsOmitted] to confirm if a field is set.
@@ -3039,6 +3117,31 @@ func (u *OverlayPositionYUnionParam) asAny() any {
return nil
}
+// Only one field can be non-zero.
+//
+// Use [param.IsOmitted] to confirm if a field is set.
+type OverlayPositionYCenterUnionParam struct {
+ OfFloat param.Opt[float64] `json:",omitzero,inline"`
+ OfString param.Opt[string] `json:",omitzero,inline"`
+ paramUnion
+}
+
+func (u OverlayPositionYCenterUnionParam) MarshalJSON() ([]byte, error) {
+ return param.MarshalUnion(u, u.OfFloat, u.OfString)
+}
+func (u *OverlayPositionYCenterUnionParam) UnmarshalJSON(data []byte) error {
+ return apijson.UnmarshalRoot(data, u)
+}
+
+func (u *OverlayPositionYCenterUnionParam) asAny() any {
+ if !param.IsOmitted(u.OfFloat) {
+ return &u.OfFloat.Value
+ } else if !param.IsOmitted(u.OfString) {
+ return &u.OfString.Value
+ }
+ return nil
+}
+
type OverlayTimingParam struct {
// Specifies the duration (in seconds) during which the overlay should appear on
// the base video. Accepts a positive number up to two decimal places (e.g., `20`
@@ -3148,7 +3251,7 @@ func (u *OverlayTimingStartUnionParam) asAny() any {
// The property Src is required.
type ResponsiveImageAttributesParam struct {
// URL for the _largest_ candidate (assigned to plain `src`).
- Src string `json:"src,required" format:"uri"`
+ Src string `json:"src" api:"required" format:"uri"`
// `sizes` returned (or synthesised as `100vw`). The value for the HTML `sizes`
// attribute.
Sizes param.Opt[string] `json:"sizes,omitzero"`
@@ -3242,8 +3345,8 @@ type SolidColorOverlayParam struct {
// code (e.g., `FFAABB50`), or a color name (e.g., `red`). If an 8-character value
// is provided, the last two characters represent the opacity level (from `00` for
// 0.00 to `99` for 0.99).
- Color string `json:"color,required"`
- Type constant.SolidColor `json:"type,required"`
+ Color string `json:"color" api:"required"`
+ Type constant.SolidColor `json:"type" default:"solidColor"`
// Control width and height of the solid color overlay. Supported transformations
// depend on the base/parent asset. See overlays on
// [Images](https://imagekit.io/docs/add-overlays-on-images#apply-transformation-on-solid-color-overlay)
@@ -3420,10 +3523,10 @@ type SrcOptionsParam struct {
// Accepts a relative or absolute path of the resource. If a relative path is
// provided, it is appended to the `urlEndpoint`. If an absolute path is provided,
// `urlEndpoint` is ignored.
- Src string `json:"src,required"`
+ Src string `json:"src" api:"required"`
// Get your urlEndpoint from the
// [ImageKit dashboard](https://imagekit.io/dashboard/url-endpoints).
- URLEndpoint string `json:"urlEndpoint,required" format:"uri"`
+ URLEndpoint string `json:"urlEndpoint" api:"required" format:"uri"`
// When you want the signed URL to expire, specified in seconds. If `expiresIn` is
// anything above 0, the URL will always be signed even if `signed` is set to
// false. If not specified and `signed` is `true`, the signed URL will not expire
@@ -3484,8 +3587,8 @@ const (
type SubtitleOverlayParam struct {
// Specifies the relative path to the subtitle file used as an overlay.
- Input string `json:"input,required"`
- Type constant.Subtitle `json:"type,required"`
+ Input string `json:"input" api:"required"`
+ Type constant.Subtitle `json:"type" default:"subtitle"`
// The input path can be included in the layer as either `i-{input}` or
// `ie-{base64_encoded_input}`. By default, the SDK determines the appropriate
// format automatically. To always use base64 encoding (`ie-{base64}`), set this
@@ -3584,8 +3687,8 @@ const (
type TextOverlayParam struct {
// Specifies the text to be displayed in the overlay. The SDK automatically handles
// special characters and encoding.
- Text string `json:"text,required"`
- Type constant.Text `json:"type,required"`
+ Text string `json:"text" api:"required"`
+ Type constant.Text `json:"type" default:"text"`
// Text can be included in the layer as either `i-{input}` (plain text) or
// `ie-{base64_encoded_input}` (base64). By default, the SDK selects the
// appropriate format based on the input text. To always use base64
@@ -4805,8 +4908,8 @@ const (
type VideoOverlayParam struct {
// Specifies the relative path to the video used as an overlay.
- Input string `json:"input,required"`
- Type constant.Video `json:"type,required"`
+ Input string `json:"input" api:"required"`
+ Type constant.Video `json:"type" default:"video"`
// The input path can be included in the layer as either `i-{input}` or
// `ie-{base64_encoded_input}`. By default, the SDK determines the appropriate
// format automatically. To always use base64 encoding (`ie-{base64}`), set this
diff --git a/tests/helper_overlay_test.go b/tests/helper_overlay_test.go
index 4e730d1..ace80d8 100644
--- a/tests/helper_overlay_test.go
+++ b/tests/helper_overlay_test.go
@@ -945,4 +945,36 @@ func TestOverlayEncoding(t *testing.T) {
t.Errorf("Expected %s, got %s", expected, url)
}
})
+
+ t.Run("should generate URL with image overlay using xCenter yCenter and anchorPoint", func(t *testing.T) {
+ transformation := []shared.TransformationParam{
+ {
+ Overlay: shared.OverlayUnionParam{
+ OfImage: &shared.ImageOverlayParam{
+ Input: "logo.png",
+ Type: constant.Image("image"),
+ BaseOverlayParam: shared.BaseOverlayParam{
+ Position: shared.OverlayPositionParam{
+ XCenter: shared.OverlayPositionXCenterUnionParam{OfFloat: param.Opt[float64]{Value: 50}},
+ YCenter: shared.OverlayPositionYCenterUnionParam{OfString: param.Opt[string]{Value: "bh_mul_0.5"}},
+ AnchorPoint: shared.OverlayPositionAnchorPointTopLeft,
+ },
+ },
+ },
+ },
+ },
+ }
+
+ url := client.Helper.BuildURL(shared.SrcOptionsParam{
+ URLEndpoint: "https://ik.imagekit.io/test_url_endpoint",
+ TransformationPosition: shared.TransformationPositionPath,
+ Src: "/base-image.jpg",
+ Transformation: transformation,
+ })
+
+ expected := "https://ik.imagekit.io/test_url_endpoint/tr:l-image,i-logo.png,lxc-50,lyc-bh_mul_0.5,lap-top_left,l-end/base-image.jpg"
+ if url != expected {
+ t.Errorf("Expected %s, got %s", expected, url)
+ }
+ })
}
diff --git a/usage_test.go b/usage_test.go
index 6792db9..9f1ec4a 100644
--- a/usage_test.go
+++ b/usage_test.go
@@ -15,6 +15,7 @@ import (
)
func TestUsage(t *testing.T) {
+ t.Skip("Mock server tests are disabled")
baseURL := "http://localhost:4010"
if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok {
baseURL = envURL
@@ -27,7 +28,6 @@ func TestUsage(t *testing.T) {
option.WithPrivateKey("My Private Key"),
option.WithPassword("My Password"),
)
- t.Skip("Prism tests are disabled")
response, err := client.Files.Upload(context.TODO(), imagekit.FileUploadParams{
File: io.Reader(bytes.NewBuffer([]byte("https://www.example.com/public-url.jpg"))),
FileName: "file-name.jpg",
diff --git a/webhook.go b/webhook.go
index abddde8..d49e2ac 100644
--- a/webhook.go
+++ b/webhook.go
@@ -75,9 +75,9 @@ func (r *WebhookService) Unwrap(payload []byte, headers http.Header, opts ...opt
type BaseWebhookEvent struct {
// Unique identifier for the event.
- ID string `json:"id,required"`
+ ID string `json:"id" api:"required"`
// The type of webhook event.
- Type string `json:"type,required"`
+ Type string `json:"type" api:"required"`
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
JSON struct {
ID respjson.Field
@@ -97,10 +97,10 @@ func (r *BaseWebhookEvent) UnmarshalJSON(data []byte) error {
// but the requested transformation could not be generated.
type UploadPostTransformErrorEvent struct {
// Timestamp of when the event occurred in ISO8601 format.
- CreatedAt time.Time `json:"created_at,required" format:"date-time"`
- Data UploadPostTransformErrorEventData `json:"data,required"`
- Request UploadPostTransformErrorEventRequest `json:"request,required"`
- Type constant.UploadPostTransformError `json:"type,required"`
+ CreatedAt time.Time `json:"created_at" api:"required" format:"date-time"`
+ Data UploadPostTransformErrorEventData `json:"data" api:"required"`
+ Request UploadPostTransformErrorEventRequest `json:"request" api:"required"`
+ Type constant.UploadPostTransformError `json:"type" default:"upload.post-transform.error"`
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
JSON struct {
CreatedAt respjson.Field
@@ -121,14 +121,14 @@ func (r *UploadPostTransformErrorEvent) UnmarshalJSON(data []byte) error {
type UploadPostTransformErrorEventData struct {
// Unique identifier of the originally uploaded file.
- FileID string `json:"fileId,required"`
+ FileID string `json:"fileId" api:"required"`
// Name of the file.
- Name string `json:"name,required"`
+ Name string `json:"name" api:"required"`
// Path of the file.
- Path string `json:"path,required"`
- Transformation UploadPostTransformErrorEventDataTransformation `json:"transformation,required"`
+ Path string `json:"path" api:"required"`
+ Transformation UploadPostTransformErrorEventDataTransformation `json:"transformation" api:"required"`
// URL of the attempted post-transformation.
- URL string `json:"url,required" format:"uri"`
+ URL string `json:"url" api:"required" format:"uri"`
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
JSON struct {
FileID respjson.Field
@@ -148,7 +148,7 @@ func (r *UploadPostTransformErrorEventData) UnmarshalJSON(data []byte) error {
}
type UploadPostTransformErrorEventDataTransformation struct {
- Error UploadPostTransformErrorEventDataTransformationError `json:"error,required"`
+ Error UploadPostTransformErrorEventDataTransformationError `json:"error" api:"required"`
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
JSON struct {
Error respjson.Field
@@ -165,7 +165,7 @@ func (r *UploadPostTransformErrorEventDataTransformation) UnmarshalJSON(data []b
type UploadPostTransformErrorEventDataTransformationError struct {
// Reason for the post-transformation failure.
- Reason string `json:"reason,required"`
+ Reason string `json:"reason" api:"required"`
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
JSON struct {
Reason respjson.Field
@@ -181,9 +181,9 @@ func (r *UploadPostTransformErrorEventDataTransformationError) UnmarshalJSON(dat
}
type UploadPostTransformErrorEventRequest struct {
- Transformation UploadPostTransformErrorEventRequestTransformation `json:"transformation,required"`
+ Transformation UploadPostTransformErrorEventRequestTransformation `json:"transformation" api:"required"`
// Unique identifier for the originating request.
- XRequestID string `json:"x_request_id,required"`
+ XRequestID string `json:"x_request_id" api:"required"`
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
JSON struct {
Transformation respjson.Field
@@ -203,7 +203,7 @@ type UploadPostTransformErrorEventRequestTransformation struct {
// Type of the requested post-transformation.
//
// Any of "transformation", "abs", "gif-to-video", "thumbnail".
- Type string `json:"type,required"`
+ Type string `json:"type" api:"required"`
// Only applicable if transformation type is 'abs'. Streaming protocol used.
//
// Any of "hls", "dash".
@@ -231,10 +231,10 @@ func (r *UploadPostTransformErrorEventRequestTransformation) UnmarshalJSON(data
// that each post-transformation generates a separate webhook event.
type UploadPostTransformSuccessEvent struct {
// Timestamp of when the event occurred in ISO8601 format.
- CreatedAt time.Time `json:"created_at,required" format:"date-time"`
- Data UploadPostTransformSuccessEventData `json:"data,required"`
- Request UploadPostTransformSuccessEventRequest `json:"request,required"`
- Type constant.UploadPostTransformSuccess `json:"type,required"`
+ CreatedAt time.Time `json:"created_at" api:"required" format:"date-time"`
+ Data UploadPostTransformSuccessEventData `json:"data" api:"required"`
+ Request UploadPostTransformSuccessEventRequest `json:"request" api:"required"`
+ Type constant.UploadPostTransformSuccess `json:"type" default:"upload.post-transform.success"`
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
JSON struct {
CreatedAt respjson.Field
@@ -255,11 +255,11 @@ func (r *UploadPostTransformSuccessEvent) UnmarshalJSON(data []byte) error {
type UploadPostTransformSuccessEventData struct {
// Unique identifier of the originally uploaded file.
- FileID string `json:"fileId,required"`
+ FileID string `json:"fileId" api:"required"`
// Name of the file.
- Name string `json:"name,required"`
+ Name string `json:"name" api:"required"`
// URL of the generated post-transformation.
- URL string `json:"url,required" format:"uri"`
+ URL string `json:"url" api:"required" format:"uri"`
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
JSON struct {
FileID respjson.Field
@@ -277,9 +277,9 @@ func (r *UploadPostTransformSuccessEventData) UnmarshalJSON(data []byte) error {
}
type UploadPostTransformSuccessEventRequest struct {
- Transformation UploadPostTransformSuccessEventRequestTransformation `json:"transformation,required"`
+ Transformation UploadPostTransformSuccessEventRequestTransformation `json:"transformation" api:"required"`
// Unique identifier for the originating request.
- XRequestID string `json:"x_request_id,required"`
+ XRequestID string `json:"x_request_id" api:"required"`
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
JSON struct {
Transformation respjson.Field
@@ -299,7 +299,7 @@ type UploadPostTransformSuccessEventRequestTransformation struct {
// Type of the requested post-transformation.
//
// Any of "transformation", "abs", "gif-to-video", "thumbnail".
- Type string `json:"type,required"`
+ Type string `json:"type" api:"required"`
// Only applicable if transformation type is 'abs'. Streaming protocol used.
//
// Any of "hls", "dash".
@@ -326,10 +326,10 @@ func (r *UploadPostTransformSuccessEventRequestTransformation) UnmarshalJSON(dat
// accepted, but the requested transformation could not be applied.
type UploadPreTransformErrorEvent struct {
// Timestamp of when the event occurred in ISO8601 format.
- CreatedAt time.Time `json:"created_at,required" format:"date-time"`
- Data UploadPreTransformErrorEventData `json:"data,required"`
- Request UploadPreTransformErrorEventRequest `json:"request,required"`
- Type constant.UploadPreTransformError `json:"type,required"`
+ CreatedAt time.Time `json:"created_at" api:"required" format:"date-time"`
+ Data UploadPreTransformErrorEventData `json:"data" api:"required"`
+ Request UploadPreTransformErrorEventRequest `json:"request" api:"required"`
+ Type constant.UploadPreTransformError `json:"type" default:"upload.pre-transform.error"`
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
JSON struct {
CreatedAt respjson.Field
@@ -350,10 +350,10 @@ func (r *UploadPreTransformErrorEvent) UnmarshalJSON(data []byte) error {
type UploadPreTransformErrorEventData struct {
// Name of the file.
- Name string `json:"name,required"`
+ Name string `json:"name" api:"required"`
// Path of the file.
- Path string `json:"path,required"`
- Transformation UploadPreTransformErrorEventDataTransformation `json:"transformation,required"`
+ Path string `json:"path" api:"required"`
+ Transformation UploadPreTransformErrorEventDataTransformation `json:"transformation" api:"required"`
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
JSON struct {
Name respjson.Field
@@ -371,7 +371,7 @@ func (r *UploadPreTransformErrorEventData) UnmarshalJSON(data []byte) error {
}
type UploadPreTransformErrorEventDataTransformation struct {
- Error UploadPreTransformErrorEventDataTransformationError `json:"error,required"`
+ Error UploadPreTransformErrorEventDataTransformationError `json:"error" api:"required"`
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
JSON struct {
Error respjson.Field
@@ -388,7 +388,7 @@ func (r *UploadPreTransformErrorEventDataTransformation) UnmarshalJSON(data []by
type UploadPreTransformErrorEventDataTransformationError struct {
// Reason for the pre-transformation failure.
- Reason string `json:"reason,required"`
+ Reason string `json:"reason" api:"required"`
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
JSON struct {
Reason respjson.Field
@@ -405,9 +405,9 @@ func (r *UploadPreTransformErrorEventDataTransformationError) UnmarshalJSON(data
type UploadPreTransformErrorEventRequest struct {
// The requested pre-transformation string.
- Transformation string `json:"transformation,required"`
+ Transformation string `json:"transformation" api:"required"`
// Unique identifier for the originating request.
- XRequestID string `json:"x_request_id,required"`
+ XRequestID string `json:"x_request_id" api:"required"`
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
JSON struct {
Transformation respjson.Field
@@ -428,11 +428,11 @@ func (r *UploadPreTransformErrorEventRequest) UnmarshalJSON(data []byte) error {
// Library.
type UploadPreTransformSuccessEvent struct {
// Timestamp of when the event occurred in ISO8601 format.
- CreatedAt time.Time `json:"created_at,required" format:"date-time"`
+ CreatedAt time.Time `json:"created_at" api:"required" format:"date-time"`
// Object containing details of a successful upload.
- Data UploadPreTransformSuccessEventData `json:"data,required"`
- Request UploadPreTransformSuccessEventRequest `json:"request,required"`
- Type constant.UploadPreTransformSuccess `json:"type,required"`
+ Data UploadPreTransformSuccessEventData `json:"data" api:"required"`
+ Request UploadPreTransformSuccessEventRequest `json:"request" api:"required"`
+ Type constant.UploadPreTransformSuccess `json:"type" default:"upload.pre-transform.success"`
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
JSON struct {
CreatedAt respjson.Field
@@ -454,7 +454,7 @@ func (r *UploadPreTransformSuccessEvent) UnmarshalJSON(data []byte) error {
// Object containing details of a successful upload.
type UploadPreTransformSuccessEventData struct {
// An array of tags assigned to the uploaded file by auto tagging.
- AITags []UploadPreTransformSuccessEventDataAITag `json:"AITags,nullable"`
+ AITags []UploadPreTransformSuccessEventDataAITag `json:"AITags" api:"nullable"`
// The audio codec used in the video (only for video).
AudioCodec string `json:"audioCodec"`
// The bit rate of the video in kbps (only for video).
@@ -463,7 +463,7 @@ type UploadPreTransformSuccessEventData struct {
// `x,y,width,height`. If `customCoordinates` are not defined, then it is `null`.
// Send `customCoordinates` in `responseFields` in API request to get the value of
// this field.
- CustomCoordinates string `json:"customCoordinates,nullable"`
+ CustomCoordinates string `json:"customCoordinates" api:"nullable"`
// A key-value data associated with the asset. Use `responseField` in API request
// to get `customMetadata` in the upload API response. Before setting any custom
// metadata on an asset, you have to create the field using custom metadata fields
@@ -525,7 +525,7 @@ type UploadPreTransformSuccessEventData struct {
// The array of tags associated with the asset. If no tags are set, it will be
// `null`. Send `tags` in `responseFields` in API request to get the value of this
// field.
- Tags []string `json:"tags,nullable"`
+ Tags []string `json:"tags" api:"nullable"`
// In the case of an image, a small thumbnail URL.
ThumbnailURL string `json:"thumbnailUrl"`
// A publicly accessible URL of the file.
@@ -642,7 +642,7 @@ type UploadPreTransformSuccessEventDataSelectedFieldsSchema struct {
//
// Any of "Text", "Textarea", "Number", "Date", "Boolean", "SingleSelect",
// "MultiSelect".
- Type string `json:"type,required"`
+ Type string `json:"type" api:"required"`
// The default value for this custom metadata field. The value should match the
// `type` of custom metadata field.
DefaultValue UploadPreTransformSuccessEventDataSelectedFieldsSchemaDefaultValueUnion `json:"defaultValue"`
@@ -940,9 +940,9 @@ func (r *UploadPreTransformSuccessEventDataVersionInfo) UnmarshalJSON(data []byt
type UploadPreTransformSuccessEventRequest struct {
// The requested pre-transformation string.
- Transformation string `json:"transformation,required"`
+ Transformation string `json:"transformation" api:"required"`
// Unique identifier for the originating request.
- XRequestID string `json:"x_request_id,required"`
+ XRequestID string `json:"x_request_id" api:"required"`
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
JSON struct {
Transformation respjson.Field
@@ -963,11 +963,11 @@ func (r *UploadPreTransformSuccessEventRequest) UnmarshalJSON(data []byte) error
// request. Use this for debugging and tracking transformation lifecycle.
type VideoTransformationAcceptedEvent struct {
// Timestamp when the event was created in ISO8601 format.
- CreatedAt time.Time `json:"created_at,required" format:"date-time"`
- Data VideoTransformationAcceptedEventData `json:"data,required"`
+ CreatedAt time.Time `json:"created_at" api:"required" format:"date-time"`
+ Data VideoTransformationAcceptedEventData `json:"data" api:"required"`
// Information about the original request that triggered the video transformation.
- Request VideoTransformationAcceptedEventRequest `json:"request,required"`
- Type constant.VideoTransformationAccepted `json:"type,required"`
+ Request VideoTransformationAcceptedEventRequest `json:"request" api:"required"`
+ Type constant.VideoTransformationAccepted `json:"type" default:"video.transformation.accepted"`
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
JSON struct {
CreatedAt respjson.Field
@@ -988,9 +988,9 @@ func (r *VideoTransformationAcceptedEvent) UnmarshalJSON(data []byte) error {
type VideoTransformationAcceptedEventData struct {
// Information about the source video asset being transformed.
- Asset VideoTransformationAcceptedEventDataAsset `json:"asset,required"`
+ Asset VideoTransformationAcceptedEventDataAsset `json:"asset" api:"required"`
// Base information about a video transformation request.
- Transformation VideoTransformationAcceptedEventDataTransformation `json:"transformation,required"`
+ Transformation VideoTransformationAcceptedEventDataTransformation `json:"transformation" api:"required"`
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
JSON struct {
Asset respjson.Field
@@ -1009,7 +1009,7 @@ func (r *VideoTransformationAcceptedEventData) UnmarshalJSON(data []byte) error
// Information about the source video asset being transformed.
type VideoTransformationAcceptedEventDataAsset struct {
// URL to download or access the source video file.
- URL string `json:"url,required" format:"uri"`
+ URL string `json:"url" api:"required" format:"uri"`
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
JSON struct {
URL respjson.Field
@@ -1034,7 +1034,7 @@ type VideoTransformationAcceptedEventDataTransformation struct {
// - `video-thumbnail`: Generate thumbnail image from video
//
// Any of "video-transformation", "gif-to-video", "video-thumbnail".
- Type string `json:"type,required"`
+ Type string `json:"type" api:"required"`
// Configuration options for video transformations.
Options VideoTransformationAcceptedEventDataTransformationOptions `json:"options"`
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
@@ -1101,9 +1101,9 @@ func (r *VideoTransformationAcceptedEventDataTransformationOptions) UnmarshalJSO
// Information about the original request that triggered the video transformation.
type VideoTransformationAcceptedEventRequest struct {
// Full URL of the transformation request that was submitted.
- URL string `json:"url,required" format:"uri"`
+ URL string `json:"url" api:"required" format:"uri"`
// Unique identifier for the originating transformation request.
- XRequestID string `json:"x_request_id,required"`
+ XRequestID string `json:"x_request_id" api:"required"`
// User-Agent header from the original request that triggered the transformation.
UserAgent string `json:"user_agent"`
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
@@ -1128,11 +1128,11 @@ func (r *VideoTransformationAcceptedEventRequest) UnmarshalJSON(data []byte) err
// support.
type VideoTransformationErrorEvent struct {
// Timestamp when the event was created in ISO8601 format.
- CreatedAt time.Time `json:"created_at,required" format:"date-time"`
- Data VideoTransformationErrorEventData `json:"data,required"`
+ CreatedAt time.Time `json:"created_at" api:"required" format:"date-time"`
+ Data VideoTransformationErrorEventData `json:"data" api:"required"`
// Information about the original request that triggered the video transformation.
- Request VideoTransformationErrorEventRequest `json:"request,required"`
- Type constant.VideoTransformationError `json:"type,required"`
+ Request VideoTransformationErrorEventRequest `json:"request" api:"required"`
+ Type constant.VideoTransformationError `json:"type" default:"video.transformation.error"`
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
JSON struct {
CreatedAt respjson.Field
@@ -1153,8 +1153,8 @@ func (r *VideoTransformationErrorEvent) UnmarshalJSON(data []byte) error {
type VideoTransformationErrorEventData struct {
// Information about the source video asset being transformed.
- Asset VideoTransformationErrorEventDataAsset `json:"asset,required"`
- Transformation VideoTransformationErrorEventDataTransformation `json:"transformation,required"`
+ Asset VideoTransformationErrorEventDataAsset `json:"asset" api:"required"`
+ Transformation VideoTransformationErrorEventDataTransformation `json:"transformation" api:"required"`
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
JSON struct {
Asset respjson.Field
@@ -1173,7 +1173,7 @@ func (r *VideoTransformationErrorEventData) UnmarshalJSON(data []byte) error {
// Information about the source video asset being transformed.
type VideoTransformationErrorEventDataAsset struct {
// URL to download or access the source video file.
- URL string `json:"url,required" format:"uri"`
+ URL string `json:"url" api:"required" format:"uri"`
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
JSON struct {
URL respjson.Field
@@ -1197,7 +1197,7 @@ type VideoTransformationErrorEventDataTransformation struct {
// - `video-thumbnail`: Generate thumbnail image from video
//
// Any of "video-transformation", "gif-to-video", "video-thumbnail".
- Type string `json:"type,required"`
+ Type string `json:"type" api:"required"`
// Details about the transformation error.
Error VideoTransformationErrorEventDataTransformationError `json:"error"`
// Configuration options for video transformations.
@@ -1227,7 +1227,7 @@ type VideoTransformationErrorEventDataTransformationError struct {
// - `internal_server_error`: Unexpected server error
//
// Any of "encoding_failed", "download_failed", "internal_server_error".
- Reason string `json:"reason,required"`
+ Reason string `json:"reason" api:"required"`
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
JSON struct {
Reason respjson.Field
@@ -1289,9 +1289,9 @@ func (r *VideoTransformationErrorEventDataTransformationOptions) UnmarshalJSON(d
// Information about the original request that triggered the video transformation.
type VideoTransformationErrorEventRequest struct {
// Full URL of the transformation request that was submitted.
- URL string `json:"url,required" format:"uri"`
+ URL string `json:"url" api:"required" format:"uri"`
// Unique identifier for the originating transformation request.
- XRequestID string `json:"x_request_id,required"`
+ XRequestID string `json:"x_request_id" api:"required"`
// User-Agent header from the original request that triggered the transformation.
UserAgent string `json:"user_agent"`
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
@@ -1316,11 +1316,11 @@ func (r *VideoTransformationErrorEventRequest) UnmarshalJSON(data []byte) error
// transformed video to users.
type VideoTransformationReadyEvent struct {
// Timestamp when the event was created in ISO8601 format.
- CreatedAt time.Time `json:"created_at,required" format:"date-time"`
- Data VideoTransformationReadyEventData `json:"data,required"`
+ CreatedAt time.Time `json:"created_at" api:"required" format:"date-time"`
+ Data VideoTransformationReadyEventData `json:"data" api:"required"`
// Information about the original request that triggered the video transformation.
- Request VideoTransformationReadyEventRequest `json:"request,required"`
- Type constant.VideoTransformationReady `json:"type,required"`
+ Request VideoTransformationReadyEventRequest `json:"request" api:"required"`
+ Type constant.VideoTransformationReady `json:"type" default:"video.transformation.ready"`
// Performance metrics for the transformation process.
Timings VideoTransformationReadyEventTimings `json:"timings"`
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
@@ -1344,8 +1344,8 @@ func (r *VideoTransformationReadyEvent) UnmarshalJSON(data []byte) error {
type VideoTransformationReadyEventData struct {
// Information about the source video asset being transformed.
- Asset VideoTransformationReadyEventDataAsset `json:"asset,required"`
- Transformation VideoTransformationReadyEventDataTransformation `json:"transformation,required"`
+ Asset VideoTransformationReadyEventDataAsset `json:"asset" api:"required"`
+ Transformation VideoTransformationReadyEventDataTransformation `json:"transformation" api:"required"`
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
JSON struct {
Asset respjson.Field
@@ -1364,7 +1364,7 @@ func (r *VideoTransformationReadyEventData) UnmarshalJSON(data []byte) error {
// Information about the source video asset being transformed.
type VideoTransformationReadyEventDataAsset struct {
// URL to download or access the source video file.
- URL string `json:"url,required" format:"uri"`
+ URL string `json:"url" api:"required" format:"uri"`
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
JSON struct {
URL respjson.Field
@@ -1388,7 +1388,7 @@ type VideoTransformationReadyEventDataTransformation struct {
// - `video-thumbnail`: Generate thumbnail image from video
//
// Any of "video-transformation", "gif-to-video", "video-thumbnail".
- Type string `json:"type,required"`
+ Type string `json:"type" api:"required"`
// Configuration options for video transformations.
Options VideoTransformationReadyEventDataTransformationOptions `json:"options"`
// Information about the transformed output video.
@@ -1456,7 +1456,7 @@ func (r *VideoTransformationReadyEventDataTransformationOptions) UnmarshalJSON(d
// Information about the transformed output video.
type VideoTransformationReadyEventDataTransformationOutput struct {
// URL to access the transformed video.
- URL string `json:"url,required" format:"uri"`
+ URL string `json:"url" api:"required" format:"uri"`
// Metadata of the output video file.
VideoMetadata VideoTransformationReadyEventDataTransformationOutputVideoMetadata `json:"video_metadata"`
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
@@ -1477,13 +1477,13 @@ func (r *VideoTransformationReadyEventDataTransformationOutput) UnmarshalJSON(da
// Metadata of the output video file.
type VideoTransformationReadyEventDataTransformationOutputVideoMetadata struct {
// Bitrate of the output video in bits per second.
- Bitrate int64 `json:"bitrate,required"`
+ Bitrate int64 `json:"bitrate" api:"required"`
// Duration of the output video in seconds.
- Duration float64 `json:"duration,required"`
+ Duration float64 `json:"duration" api:"required"`
// Height of the output video in pixels.
- Height int64 `json:"height,required"`
+ Height int64 `json:"height" api:"required"`
// Width of the output video in pixels.
- Width int64 `json:"width,required"`
+ Width int64 `json:"width" api:"required"`
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
JSON struct {
Bitrate respjson.Field
@@ -1506,9 +1506,9 @@ func (r *VideoTransformationReadyEventDataTransformationOutputVideoMetadata) Unm
// Information about the original request that triggered the video transformation.
type VideoTransformationReadyEventRequest struct {
// Full URL of the transformation request that was submitted.
- URL string `json:"url,required" format:"uri"`
+ URL string `json:"url" api:"required" format:"uri"`
// Unique identifier for the originating transformation request.
- XRequestID string `json:"x_request_id,required"`
+ XRequestID string `json:"x_request_id" api:"required"`
// User-Agent header from the original request that triggered the transformation.
UserAgent string `json:"user_agent"`
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
diff --git a/webhook_test.go b/webhook_test.go
index 23f90c8..2e2195a 100644
--- a/webhook_test.go
+++ b/webhook_test.go
@@ -22,13 +22,13 @@ func TestWebhookUnwrap(t *testing.T) {
payload := []byte(`{"id":"id","type":"video.transformation.accepted","created_at":"2019-12-27T18:11:19.117Z","data":{"asset":{"url":"https://example.com"},"transformation":{"type":"video-transformation","options":{"audio_codec":"aac","auto_rotate":true,"format":"mp4","quality":0,"stream_protocol":"HLS","variants":["string"],"video_codec":"h264"}}},"request":{"url":"https://example.com","x_request_id":"x_request_id","user_agent":"user_agent"}}`)
wh, err := standardwebhooks.NewWebhook("whsec_c2VjcmV0Cg==")
if err != nil {
- t.Error("Failed to sign test webhook message")
+ t.Fatal("Failed to sign test webhook message", err)
}
msgID := "1"
now := time.Now()
sig, err := wh.Sign(msgID, now, payload)
if err != nil {
- t.Error("Failed to sign test webhook message:", err)
+ t.Fatal("Failed to sign test webhook message:", err)
}
headers := make(http.Header)
headers.Set("webhook-signature", sig)
@@ -36,6 +36,6 @@ func TestWebhookUnwrap(t *testing.T) {
headers.Set("webhook-timestamp", strconv.FormatInt(now.Unix(), 10))
_, err = client.Webhooks.Unwrap(payload, headers)
if err != nil {
- t.Error("Failed to unwrap webhook:", err)
+ t.Fatal("Failed to unwrap webhook:", err)
}
}