diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 6731678f..cd52c1e8 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "7.4.0" + ".": "7.5.0" } diff --git a/.stats.yml b/.stats.yml index df5aafb6..aae6cba6 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 47 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/imagekit-inc%2Fimagekit-63aff1629530786015da3c86131afa8a9b60545d488884b77641f1d4b89c6e9d.yml -openapi_spec_hash: 586d357bd7e5217d240a99e0d83c6d1f -config_hash: 47cb702ee2cb52c58d803ae39ade9b44 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/imagekit-inc%2Fimagekit-d73a37dc3426586109bd153f02c6a605036b6a7396bba5173d013468c5291ce6.yml +openapi_spec_hash: c193c6e557ff477481ec8d5ac8a0c96e +config_hash: 32b155378f65c234d3abeb18519fb3cd diff --git a/CHANGELOG.md b/CHANGELOG.md index eae4b424..4d406d4b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,37 @@ # Changelog +## 7.5.0 (2026-04-10) + +Full Changelog: [v7.4.0...v7.5.0](https://github.com/imagekit-developer/imagekit-nodejs/compare/v7.4.0...v7.5.0) + +### Features + +* **api:** dam related webhook events ([d2bc9ce](https://github.com/imagekit-developer/imagekit-nodejs/commit/d2bc9ce8f62be8c4da65f655b8113a0bca685c37)) +* **api:** fix spec indentation ([79ae799](https://github.com/imagekit-developer/imagekit-nodejs/commit/79ae799823f2dcdde7eece7fc0588916e453537e)) +* **api:** indentation fix ([65c6eec](https://github.com/imagekit-developer/imagekit-nodejs/commit/65c6eec03f5907dedd73500eeba8f9aa0de1f66c)) +* **api:** merge with main to bring back missing parameters ([bd6474f](https://github.com/imagekit-developer/imagekit-nodejs/commit/bd6474f9af40cae66818a260f21087d4e19f76af)) +* **api:** update webhook event names and remove DAM prefix ([a86f04c](https://github.com/imagekit-developer/imagekit-nodejs/commit/a86f04c6c187b3bedced5146a5ca717eccc8492e)) +* **docs:** simplify authentication parameters example in README ([c14843b](https://github.com/imagekit-developer/imagekit-nodejs/commit/c14843b8e77bc24a871ed594962105fbfa7fa38a)) + + +### Bug Fixes + +* **api:** rename DamFile events to File for consistency ([24b7f4b](https://github.com/imagekit-developer/imagekit-nodejs/commit/24b7f4b33977691dadbed303fd10acd532dcd5c1)) + + +### Chores + +* **internal:** codegen related update ([eb9b6dc](https://github.com/imagekit-developer/imagekit-nodejs/commit/eb9b6dc079d3c174b37863892e3dbc5a6ca0a2d5)) +* **internal:** codegen related update ([e2cf4dc](https://github.com/imagekit-developer/imagekit-nodejs/commit/e2cf4dcd2be96f3d7d60244e40592aa94f393e8c)) +* **internal:** fix MCP server import ordering ([31100e2](https://github.com/imagekit-developer/imagekit-nodejs/commit/31100e2ee17426153efea46f8787d2cfb5e2a9ee)) +* **internal:** show error causes in MCP servers when running in local mode ([7f1ff53](https://github.com/imagekit-developer/imagekit-nodejs/commit/7f1ff53ef5fedeb78fd73571664789c858133351)) +* **mcp-server:** increase local docs search result count from 5 to 10 ([35dc080](https://github.com/imagekit-developer/imagekit-nodejs/commit/35dc080ca7ef76d09db5152fbc8e3af285581822)) + + +### Documentation + +* improve examples ([cbfbebc](https://github.com/imagekit-developer/imagekit-nodejs/commit/cbfbebc7d6ecb5e71207e9885f7b3195d1d1c316)) + ## 7.4.0 (2026-04-06) Full Changelog: [v7.3.0...v7.4.0](https://github.com/imagekit-developer/imagekit-nodejs/compare/v7.3.0...v7.4.0) diff --git a/api.md b/api.md index 94780b7e..742e7a39 100644 --- a/api.md +++ b/api.md @@ -229,6 +229,11 @@ Methods: Types: - BaseWebhookEvent +- FileCreateEvent +- FileDeleteEvent +- FileUpdateEvent +- FileVersionCreateEvent +- FileVersionDeleteEvent - UploadPostTransformErrorEvent - UploadPostTransformSuccessEvent - UploadPreTransformErrorEvent diff --git a/package.json b/package.json index af9466f2..10029643 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@imagekit/nodejs", - "version": "7.4.0", + "version": "7.5.0", "description": "Offical NodeJS SDK for ImageKit.io integration", "author": "Image Kit ", "types": "dist/index.d.ts", diff --git a/packages/mcp-server/manifest.json b/packages/mcp-server/manifest.json index 934e4661..c9dbefa4 100644 --- a/packages/mcp-server/manifest.json +++ b/packages/mcp-server/manifest.json @@ -1,7 +1,7 @@ { "dxt_version": "0.2", "name": "@imagekit/api-mcp", - "version": "7.4.0", + "version": "7.5.0", "description": "The official MCP Server for the Image Kit API", "author": { "name": "Image Kit", diff --git a/packages/mcp-server/package.json b/packages/mcp-server/package.json index 26fcf65c..d3b791d3 100644 --- a/packages/mcp-server/package.json +++ b/packages/mcp-server/package.json @@ -1,6 +1,6 @@ { "name": "@imagekit/api-mcp", - "version": "7.4.0", + "version": "7.5.0", "description": "The official MCP Server for the Image Kit API", "author": "Image Kit ", "types": "dist/index.d.ts", diff --git a/packages/mcp-server/src/code-tool-worker.ts b/packages/mcp-server/src/code-tool-worker.ts index 23ff1794..07b79f57 100644 --- a/packages/mcp-server/src/code-tool-worker.ts +++ b/packages/mcp-server/src/code-tool-worker.ts @@ -233,7 +233,8 @@ function makeSdkProxy(obj: T, { path, isBelievedBad = false }: function parseError(code: string, error: unknown): string | undefined { if (!(error instanceof Error)) return; - const message = error.name ? `${error.name}: ${error.message}` : error.message; + const cause = error.cause instanceof Error ? `: ${error.cause.message}` : ''; + const message = error.name ? `${error.name}: ${error.message}${cause}` : `${error.message}${cause}`; try { // Deno uses V8; the first ":LINE:COLUMN" is the top of stack. const lineNumber = error.stack?.match(/:([0-9]+):[0-9]+/)?.[1]; diff --git a/packages/mcp-server/src/docs-search-tool.ts b/packages/mcp-server/src/docs-search-tool.ts index 476e7007..25c9c7ea 100644 --- a/packages/mcp-server/src/docs-search-tool.ts +++ b/packages/mcp-server/src/docs-search-tool.ts @@ -63,7 +63,7 @@ async function searchLocal(args: Record): Promise { query, language, detail, - maxResults: 5, + maxResults: 10, }).results; } diff --git a/packages/mcp-server/src/instructions.ts b/packages/mcp-server/src/instructions.ts index 09c278fd..ffe655a0 100644 --- a/packages/mcp-server/src/instructions.ts +++ b/packages/mcp-server/src/instructions.ts @@ -1,8 +1,8 @@ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. import fs from 'fs/promises'; -import { readEnv } from './util'; import { getLogger } from './logger'; +import { readEnv } from './util'; const INSTRUCTIONS_CACHE_TTL_MS = 15 * 60 * 1000; // 15 minutes diff --git a/packages/mcp-server/src/local-docs-search.ts b/packages/mcp-server/src/local-docs-search.ts index 294e25cf..5388085b 100644 --- a/packages/mcp-server/src/local-docs-search.ts +++ b/packages/mcp-server/src/local-docs-search.ts @@ -77,7 +77,7 @@ const EMBEDDED_METHODS: MethodEntry[] = [ csharp: { method: 'CustomMetadataFields.Create', example: - 'CustomMetadataFieldCreateParams parameters = new()\n{\n Label = "price",\n Name = "price",\n Schema = new()\n {\n Type = Type.Number,\n DefaultValue = "string",\n IsValueRequired = true,\n MaxLength = 0,\n MaxValue = 3000,\n MinLength = 0,\n MinValue = 1000,\n SelectOptions =\n [\n "small", "medium", "large", 30, 40, true\n ],\n },\n};\n\nvar customMetadataField = await client.CustomMetadataFields.Create(parameters);\n\nConsole.WriteLine(customMetadataField);', + 'CustomMetadataFieldCreateParams parameters = new()\n{\n Label = "price",\n Name = "price",\n Schema = new()\n {\n Type = Type.Number,\n DefaultValue = new(\n\n [\n new UnnamedSchemaWithArrayParent1(true),\n new UnnamedSchemaWithArrayParent1(10),\n new UnnamedSchemaWithArrayParent1("Hello"),\n ]\n ),\n IsValueRequired = true,\n MaxLength = 0,\n MaxValue = 3000,\n MinLength = 0,\n MinValue = 1000,\n SelectOptions =\n [\n "small", "medium", "large", 30, 40, true\n ],\n },\n};\n\nvar customMetadataField = await client.CustomMetadataFields.Create(parameters);\n\nConsole.WriteLine(customMetadataField);', }, go: { method: 'client.CustomMetadataFields.New', @@ -96,7 +96,7 @@ const EMBEDDED_METHODS: MethodEntry[] = [ php: { method: 'customMetadataFields->create', example: - "customMetadataFields->create(\n label: 'price',\n name: 'price',\n schema: [\n 'type' => 'Number',\n 'defaultValue' => 'string',\n 'isValueRequired' => true,\n 'maxLength' => 0,\n 'maxValue' => 3000,\n 'minLength' => 0,\n 'minValue' => 1000,\n 'selectOptions' => ['small', 'medium', 'large', 30, 40, true],\n ],\n);\n\nvar_dump($customMetadataField);", + "customMetadataFields->create(\n label: 'price',\n name: 'price',\n schema: [\n 'type' => 'Number',\n 'defaultValue' => [true, 10, 'Hello'],\n 'isValueRequired' => true,\n 'maxLength' => 0,\n 'maxValue' => 3000,\n 'minLength' => 0,\n 'minValue' => 1000,\n 'selectOptions' => ['small', 'medium', 'large', 30, 40, true],\n ],\n);\n\nvar_dump($customMetadataField);", }, python: { method: 'custom_metadata_fields.create', @@ -221,7 +221,7 @@ const EMBEDDED_METHODS: MethodEntry[] = [ php: { method: 'customMetadataFields->update', example: - "customMetadataFields->update(\n 'id',\n label: 'price',\n schema: [\n 'defaultValue' => 'string',\n 'isValueRequired' => true,\n 'maxLength' => 0,\n 'maxValue' => 3000,\n 'minLength' => 0,\n 'minValue' => 1000,\n 'selectOptions' => ['small', 'medium', 'large', 30, 40, true],\n ],\n);\n\nvar_dump($customMetadataField);", + "customMetadataFields->update(\n 'id',\n label: 'price',\n schema: [\n 'defaultValue' => [true, 10, 'Hello'],\n 'isValueRequired' => true,\n 'maxLength' => 0,\n 'maxValue' => 3000,\n 'minLength' => 0,\n 'minValue' => 1000,\n 'selectOptions' => ['small', 'medium', 'large', 30, 40, true],\n ],\n);\n\nvar_dump($customMetadataField);", }, python: { method: 'custom_metadata_fields.update', @@ -366,7 +366,7 @@ const EMBEDDED_METHODS: MethodEntry[] = [ php: { method: 'files->upload', example: - "files->upload(\n file: 'file',\n fileName: 'fileName',\n token: 'token',\n checks: \"\\\"request.folder\\\" : \\\"marketing/\\\"\\n\",\n customCoordinates: 'customCoordinates',\n customMetadata: ['brand' => 'bar', 'color' => 'bar'],\n description: 'Running shoes',\n expire: 0,\n extensions: [\n [\n 'name' => 'remove-bg',\n 'options' => [\n 'addShadow' => true,\n 'bgColor' => 'bg_color',\n 'bgImageURL' => 'bg_image_url',\n 'semitransparency' => true,\n ],\n ],\n ['maxTags' => 5, 'minConfidence' => 95, 'name' => 'google-auto-tagging'],\n ['name' => 'ai-auto-description'],\n [\n 'name' => 'ai-tasks',\n 'tasks' => [\n [\n 'instruction' => 'What types of clothing items are visible in this image?',\n 'type' => 'select_tags',\n 'maxSelections' => 1,\n 'minSelections' => 0,\n 'vocabulary' => ['shirt', 'tshirt', 'dress', 'trousers', 'jacket'],\n ],\n [\n 'instruction' => 'Is this a luxury or high-end fashion item?',\n 'type' => 'yes_no',\n 'onNo' => [\n 'addTags' => ['luxury', 'premium'],\n 'removeTags' => ['budget', 'affordable'],\n 'setMetadata' => [['field' => 'price_range', 'value' => 'premium']],\n 'unsetMetadata' => [['field' => 'price_range']],\n ],\n 'onUnknown' => [\n 'addTags' => ['luxury', 'premium'],\n 'removeTags' => ['budget', 'affordable'],\n 'setMetadata' => [['field' => 'price_range', 'value' => 'premium']],\n 'unsetMetadata' => [['field' => 'price_range']],\n ],\n 'onYes' => [\n 'addTags' => ['luxury', 'premium'],\n 'removeTags' => ['budget', 'affordable'],\n 'setMetadata' => [['field' => 'price_range', 'value' => 'premium']],\n 'unsetMetadata' => [['field' => 'price_range']],\n ],\n ],\n ],\n ],\n ['id' => 'ext_abc123', 'name' => 'saved-extension'],\n ],\n folder: 'folder',\n isPrivateFile: true,\n isPublished: true,\n overwriteAITags: true,\n overwriteCustomMetadata: true,\n overwriteFile: true,\n overwriteTags: true,\n publicKey: 'publicKey',\n responseFields: ['tags', 'customCoordinates', 'isPrivateFile'],\n signature: 'signature',\n tags: ['t-shirt', 'round-neck', 'men'],\n transformation: [\n 'post' => [\n ['type' => 'thumbnail', 'value' => 'w-150,h-150'],\n [\n 'protocol' => 'dash',\n 'type' => 'abs',\n 'value' => 'sr-240_360_480_720_1080',\n ],\n ],\n 'pre' => 'w-300,h-300,q-80',\n ],\n useUniqueFileName: true,\n webhookURL: 'https://example.com',\n);\n\nvar_dump($response);", + "files->upload(\n file: FileParam::fromString('Example data', filename: uniqid('file-upload-', true)),\n fileName: 'fileName',\n token: 'token',\n checks: \"\\\"request.folder\\\" : \\\"marketing/\\\"\\n\",\n customCoordinates: 'customCoordinates',\n customMetadata: ['brand' => 'bar', 'color' => 'bar'],\n description: 'Running shoes',\n expire: 0,\n extensions: [\n [\n 'name' => 'remove-bg',\n 'options' => [\n 'addShadow' => true,\n 'bgColor' => 'bg_color',\n 'bgImageURL' => 'bg_image_url',\n 'semitransparency' => true,\n ],\n ],\n ['maxTags' => 5, 'minConfidence' => 95, 'name' => 'google-auto-tagging'],\n ['name' => 'ai-auto-description'],\n [\n 'name' => 'ai-tasks',\n 'tasks' => [\n [\n 'instruction' => 'What types of clothing items are visible in this image?',\n 'type' => 'select_tags',\n 'maxSelections' => 1,\n 'minSelections' => 0,\n 'vocabulary' => ['shirt', 'tshirt', 'dress', 'trousers', 'jacket'],\n ],\n [\n 'instruction' => 'Is this a luxury or high-end fashion item?',\n 'type' => 'yes_no',\n 'onNo' => [\n 'addTags' => ['luxury', 'premium'],\n 'removeTags' => ['budget', 'affordable'],\n 'setMetadata' => [['field' => 'price_range', 'value' => 'premium']],\n 'unsetMetadata' => [['field' => 'price_range']],\n ],\n 'onUnknown' => [\n 'addTags' => ['luxury', 'premium'],\n 'removeTags' => ['budget', 'affordable'],\n 'setMetadata' => [['field' => 'price_range', 'value' => 'premium']],\n 'unsetMetadata' => [['field' => 'price_range']],\n ],\n 'onYes' => [\n 'addTags' => ['luxury', 'premium'],\n 'removeTags' => ['budget', 'affordable'],\n 'setMetadata' => [['field' => 'price_range', 'value' => 'premium']],\n 'unsetMetadata' => [['field' => 'price_range']],\n ],\n ],\n ],\n ],\n ['id' => 'ext_abc123', 'name' => 'saved-extension'],\n ],\n folder: 'folder',\n isPrivateFile: true,\n isPublished: true,\n overwriteAITags: true,\n overwriteCustomMetadata: true,\n overwriteFile: true,\n overwriteTags: true,\n publicKey: 'publicKey',\n responseFields: ['tags', 'customCoordinates', 'isPrivateFile'],\n signature: 'signature',\n tags: ['t-shirt', 'round-neck', 'men'],\n transformation: [\n 'post' => [\n ['type' => 'thumbnail', 'value' => 'w-150,h-150'],\n [\n 'protocol' => 'dash',\n 'type' => 'abs',\n 'value' => 'sr-240_360_480_720_1080',\n ],\n ],\n 'pre' => 'w-300,h-300,q-80',\n ],\n useUniqueFileName: true,\n webhookURL: 'https://example.com',\n);\n\nvar_dump($response);", }, python: { method: 'files.upload', @@ -489,7 +489,7 @@ const EMBEDDED_METHODS: MethodEntry[] = [ php: { method: 'files->update', example: - "files->update(\n 'fileId',\n customCoordinates: 'customCoordinates',\n customMetadata: ['foo' => 'bar'],\n description: 'description',\n extensions: [\n [\n 'name' => 'remove-bg',\n 'options' => [\n 'addShadow' => true,\n 'bgColor' => 'bg_color',\n 'bgImageURL' => 'bg_image_url',\n 'semitransparency' => true,\n ],\n ],\n ['maxTags' => 5, 'minConfidence' => 95, 'name' => 'google-auto-tagging'],\n ['name' => 'ai-auto-description'],\n [\n 'name' => 'ai-tasks',\n 'tasks' => [\n [\n 'instruction' => 'What types of clothing items are visible in this image?',\n 'type' => 'select_tags',\n 'maxSelections' => 1,\n 'minSelections' => 0,\n 'vocabulary' => ['shirt', 'tshirt', 'dress', 'trousers', 'jacket'],\n ],\n [\n 'instruction' => 'Is this a luxury or high-end fashion item?',\n 'type' => 'yes_no',\n 'onNo' => [\n 'addTags' => ['luxury', 'premium'],\n 'removeTags' => ['budget', 'affordable'],\n 'setMetadata' => [['field' => 'price_range', 'value' => 'premium']],\n 'unsetMetadata' => [['field' => 'price_range']],\n ],\n 'onUnknown' => [\n 'addTags' => ['luxury', 'premium'],\n 'removeTags' => ['budget', 'affordable'],\n 'setMetadata' => [['field' => 'price_range', 'value' => 'premium']],\n 'unsetMetadata' => [['field' => 'price_range']],\n ],\n 'onYes' => [\n 'addTags' => ['luxury', 'premium'],\n 'removeTags' => ['budget', 'affordable'],\n 'setMetadata' => [['field' => 'price_range', 'value' => 'premium']],\n 'unsetMetadata' => [['field' => 'price_range']],\n ],\n ],\n ],\n ],\n ['id' => 'ext_abc123', 'name' => 'saved-extension'],\n ],\n removeAITags: ['string'],\n tags: ['tag1', 'tag2'],\n webhookURL: 'https://example.com',\n publish: ['isPublished' => true, 'includeFileVersions' => true],\n);\n\nvar_dump($file);", + "files->update(\n 'fileId',\n customCoordinates: 'customCoordinates',\n customMetadata: ['foo' => 'bar'],\n description: 'description',\n extensions: [\n [\n 'name' => 'remove-bg',\n 'options' => [\n 'addShadow' => true,\n 'bgColor' => 'bg_color',\n 'bgImageURL' => 'bg_image_url',\n 'semitransparency' => true,\n ],\n ],\n ['maxTags' => 5, 'minConfidence' => 95, 'name' => 'google-auto-tagging'],\n ['name' => 'ai-auto-description'],\n [\n 'name' => 'ai-tasks',\n 'tasks' => [\n [\n 'instruction' => 'What types of clothing items are visible in this image?',\n 'type' => 'select_tags',\n 'maxSelections' => 1,\n 'minSelections' => 0,\n 'vocabulary' => ['shirt', 'tshirt', 'dress', 'trousers', 'jacket'],\n ],\n [\n 'instruction' => 'Is this a luxury or high-end fashion item?',\n 'type' => 'yes_no',\n 'onNo' => [\n 'addTags' => ['luxury', 'premium'],\n 'removeTags' => ['budget', 'affordable'],\n 'setMetadata' => [['field' => 'price_range', 'value' => 'premium']],\n 'unsetMetadata' => [['field' => 'price_range']],\n ],\n 'onUnknown' => [\n 'addTags' => ['luxury', 'premium'],\n 'removeTags' => ['budget', 'affordable'],\n 'setMetadata' => [['field' => 'price_range', 'value' => 'premium']],\n 'unsetMetadata' => [['field' => 'price_range']],\n ],\n 'onYes' => [\n 'addTags' => ['luxury', 'premium'],\n 'removeTags' => ['budget', 'affordable'],\n 'setMetadata' => [['field' => 'price_range', 'value' => 'premium']],\n 'unsetMetadata' => [['field' => 'price_range']],\n ],\n ],\n ],\n ],\n ['id' => 'ext_abc123', 'name' => 'saved-extension'],\n ],\n removeAITags: 'all',\n tags: ['tag1', 'tag2'],\n webhookURL: 'https://example.com',\n publish: ['isPublished' => true, 'includeFileVersions' => true],\n);\n\nvar_dump($file);", }, python: { method: 'files.update', @@ -2940,7 +2940,7 @@ const EMBEDDED_METHODS: MethodEntry[] = [ php: { method: 'beta->v2->files->upload', example: - "beta->v2->files->upload(\n file: 'file',\n fileName: 'fileName',\n token: 'token',\n checks: \"\\\"request.folder\\\" : \\\"marketing/\\\"\\n\",\n customCoordinates: 'customCoordinates',\n customMetadata: ['brand' => 'bar', 'color' => 'bar'],\n description: 'Running shoes',\n extensions: [\n [\n 'name' => 'remove-bg',\n 'options' => [\n 'addShadow' => true,\n 'bgColor' => 'bg_color',\n 'bgImageURL' => 'bg_image_url',\n 'semitransparency' => true,\n ],\n ],\n ['maxTags' => 5, 'minConfidence' => 95, 'name' => 'google-auto-tagging'],\n ['name' => 'ai-auto-description'],\n [\n 'name' => 'ai-tasks',\n 'tasks' => [\n [\n 'instruction' => 'What types of clothing items are visible in this image?',\n 'type' => 'select_tags',\n 'maxSelections' => 1,\n 'minSelections' => 0,\n 'vocabulary' => ['shirt', 'tshirt', 'dress', 'trousers', 'jacket'],\n ],\n [\n 'instruction' => 'Is this a luxury or high-end fashion item?',\n 'type' => 'yes_no',\n 'onNo' => [\n 'addTags' => ['luxury', 'premium'],\n 'removeTags' => ['budget', 'affordable'],\n 'setMetadata' => [['field' => 'price_range', 'value' => 'premium']],\n 'unsetMetadata' => [['field' => 'price_range']],\n ],\n 'onUnknown' => [\n 'addTags' => ['luxury', 'premium'],\n 'removeTags' => ['budget', 'affordable'],\n 'setMetadata' => [['field' => 'price_range', 'value' => 'premium']],\n 'unsetMetadata' => [['field' => 'price_range']],\n ],\n 'onYes' => [\n 'addTags' => ['luxury', 'premium'],\n 'removeTags' => ['budget', 'affordable'],\n 'setMetadata' => [['field' => 'price_range', 'value' => 'premium']],\n 'unsetMetadata' => [['field' => 'price_range']],\n ],\n ],\n ],\n ],\n ['id' => 'ext_abc123', 'name' => 'saved-extension'],\n ],\n folder: 'folder',\n isPrivateFile: true,\n isPublished: true,\n overwriteAITags: true,\n overwriteCustomMetadata: true,\n overwriteFile: true,\n overwriteTags: true,\n responseFields: ['tags', 'customCoordinates', 'isPrivateFile'],\n tags: ['t-shirt', 'round-neck', 'men'],\n transformation: [\n 'post' => [\n ['type' => 'thumbnail', 'value' => 'w-150,h-150'],\n [\n 'protocol' => 'dash',\n 'type' => 'abs',\n 'value' => 'sr-240_360_480_720_1080',\n ],\n ],\n 'pre' => 'w-300,h-300,q-80',\n ],\n useUniqueFileName: true,\n webhookURL: 'https://example.com',\n);\n\nvar_dump($response);", + "beta->v2->files->upload(\n file: FileParam::fromString('Example data', filename: uniqid('file-upload-', true)),\n fileName: 'fileName',\n token: 'token',\n checks: \"\\\"request.folder\\\" : \\\"marketing/\\\"\\n\",\n customCoordinates: 'customCoordinates',\n customMetadata: ['brand' => 'bar', 'color' => 'bar'],\n description: 'Running shoes',\n extensions: [\n [\n 'name' => 'remove-bg',\n 'options' => [\n 'addShadow' => true,\n 'bgColor' => 'bg_color',\n 'bgImageURL' => 'bg_image_url',\n 'semitransparency' => true,\n ],\n ],\n ['maxTags' => 5, 'minConfidence' => 95, 'name' => 'google-auto-tagging'],\n ['name' => 'ai-auto-description'],\n [\n 'name' => 'ai-tasks',\n 'tasks' => [\n [\n 'instruction' => 'What types of clothing items are visible in this image?',\n 'type' => 'select_tags',\n 'maxSelections' => 1,\n 'minSelections' => 0,\n 'vocabulary' => ['shirt', 'tshirt', 'dress', 'trousers', 'jacket'],\n ],\n [\n 'instruction' => 'Is this a luxury or high-end fashion item?',\n 'type' => 'yes_no',\n 'onNo' => [\n 'addTags' => ['luxury', 'premium'],\n 'removeTags' => ['budget', 'affordable'],\n 'setMetadata' => [['field' => 'price_range', 'value' => 'premium']],\n 'unsetMetadata' => [['field' => 'price_range']],\n ],\n 'onUnknown' => [\n 'addTags' => ['luxury', 'premium'],\n 'removeTags' => ['budget', 'affordable'],\n 'setMetadata' => [['field' => 'price_range', 'value' => 'premium']],\n 'unsetMetadata' => [['field' => 'price_range']],\n ],\n 'onYes' => [\n 'addTags' => ['luxury', 'premium'],\n 'removeTags' => ['budget', 'affordable'],\n 'setMetadata' => [['field' => 'price_range', 'value' => 'premium']],\n 'unsetMetadata' => [['field' => 'price_range']],\n ],\n ],\n ],\n ],\n ['id' => 'ext_abc123', 'name' => 'saved-extension'],\n ],\n folder: 'folder',\n isPrivateFile: true,\n isPublished: true,\n overwriteAITags: true,\n overwriteCustomMetadata: true,\n overwriteFile: true,\n overwriteTags: true,\n responseFields: ['tags', 'customCoordinates', 'isPrivateFile'],\n tags: ['t-shirt', 'round-neck', 'men'],\n transformation: [\n 'post' => [\n ['type' => 'thumbnail', 'value' => 'w-150,h-150'],\n [\n 'protocol' => 'dash',\n 'type' => 'abs',\n 'value' => 'sr-240_360_480_720_1080',\n ],\n ],\n 'pre' => 'w-300,h-300,q-80',\n ],\n useUniqueFileName: true,\n webhookURL: 'https://example.com',\n);\n\nvar_dump($response);", }, python: { method: 'beta.v2.files.upload', @@ -3100,7 +3100,7 @@ const EMBEDDED_READMES: { language: string; content: string }[] = [ { language: 'php', content: - '# Image Kit PHP API Library\n\nThe Image Kit PHP library provides convenient access to the Image Kit REST API from any PHP 8.1.0+ application.\n\n## Installation\n\nTo use this package, install via Composer by adding the following to your application\'s `composer.json`:\n\n```json\n{\n "repositories": [\n {\n "type": "vcs",\n "url": "git@github.com:stainless-sdks/imagekit-php.git"\n }\n ],\n "require": {\n "imagekit/imagekit": "dev-main"\n }\n}\n```\n\n## Usage\n\n```php\nfiles->upload(file: \'file\', fileName: \'file-name.jpg\');\n\nvar_dump($response->videoCodec);\n```', + '# Image Kit PHP API Library\n\nThe Image Kit PHP library provides convenient access to the Image Kit REST API from any PHP 8.1.0+ application.\n\n## Installation\n\nTo use this package, install via Composer by adding the following to your application\'s `composer.json`:\n\n```json\n{\n "repositories": [\n {\n "type": "vcs",\n "url": "git@github.com:stainless-sdks/imagekit-php.git"\n }\n ],\n "require": {\n "imagekit/imagekit": "dev-main"\n }\n}\n```\n\n## Usage\n\n```php\nfiles->upload(\n file: FileParam::fromString(\'https://www.example.com/public-url.jpg\', filename: uniqid(\'file-upload-\', true)),\n fileName: \'file-name.jpg\',\n);\n\nvar_dump($response->videoCodec);\n```', }, ]; diff --git a/packages/mcp-server/src/server.ts b/packages/mcp-server/src/server.ts index c9bb80fa..4668d948 100644 --- a/packages/mcp-server/src/server.ts +++ b/packages/mcp-server/src/server.ts @@ -28,7 +28,7 @@ export const newMcpServer = async ({ new McpServer( { name: 'imagekit_nodejs_api', - version: '7.4.0', + version: '7.5.0', }, { instructions: await getInstructions({ stainlessApiKey, customInstructionsPath }), diff --git a/packages/mcp-server/src/util.ts b/packages/mcp-server/src/util.ts index 40ed5501..069a2b47 100644 --- a/packages/mcp-server/src/util.ts +++ b/packages/mcp-server/src/util.ts @@ -2,9 +2,9 @@ export const readEnv = (env: string): string | undefined => { if (typeof (globalThis as any).process !== 'undefined') { - return (globalThis as any).process.env?.[env]?.trim(); + return (globalThis as any).process.env?.[env]?.trim() || undefined; } else if (typeof (globalThis as any).Deno !== 'undefined') { - return (globalThis as any).Deno.env?.get?.(env)?.trim(); + return (globalThis as any).Deno.env?.get?.(env)?.trim() || undefined; } return; }; diff --git a/src/client.ts b/src/client.ts index 7be4e749..77700f16 100644 --- a/src/client.ts +++ b/src/client.ts @@ -35,6 +35,11 @@ import { } from './resources/saved-extensions'; import { BaseWebhookEvent, + FileCreateEvent, + FileDeleteEvent, + FileUpdateEvent, + FileVersionCreateEvent, + FileVersionDeleteEvent, UnsafeUnwrapWebhookEvent, UnwrapWebhookEvent, UploadPostTransformErrorEvent, @@ -917,6 +922,11 @@ export declare namespace ImageKit { export { Webhooks as Webhooks, type BaseWebhookEvent as BaseWebhookEvent, + type FileCreateEvent as FileCreateEvent, + type FileDeleteEvent as FileDeleteEvent, + type FileUpdateEvent as FileUpdateEvent, + type FileVersionCreateEvent as FileVersionCreateEvent, + type FileVersionDeleteEvent as FileVersionDeleteEvent, type UploadPostTransformErrorEvent as UploadPostTransformErrorEvent, type UploadPostTransformSuccessEvent as UploadPostTransformSuccessEvent, type UploadPreTransformErrorEvent as UploadPreTransformErrorEvent, diff --git a/src/internal/utils/env.ts b/src/internal/utils/env.ts index 2d848007..cc5fa0fa 100644 --- a/src/internal/utils/env.ts +++ b/src/internal/utils/env.ts @@ -9,10 +9,10 @@ */ export const readEnv = (env: string): string | undefined => { if (typeof (globalThis as any).process !== 'undefined') { - return (globalThis as any).process.env?.[env]?.trim() ?? undefined; + return (globalThis as any).process.env?.[env]?.trim() || undefined; } if (typeof (globalThis as any).Deno !== 'undefined') { - return (globalThis as any).Deno.env?.get?.(env)?.trim(); + return (globalThis as any).Deno.env?.get?.(env)?.trim() || undefined; } return undefined; }; diff --git a/src/resources/index.ts b/src/resources/index.ts index a6ba6506..cda97941 100644 --- a/src/resources/index.ts +++ b/src/resources/index.ts @@ -53,6 +53,11 @@ export { export { Webhooks, type BaseWebhookEvent, + type FileCreateEvent, + type FileDeleteEvent, + type FileUpdateEvent, + type FileVersionCreateEvent, + type FileVersionDeleteEvent, type UploadPostTransformErrorEvent, type UploadPostTransformSuccessEvent, type UploadPreTransformErrorEvent, diff --git a/src/resources/webhooks.ts b/src/resources/webhooks.ts index 66b8a83d..cce8a7b6 100644 --- a/src/resources/webhooks.ts +++ b/src/resources/webhooks.ts @@ -36,6 +36,123 @@ export interface BaseWebhookEvent { type: string; } +/** + * Triggered when a file is created. + */ +export interface FileCreateEvent extends BaseWebhookEvent { + /** + * Timestamp of when the event occurred in ISO8601 format. + */ + created_at: string; + + /** + * Object containing details of a file or file version. + */ + data: FilesAPI.File; + + /** + * Type of the webhook event. + */ + type: 'file.created'; +} + +/** + * Triggered when a file is deleted. + */ +export interface FileDeleteEvent extends BaseWebhookEvent { + /** + * Timestamp of when the event occurred in ISO8601 format. + */ + created_at: string; + + data: FileDeleteEvent.Data; + + /** + * Type of the webhook event. + */ + type: 'file.deleted'; +} + +export namespace FileDeleteEvent { + export interface Data { + /** + * The unique `fileId` of the deleted file. + */ + fileId: string; + } +} + +/** + * Triggered when a file is updated. + */ +export interface FileUpdateEvent extends BaseWebhookEvent { + /** + * Timestamp of when the event occurred in ISO8601 format. + */ + created_at: string; + + /** + * Object containing details of a file or file version. + */ + data: FilesAPI.File; + + /** + * Type of the webhook event. + */ + type: 'file.updated'; +} + +/** + * Triggered when a file version is created. + */ +export interface FileVersionCreateEvent extends BaseWebhookEvent { + /** + * Timestamp of when the event occurred in ISO8601 format. + */ + created_at: string; + + /** + * Object containing details of a file or file version. + */ + data: FilesAPI.File; + + /** + * Type of the webhook event. + */ + type: 'file-version.created'; +} + +/** + * Triggered when a file version is deleted. + */ +export interface FileVersionDeleteEvent extends BaseWebhookEvent { + /** + * Timestamp of when the event occurred in ISO8601 format. + */ + created_at: string; + + data: FileVersionDeleteEvent.Data; + + /** + * Type of the webhook event. + */ + type: 'file-version.deleted'; +} + +export namespace FileVersionDeleteEvent { + export interface Data { + /** + * The unique `fileId` of the deleted file. + */ + fileId: string; + + /** + * The unique `versionId` of the deleted file version. + */ + versionId: string; + } +} + /** * Triggered when a post-transformation fails. The original file remains available, * but the requested transformation could not be generated. @@ -1040,7 +1157,12 @@ export type UnsafeUnwrapWebhookEvent = | UploadPreTransformSuccessEvent | UploadPreTransformErrorEvent | UploadPostTransformSuccessEvent - | UploadPostTransformErrorEvent; + | UploadPostTransformErrorEvent + | FileCreateEvent + | FileUpdateEvent + | FileDeleteEvent + | FileVersionCreateEvent + | FileVersionDeleteEvent; /** * Triggered when a new video transformation request is accepted for processing. @@ -1054,11 +1176,21 @@ export type UnwrapWebhookEvent = | UploadPreTransformSuccessEvent | UploadPreTransformErrorEvent | UploadPostTransformSuccessEvent - | UploadPostTransformErrorEvent; + | UploadPostTransformErrorEvent + | FileCreateEvent + | FileUpdateEvent + | FileDeleteEvent + | FileVersionCreateEvent + | FileVersionDeleteEvent; export declare namespace Webhooks { export { type BaseWebhookEvent as BaseWebhookEvent, + type FileCreateEvent as FileCreateEvent, + type FileDeleteEvent as FileDeleteEvent, + type FileUpdateEvent as FileUpdateEvent, + type FileVersionCreateEvent as FileVersionCreateEvent, + type FileVersionDeleteEvent as FileVersionDeleteEvent, type UploadPostTransformErrorEvent as UploadPostTransformErrorEvent, type UploadPostTransformSuccessEvent as UploadPostTransformSuccessEvent, type UploadPreTransformErrorEvent as UploadPreTransformErrorEvent, diff --git a/src/version.ts b/src/version.ts index 06a61128..662d85ef 100644 --- a/src/version.ts +++ b/src/version.ts @@ -1 +1 @@ -export const VERSION = '7.4.0'; // x-release-please-version +export const VERSION = '7.5.0'; // x-release-please-version diff --git a/tests/api-resources/custom-metadata-fields.test.ts b/tests/api-resources/custom-metadata-fields.test.ts index 3fbf78f7..52e39794 100644 --- a/tests/api-resources/custom-metadata-fields.test.ts +++ b/tests/api-resources/custom-metadata-fields.test.ts @@ -32,7 +32,7 @@ describe('resource customMetadataFields', () => { name: 'price', schema: { type: 'Number', - defaultValue: 'string', + defaultValue: [true, 10, 'Hello'], isValueRequired: true, maxLength: 0, maxValue: 3000, @@ -64,7 +64,7 @@ describe('resource customMetadataFields', () => { { label: 'price', schema: { - defaultValue: 'string', + defaultValue: [true, 10, 'Hello'], isValueRequired: true, maxLength: 0, maxValue: 3000,