@umbraco-cms/mcp-dev 17.4.0 → 17.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -3002,28 +3002,28 @@ var getUmbracoManagementAPI = () => {
3002
3002
  options
3003
3003
  );
3004
3004
  };
3005
- const getPartialViewByPath = (path4, options) => {
3005
+ const getPartialViewByPath = (path3, options) => {
3006
3006
  return UmbracoManagementClient(
3007
3007
  {
3008
- url: `/umbraco/management/api/v1/partial-view/${path4}`,
3008
+ url: `/umbraco/management/api/v1/partial-view/${path3}`,
3009
3009
  method: "GET"
3010
3010
  },
3011
3011
  options
3012
3012
  );
3013
3013
  };
3014
- const deletePartialViewByPath = (path4, options) => {
3014
+ const deletePartialViewByPath = (path3, options) => {
3015
3015
  return UmbracoManagementClient(
3016
3016
  {
3017
- url: `/umbraco/management/api/v1/partial-view/${path4}`,
3017
+ url: `/umbraco/management/api/v1/partial-view/${path3}`,
3018
3018
  method: "DELETE"
3019
3019
  },
3020
3020
  options
3021
3021
  );
3022
3022
  };
3023
- const putPartialViewByPath = (path4, updatePartialViewRequestModel, options) => {
3023
+ const putPartialViewByPath = (path3, updatePartialViewRequestModel, options) => {
3024
3024
  return UmbracoManagementClient(
3025
3025
  {
3026
- url: `/umbraco/management/api/v1/partial-view/${path4}`,
3026
+ url: `/umbraco/management/api/v1/partial-view/${path3}`,
3027
3027
  method: "PUT",
3028
3028
  headers: { "Content-Type": "application/json" },
3029
3029
  data: updatePartialViewRequestModel
@@ -3031,10 +3031,10 @@ var getUmbracoManagementAPI = () => {
3031
3031
  options
3032
3032
  );
3033
3033
  };
3034
- const putPartialViewByPathRename = (path4, renamePartialViewRequestModel, options) => {
3034
+ const putPartialViewByPathRename = (path3, renamePartialViewRequestModel, options) => {
3035
3035
  return UmbracoManagementClient(
3036
3036
  {
3037
- url: `/umbraco/management/api/v1/partial-view/${path4}/rename`,
3037
+ url: `/umbraco/management/api/v1/partial-view/${path3}/rename`,
3038
3038
  method: "PUT",
3039
3039
  headers: { "Content-Type": "application/json" },
3040
3040
  data: renamePartialViewRequestModel
@@ -3053,19 +3053,19 @@ var getUmbracoManagementAPI = () => {
3053
3053
  options
3054
3054
  );
3055
3055
  };
3056
- const getPartialViewFolderByPath = (path4, options) => {
3056
+ const getPartialViewFolderByPath = (path3, options) => {
3057
3057
  return UmbracoManagementClient(
3058
3058
  {
3059
- url: `/umbraco/management/api/v1/partial-view/folder/${path4}`,
3059
+ url: `/umbraco/management/api/v1/partial-view/folder/${path3}`,
3060
3060
  method: "GET"
3061
3061
  },
3062
3062
  options
3063
3063
  );
3064
3064
  };
3065
- const deletePartialViewFolderByPath = (path4, options) => {
3065
+ const deletePartialViewFolderByPath = (path3, options) => {
3066
3066
  return UmbracoManagementClient(
3067
3067
  {
3068
- url: `/umbraco/management/api/v1/partial-view/folder/${path4}`,
3068
+ url: `/umbraco/management/api/v1/partial-view/folder/${path3}`,
3069
3069
  method: "DELETE"
3070
3070
  },
3071
3071
  options
@@ -3313,28 +3313,28 @@ var getUmbracoManagementAPI = () => {
3313
3313
  options
3314
3314
  );
3315
3315
  };
3316
- const getScriptByPath = (path4, options) => {
3316
+ const getScriptByPath = (path3, options) => {
3317
3317
  return UmbracoManagementClient(
3318
3318
  {
3319
- url: `/umbraco/management/api/v1/script/${path4}`,
3319
+ url: `/umbraco/management/api/v1/script/${path3}`,
3320
3320
  method: "GET"
3321
3321
  },
3322
3322
  options
3323
3323
  );
3324
3324
  };
3325
- const deleteScriptByPath = (path4, options) => {
3325
+ const deleteScriptByPath = (path3, options) => {
3326
3326
  return UmbracoManagementClient(
3327
3327
  {
3328
- url: `/umbraco/management/api/v1/script/${path4}`,
3328
+ url: `/umbraco/management/api/v1/script/${path3}`,
3329
3329
  method: "DELETE"
3330
3330
  },
3331
3331
  options
3332
3332
  );
3333
3333
  };
3334
- const putScriptByPath = (path4, updateScriptRequestModel, options) => {
3334
+ const putScriptByPath = (path3, updateScriptRequestModel, options) => {
3335
3335
  return UmbracoManagementClient(
3336
3336
  {
3337
- url: `/umbraco/management/api/v1/script/${path4}`,
3337
+ url: `/umbraco/management/api/v1/script/${path3}`,
3338
3338
  method: "PUT",
3339
3339
  headers: { "Content-Type": "application/json" },
3340
3340
  data: updateScriptRequestModel
@@ -3342,10 +3342,10 @@ var getUmbracoManagementAPI = () => {
3342
3342
  options
3343
3343
  );
3344
3344
  };
3345
- const putScriptByPathRename = (path4, renameScriptRequestModel, options) => {
3345
+ const putScriptByPathRename = (path3, renameScriptRequestModel, options) => {
3346
3346
  return UmbracoManagementClient(
3347
3347
  {
3348
- url: `/umbraco/management/api/v1/script/${path4}/rename`,
3348
+ url: `/umbraco/management/api/v1/script/${path3}/rename`,
3349
3349
  method: "PUT",
3350
3350
  headers: { "Content-Type": "application/json" },
3351
3351
  data: renameScriptRequestModel
@@ -3364,19 +3364,19 @@ var getUmbracoManagementAPI = () => {
3364
3364
  options
3365
3365
  );
3366
3366
  };
3367
- const getScriptFolderByPath = (path4, options) => {
3367
+ const getScriptFolderByPath = (path3, options) => {
3368
3368
  return UmbracoManagementClient(
3369
3369
  {
3370
- url: `/umbraco/management/api/v1/script/folder/${path4}`,
3370
+ url: `/umbraco/management/api/v1/script/folder/${path3}`,
3371
3371
  method: "GET"
3372
3372
  },
3373
3373
  options
3374
3374
  );
3375
3375
  };
3376
- const deleteScriptFolderByPath = (path4, options) => {
3376
+ const deleteScriptFolderByPath = (path3, options) => {
3377
3377
  return UmbracoManagementClient(
3378
3378
  {
3379
- url: `/umbraco/management/api/v1/script/folder/${path4}`,
3379
+ url: `/umbraco/management/api/v1/script/folder/${path3}`,
3380
3380
  method: "DELETE"
3381
3381
  },
3382
3382
  options
@@ -3600,28 +3600,28 @@ var getUmbracoManagementAPI = () => {
3600
3600
  options
3601
3601
  );
3602
3602
  };
3603
- const getStylesheetByPath = (path4, options) => {
3603
+ const getStylesheetByPath = (path3, options) => {
3604
3604
  return UmbracoManagementClient(
3605
3605
  {
3606
- url: `/umbraco/management/api/v1/stylesheet/${path4}`,
3606
+ url: `/umbraco/management/api/v1/stylesheet/${path3}`,
3607
3607
  method: "GET"
3608
3608
  },
3609
3609
  options
3610
3610
  );
3611
3611
  };
3612
- const deleteStylesheetByPath = (path4, options) => {
3612
+ const deleteStylesheetByPath = (path3, options) => {
3613
3613
  return UmbracoManagementClient(
3614
3614
  {
3615
- url: `/umbraco/management/api/v1/stylesheet/${path4}`,
3615
+ url: `/umbraco/management/api/v1/stylesheet/${path3}`,
3616
3616
  method: "DELETE"
3617
3617
  },
3618
3618
  options
3619
3619
  );
3620
3620
  };
3621
- const putStylesheetByPath = (path4, updateStylesheetRequestModel, options) => {
3621
+ const putStylesheetByPath = (path3, updateStylesheetRequestModel, options) => {
3622
3622
  return UmbracoManagementClient(
3623
3623
  {
3624
- url: `/umbraco/management/api/v1/stylesheet/${path4}`,
3624
+ url: `/umbraco/management/api/v1/stylesheet/${path3}`,
3625
3625
  method: "PUT",
3626
3626
  headers: { "Content-Type": "application/json" },
3627
3627
  data: updateStylesheetRequestModel
@@ -3629,10 +3629,10 @@ var getUmbracoManagementAPI = () => {
3629
3629
  options
3630
3630
  );
3631
3631
  };
3632
- const putStylesheetByPathRename = (path4, renameStylesheetRequestModel, options) => {
3632
+ const putStylesheetByPathRename = (path3, renameStylesheetRequestModel, options) => {
3633
3633
  return UmbracoManagementClient(
3634
3634
  {
3635
- url: `/umbraco/management/api/v1/stylesheet/${path4}/rename`,
3635
+ url: `/umbraco/management/api/v1/stylesheet/${path3}/rename`,
3636
3636
  method: "PUT",
3637
3637
  headers: { "Content-Type": "application/json" },
3638
3638
  data: renameStylesheetRequestModel
@@ -3651,19 +3651,19 @@ var getUmbracoManagementAPI = () => {
3651
3651
  options
3652
3652
  );
3653
3653
  };
3654
- const getStylesheetFolderByPath = (path4, options) => {
3654
+ const getStylesheetFolderByPath = (path3, options) => {
3655
3655
  return UmbracoManagementClient(
3656
3656
  {
3657
- url: `/umbraco/management/api/v1/stylesheet/folder/${path4}`,
3657
+ url: `/umbraco/management/api/v1/stylesheet/folder/${path3}`,
3658
3658
  method: "GET"
3659
3659
  },
3660
3660
  options
3661
3661
  );
3662
3662
  };
3663
- const deleteStylesheetFolderByPath = (path4, options) => {
3663
+ const deleteStylesheetFolderByPath = (path3, options) => {
3664
3664
  return UmbracoManagementClient(
3665
3665
  {
3666
- url: `/umbraco/management/api/v1/stylesheet/folder/${path4}`,
3666
+ url: `/umbraco/management/api/v1/stylesheet/folder/${path3}`,
3667
3667
  method: "DELETE"
3668
3668
  },
3669
3669
  options
@@ -4546,21 +4546,47 @@ var getUmbracoManagementAPI = () => {
4546
4546
 
4547
4547
  // src/umb-management-api/api/temporary-file/index.ts
4548
4548
  import { UmbracoManagementClient as UmbracoManagementClient2 } from "@umbraco-cms/mcp-server-sdk";
4549
- import FormData from "form-data";
4549
+ async function readStreamToBuffer(stream) {
4550
+ const chunks = [];
4551
+ for await (const chunk of stream) {
4552
+ chunks.push(typeof chunk === "string" ? Buffer.from(chunk) : chunk);
4553
+ }
4554
+ return Buffer.concat(chunks);
4555
+ }
4550
4556
  var getTemporaryFileAPI = () => ({
4551
- postTemporaryFile: (postTemporaryFileBody2, options) => {
4557
+ postTemporaryFile: async (postTemporaryFileBody2, options) => {
4552
4558
  const formData = new FormData();
4553
4559
  formData.append("Id", postTemporaryFileBody2.Id);
4554
- formData.append("File", postTemporaryFileBody2.File);
4555
- const headers = {
4556
- ...formData.getHeaders(),
4557
- ...options?.headers
4558
- };
4560
+ const file = postTemporaryFileBody2.File;
4561
+ console.log("[temp-file] incoming file:", {
4562
+ typeofFile: typeof file,
4563
+ isBuffer: Buffer.isBuffer(file),
4564
+ ctorName: file?.constructor?.name,
4565
+ hasByteLength: typeof file?.byteLength,
4566
+ hasLength: typeof file?.length,
4567
+ keys: file ? Object.keys(file).slice(0, 10) : []
4568
+ });
4569
+ const buffer = Buffer.isBuffer(file) ? file : await readStreamToBuffer(file);
4570
+ console.log("[temp-file] buffer:", { length: buffer.byteLength });
4571
+ const bytes = new Uint8Array(buffer.byteLength);
4572
+ bytes.set(buffer);
4573
+ const blob = new Blob([bytes]);
4574
+ console.log("[temp-file] blob:", { size: blob.size, type: blob.type, fileName: postTemporaryFileBody2.FileName });
4575
+ formData.append("File", blob, postTemporaryFileBody2.FileName);
4576
+ const entries = [];
4577
+ for (const [k, v] of formData.entries()) {
4578
+ entries.push({
4579
+ name: k,
4580
+ valueKind: typeof v === "string" ? "string" : v?.constructor?.name ?? typeof v,
4581
+ valueSize: typeof v === "string" ? v.length : v?.size ?? void 0
4582
+ });
4583
+ }
4584
+ console.log("[temp-file] formData entries:", entries);
4559
4585
  return UmbracoManagementClient2(
4560
4586
  {
4561
4587
  url: `/umbraco/management/api/v1/temporary-file`,
4562
4588
  method: "POST",
4563
- headers,
4589
+ headers: options?.headers,
4564
4590
  data: formData
4565
4591
  },
4566
4592
  options
@@ -4610,6 +4636,13 @@ var UmbracoManagementClient3 = class {
4610
4636
 
4611
4637
  // src/umb-management-api/runtime-context.ts
4612
4638
  var umbracoVersion = null;
4639
+ var allowFilePathUploads = false;
4640
+ function setAllowFilePathUploads(allow) {
4641
+ allowFilePathUploads = allow;
4642
+ }
4643
+ function isFilePathUploadAllowed() {
4644
+ return allowFilePathUploads;
4645
+ }
4613
4646
  function setUmbracoVersion(version) {
4614
4647
  umbracoVersion = version ?? null;
4615
4648
  }
@@ -15675,13 +15708,13 @@ function isBlockStructure(value) {
15675
15708
  }
15676
15709
  return Array.isArray(value.contentData) && Array.isArray(value.settingsData);
15677
15710
  }
15678
- function discoverAllBlockArrays(value, path4 = "root") {
15711
+ function discoverAllBlockArrays(value, path3 = "root") {
15679
15712
  const results = [];
15680
15713
  if (!value || typeof value !== "object") {
15681
15714
  return results;
15682
15715
  }
15683
15716
  if (isRichTextValue(value)) {
15684
- const nestedResults = discoverAllBlockArrays(value.blocks, `${path4}.blocks`);
15717
+ const nestedResults = discoverAllBlockArrays(value.blocks, `${path3}.blocks`);
15685
15718
  results.push(...nestedResults);
15686
15719
  return results;
15687
15720
  }
@@ -15689,12 +15722,12 @@ function discoverAllBlockArrays(value, path4 = "root") {
15689
15722
  results.push({
15690
15723
  contentData: value.contentData,
15691
15724
  settingsData: value.settingsData,
15692
- path: path4
15725
+ path: path3
15693
15726
  });
15694
15727
  value.contentData.forEach((block, index) => {
15695
15728
  if (block.values && Array.isArray(block.values)) {
15696
15729
  block.values.forEach((prop, propIndex) => {
15697
- const propPath = `${path4}.contentData[${index}].values[${propIndex}](${prop.alias})`;
15730
+ const propPath = `${path3}.contentData[${index}].values[${propIndex}](${prop.alias})`;
15698
15731
  if (isRichTextValue(prop.value)) {
15699
15732
  const nestedResults = discoverAllBlockArrays(prop.value.blocks, `${propPath}.blocks`);
15700
15733
  results.push(...nestedResults);
@@ -15708,7 +15741,7 @@ function discoverAllBlockArrays(value, path4 = "root") {
15708
15741
  value.settingsData.forEach((block, index) => {
15709
15742
  if (block.values && Array.isArray(block.values)) {
15710
15743
  block.values.forEach((prop, propIndex) => {
15711
- const propPath = `${path4}.settingsData[${index}].values[${propIndex}](${prop.alias})`;
15744
+ const propPath = `${path3}.settingsData[${index}].values[${propIndex}](${prop.alias})`;
15712
15745
  if (isRichTextValue(prop.value)) {
15713
15746
  const nestedResults = discoverAllBlockArrays(prop.value.blocks, `${propPath}.blocks`);
15714
15747
  results.push(...nestedResults);
@@ -18659,16 +18692,14 @@ import { v4 as uuidv46 } from "uuid";
18659
18692
 
18660
18693
  // src/umb-management-api/tools/media/post/helpers/media-upload-helpers.ts
18661
18694
  import * as fs2 from "fs";
18662
- import * as os from "os";
18663
18695
  import * as path2 from "path";
18664
18696
  import mime from "mime-types";
18665
18697
 
18666
18698
  // src/umb-management-api/tools/media/post/helpers/validate-file-path.ts
18667
18699
  import * as path from "path";
18668
18700
  import * as fs from "fs";
18669
- import { getServerConfig } from "@umbraco-cms/mcp-server-sdk";
18670
18701
  async function validateFilePath(filePath, allowedPaths) {
18671
- const allowedMediaPaths = allowedPaths ?? (await getServerConfig(true)).config.allowedMediaPaths;
18702
+ const allowedMediaPaths = allowedPaths ?? (process.env.UMBRACO_ALLOWED_MEDIA_PATHS ? process.env.UMBRACO_ALLOWED_MEDIA_PATHS.split(",").map((p) => p.trim()).filter(Boolean) : void 0);
18672
18703
  if (!allowedMediaPaths || allowedMediaPaths.length === 0) {
18673
18704
  throw new Error(
18674
18705
  'File path uploads are disabled. To enable, set UMBRACO_ALLOWED_MEDIA_PATHS environment variable with comma-separated allowed directory paths (e.g., UMBRACO_ALLOWED_MEDIA_PATHS="/tmp/uploads,/var/media")'
@@ -18676,8 +18707,13 @@ async function validateFilePath(filePath, allowedPaths) {
18676
18707
  }
18677
18708
  const normalizedPath = path.resolve(filePath);
18678
18709
  const isAllowed = allowedMediaPaths.some((allowedPath) => {
18679
- const realAllowedPath = fs.realpathSync(allowedPath);
18680
- return normalizedPath.startsWith(allowedPath) || normalizedPath.startsWith(realAllowedPath);
18710
+ if (normalizedPath.startsWith(allowedPath)) return true;
18711
+ try {
18712
+ const realAllowedPath = fs.realpathSync(allowedPath);
18713
+ return normalizedPath.startsWith(realAllowedPath);
18714
+ } catch {
18715
+ return false;
18716
+ }
18681
18717
  });
18682
18718
  if (!isAllowed) {
18683
18719
  throw new Error(
@@ -18689,8 +18725,13 @@ async function validateFilePath(filePath, allowedPaths) {
18689
18725
  if (stats.isSymbolicLink()) {
18690
18726
  const realPath = fs.realpathSync(normalizedPath);
18691
18727
  const symlinkAllowed = allowedMediaPaths.some((allowedPath) => {
18692
- const realAllowedPath = fs.realpathSync(allowedPath);
18693
- return realPath.startsWith(allowedPath) || realPath.startsWith(realAllowedPath);
18728
+ if (realPath.startsWith(allowedPath)) return true;
18729
+ try {
18730
+ const realAllowedPath = fs.realpathSync(allowedPath);
18731
+ return realPath.startsWith(realAllowedPath);
18732
+ } catch {
18733
+ return false;
18734
+ }
18694
18735
  });
18695
18736
  if (!symlinkAllowed) {
18696
18737
  throw new Error(
@@ -18777,18 +18818,25 @@ function buildValueStructure(mediaTypeName, temporaryFileId) {
18777
18818
  value: { temporaryFileId }
18778
18819
  };
18779
18820
  }
18780
- async function createFileStream(sourceType, filePath, fileUrl, fileAsBase64, fileName) {
18781
- let tempFilePath = null;
18782
- let readStream;
18821
+ async function createFilePayload(sourceType, filePath, fileUrl, fileAsBase64, fileName) {
18783
18822
  switch (sourceType) {
18784
- case "filePath":
18823
+ case "filePath": {
18785
18824
  if (!filePath) {
18786
18825
  throw new Error("filePath is required when sourceType is 'filePath'");
18787
18826
  }
18827
+ if (typeof fs2.createReadStream !== "function") {
18828
+ throw new Error(
18829
+ "filePath source is not supported in this runtime (no filesystem). Use sourceType 'url' or 'base64' instead."
18830
+ );
18831
+ }
18788
18832
  const validatedPath = await validateFilePath(filePath);
18789
- readStream = fs2.createReadStream(validatedPath);
18790
- break;
18791
- case "url":
18833
+ const filename = fileName.includes(".") ? fileName : path2.basename(validatedPath);
18834
+ return {
18835
+ data: fs2.createReadStream(validatedPath),
18836
+ filename
18837
+ };
18838
+ }
18839
+ case "url": {
18792
18840
  if (!fileUrl) {
18793
18841
  throw new Error("fileUrl is required when sourceType is 'url'");
18794
18842
  }
@@ -18804,123 +18852,110 @@ async function createFileStream(sourceType, filePath, fileUrl, fileAsBase64, fil
18804
18852
  if (response.status >= 400) {
18805
18853
  throw new Error(`Failed to fetch file from URL: HTTP ${response.status} ${response.statusText}`);
18806
18854
  }
18807
- const arrayBuffer = await response.arrayBuffer();
18808
- let fileNameWithExtension2 = fileName;
18855
+ const buffer = Buffer.from(await response.arrayBuffer());
18856
+ let filename = fileName;
18809
18857
  if (!fileName.includes(".")) {
18810
18858
  const urlPath = new URL(fileUrl).pathname;
18811
18859
  const urlExtension = path2.extname(urlPath);
18812
18860
  if (urlExtension) {
18813
- fileNameWithExtension2 = `${fileName}${urlExtension}`;
18861
+ filename = `${fileName}${urlExtension}`;
18814
18862
  } else {
18815
18863
  const contentType = response.headers.get("content-type") ?? void 0;
18816
18864
  const extensionFromMime = getExtensionFromMimeType(contentType);
18817
- if (extensionFromMime) {
18818
- fileNameWithExtension2 = `${fileName}${extensionFromMime}`;
18819
- } else {
18820
- fileNameWithExtension2 = `${fileName}.bin`;
18821
- }
18865
+ filename = extensionFromMime ? `${fileName}${extensionFromMime}` : `${fileName}.bin`;
18822
18866
  }
18823
18867
  }
18824
- tempFilePath = path2.join(os.tmpdir(), fileNameWithExtension2);
18825
- fs2.writeFileSync(tempFilePath, Buffer.from(arrayBuffer));
18826
- readStream = fs2.createReadStream(tempFilePath);
18868
+ return { data: buffer, filename };
18827
18869
  } catch (error) {
18828
18870
  if (error.name === "AbortError") {
18829
18871
  throw new Error(`Request timeout after 30s fetching URL: ${fileUrl}`);
18830
18872
  }
18831
18873
  throw new Error(`Failed to fetch URL: ${fileUrl} - ${error.message}`);
18832
18874
  }
18833
- break;
18834
- case "base64":
18875
+ }
18876
+ case "base64": {
18835
18877
  if (!fileAsBase64) {
18836
18878
  throw new Error("fileAsBase64 is required when sourceType is 'base64'");
18837
18879
  }
18838
- const fileContent = Buffer.from(fileAsBase64, "base64");
18839
- let fileNameWithExtension = fileName;
18880
+ const buffer = Buffer.from(fileAsBase64, "base64");
18881
+ let filename = fileName;
18840
18882
  if (!fileName.includes(".")) {
18841
- const extension = detectFileExtensionFromBuffer(fileContent);
18842
- fileNameWithExtension = `${fileName}${extension}`;
18883
+ const extension = detectFileExtensionFromBuffer(buffer);
18884
+ filename = `${fileName}${extension}`;
18843
18885
  }
18844
- tempFilePath = path2.join(os.tmpdir(), fileNameWithExtension);
18845
- fs2.writeFileSync(tempFilePath, fileContent);
18846
- readStream = fs2.createReadStream(tempFilePath);
18847
- break;
18848
- }
18849
- return { readStream, tempFilePath };
18850
- }
18851
- function cleanupTempFile(tempFilePath) {
18852
- if (tempFilePath && fs2.existsSync(tempFilePath)) {
18853
- try {
18854
- fs2.unlinkSync(tempFilePath);
18855
- } catch (e) {
18856
- console.error("Failed to cleanup temp file:", e);
18886
+ return { data: buffer, filename };
18857
18887
  }
18858
18888
  }
18859
18889
  }
18860
18890
  async function uploadMediaFile(client, params) {
18861
- let tempFilePath = null;
18891
+ const validatedMediaTypeName = validateMediaTypeForSvg(
18892
+ params.filePath,
18893
+ params.fileUrl,
18894
+ params.name,
18895
+ params.mediaTypeName
18896
+ );
18897
+ const mediaTypeId = await fetchMediaTypeId(client, validatedMediaTypeName);
18898
+ const { data, filename } = await createFilePayload(
18899
+ params.sourceType,
18900
+ params.filePath,
18901
+ params.fileUrl,
18902
+ params.fileAsBase64,
18903
+ params.name
18904
+ );
18862
18905
  try {
18863
- const validatedMediaTypeName = validateMediaTypeForSvg(
18864
- params.filePath,
18865
- params.fileUrl,
18866
- params.name,
18867
- params.mediaTypeName
18868
- );
18869
- const mediaTypeId = await fetchMediaTypeId(client, validatedMediaTypeName);
18870
- const { readStream, tempFilePath: createdTempPath } = await createFileStream(
18871
- params.sourceType,
18872
- params.filePath,
18873
- params.fileUrl,
18874
- params.fileAsBase64,
18875
- params.name
18876
- );
18877
- tempFilePath = createdTempPath;
18878
- try {
18879
- await client.postTemporaryFile({
18880
- Id: params.temporaryFileId,
18881
- File: readStream
18882
- });
18883
- } catch (error) {
18884
- const err = error;
18885
- const errorData = err.response?.data ? typeof err.response.data === "string" ? err.response.data : JSON.stringify(err.response.data) : err.message;
18886
- throw new Error(`Failed to upload temporary file: ${err.response?.status || "Unknown error"} - ${errorData}`);
18887
- }
18888
- const valueStructure = buildValueStructure(validatedMediaTypeName, params.temporaryFileId);
18889
- let response;
18890
- try {
18891
- response = await client.postMedia({
18892
- mediaType: { id: mediaTypeId },
18893
- variants: [
18894
- {
18895
- culture: null,
18896
- segment: null,
18897
- name: params.name
18898
- // Use original name provided by user
18899
- }
18900
- ],
18901
- values: [valueStructure],
18902
- parent: params.parentId ? { id: params.parentId } : null
18903
- }, CAPTURE_RAW_HTTP_RESPONSE146);
18904
- } catch (error) {
18905
- const err = error;
18906
- throw new Error(`Failed to create media item: ${err.response?.status || "Unknown error"} - ${JSON.stringify(err.response?.data) || err.message}`);
18907
- }
18908
- if (response.status < 200 || response.status >= 300) {
18909
- throw new Error(`Request failed with status code ${response.status}`);
18910
- }
18911
- const locationHeader = response.headers?.location || response.headers?.Location;
18912
- if (!locationHeader) {
18913
- throw new Error("No Location header in response - cannot determine created media ID");
18914
- }
18915
- const idMatch = locationHeader.match(/\/([a-f0-9-]{36})$/i);
18916
- if (!idMatch) {
18917
- throw new Error(`Could not extract ID from Location header: ${locationHeader}`);
18918
- }
18919
- const mediaId = idMatch[1];
18920
- return { name: params.name, id: mediaId };
18921
- } finally {
18922
- cleanupTempFile(tempFilePath);
18906
+ await client.postTemporaryFile({
18907
+ Id: params.temporaryFileId,
18908
+ File: data,
18909
+ FileName: filename
18910
+ });
18911
+ } catch (error) {
18912
+ const err = error;
18913
+ const errorData = err.response?.data ? typeof err.response.data === "string" ? err.response.data : JSON.stringify(err.response.data) : err.message;
18914
+ throw new Error(`Failed to upload temporary file: ${err.response?.status || "Unknown error"} - ${errorData}`);
18923
18915
  }
18916
+ const valueStructure = buildValueStructure(validatedMediaTypeName, params.temporaryFileId);
18917
+ let response;
18918
+ try {
18919
+ response = await client.postMedia({
18920
+ mediaType: { id: mediaTypeId },
18921
+ variants: [
18922
+ {
18923
+ culture: null,
18924
+ segment: null,
18925
+ name: params.name
18926
+ // Use original name provided by user
18927
+ }
18928
+ ],
18929
+ values: [valueStructure],
18930
+ parent: params.parentId ? { id: params.parentId } : null
18931
+ }, CAPTURE_RAW_HTTP_RESPONSE146);
18932
+ } catch (error) {
18933
+ const err = error;
18934
+ throw new Error(`Failed to create media item: ${err.response?.status || "Unknown error"} - ${JSON.stringify(err.response?.data) || err.message}`);
18935
+ }
18936
+ if (response.status < 200 || response.status >= 300) {
18937
+ throw new Error(`Request failed with status code ${response.status}`);
18938
+ }
18939
+ const locationHeader = response.headers?.location || response.headers?.Location;
18940
+ if (!locationHeader) {
18941
+ throw new Error("No Location header in response - cannot determine created media ID");
18942
+ }
18943
+ const idMatch = locationHeader.match(/\/([a-f0-9-]{36})$/i);
18944
+ if (!idMatch) {
18945
+ throw new Error(`Could not extract ID from Location header: ${locationHeader}`);
18946
+ }
18947
+ const mediaId = idMatch[1];
18948
+ return { name: params.name, id: mediaId };
18949
+ }
18950
+
18951
+ // src/umb-management-api/tools/media/post/helpers/source-type-helpers.ts
18952
+ var FILE_PATH_ENTRY = `filePath - Most efficient for local files, works with any size
18953
+ SECURITY: Requires UMBRACO_ALLOWED_MEDIA_PATHS environment variable
18954
+ to be configured with comma-separated allowed directories.
18955
+ Example: UMBRACO_ALLOWED_MEDIA_PATHS="/tmp/uploads,/var/media"`;
18956
+ function buildSourceTypeSection(allowFilePath, otherSources) {
18957
+ const sources = allowFilePath ? [FILE_PATH_ENTRY, ...otherSources] : otherSources;
18958
+ return sources.map((s, i) => ` ${i + 1}. ${s}`).join("\n");
18924
18959
  }
18925
18960
 
18926
18961
  // src/umb-management-api/tools/media/post/create-media.ts
@@ -18935,23 +18970,30 @@ import {
18935
18970
  MEDIA_TYPE_VIDEO,
18936
18971
  withStandardDecorators as withStandardDecorators160
18937
18972
  } from "@umbraco-cms/mcp-server-sdk";
18938
- var createMediaSchema = z71.object({
18939
- sourceType: z71.enum(["filePath", "url", "base64"]).describe("Media source type: 'filePath' for local files (most efficient), 'url' for web files, 'base64' for embedded data (small files only)"),
18940
- name: z71.string().describe("The name of the media item"),
18941
- mediaTypeName: z71.string().describe(`Media type: '${MEDIA_TYPE_IMAGE2}', '${MEDIA_TYPE_ARTICLE}', '${MEDIA_TYPE_AUDIO}', '${MEDIA_TYPE_VIDEO}', '${MEDIA_TYPE_VECTOR_GRAPHICS2}', '${MEDIA_TYPE_FILE}', or custom media type name`),
18942
- filePath: z71.string().optional().describe("Absolute path to the file (required if sourceType is 'filePath')"),
18943
- fileUrl: z71.string().url().optional().describe("[raw] URL to fetch the file from (required if sourceType is 'url')"),
18944
- fileAsBase64: z71.string().optional().describe("Base64 encoded file data (required if sourceType is 'base64')"),
18945
- parentId: z71.string().uuid().optional().describe("Parent folder ID (defaults to root)")
18946
- });
18947
18973
  var createMediaOutputSchema = z71.object({
18948
18974
  message: z71.string(),
18949
18975
  name: z71.string(),
18950
18976
  id: z71.string().guid()
18951
18977
  });
18952
- var CreateMediaTool = {
18953
- name: "create-media",
18954
- description: `Upload any media file to Umbraco (images, documents, audio, video, SVG, or custom types).
18978
+ function createCreateMediaTool(options) {
18979
+ const sourceTypeValues = options.allowFilePath ? ["filePath", "url", "base64"] : ["url", "base64"];
18980
+ const sourceTypeDescription = options.allowFilePath ? "Media source type: 'filePath' for local files (most efficient), 'url' for web files, 'base64' for embedded data (small files only)" : "Media source type: 'url' for web files, 'base64' for embedded data (small files only)";
18981
+ const schema = z71.object({
18982
+ sourceType: z71.enum(sourceTypeValues).describe(sourceTypeDescription),
18983
+ name: z71.string().describe("The name of the media item"),
18984
+ mediaTypeName: z71.string().describe(`Media type: '${MEDIA_TYPE_IMAGE2}', '${MEDIA_TYPE_ARTICLE}', '${MEDIA_TYPE_AUDIO}', '${MEDIA_TYPE_VIDEO}', '${MEDIA_TYPE_VECTOR_GRAPHICS2}', '${MEDIA_TYPE_FILE}', or custom media type name`),
18985
+ filePath: z71.string().optional().describe("Absolute path to the file (required if sourceType is 'filePath')"),
18986
+ fileUrl: z71.string().url().optional().describe("[raw] URL to fetch the file from (required if sourceType is 'url')"),
18987
+ fileAsBase64: z71.string().optional().describe("Base64 encoded file data (required if sourceType is 'base64')"),
18988
+ parentId: z71.string().uuid().optional().describe("Parent folder ID (defaults to root)")
18989
+ });
18990
+ const filePathSection = buildSourceTypeSection(options.allowFilePath, [
18991
+ "url - Fetch from web URL",
18992
+ "base64 - Only for small files (<10KB) due to token usage"
18993
+ ]);
18994
+ const tool = {
18995
+ name: "create-media",
18996
+ description: `Upload any media file to Umbraco (images, documents, audio, video, SVG, or custom types).
18955
18997
 
18956
18998
  Media Types:
18957
18999
  - ${MEDIA_TYPE_IMAGE2}: jpg, png, gif, webp, etc. (supports cropping)
@@ -18963,48 +19005,45 @@ var CreateMediaTool = {
18963
19005
  - Custom: any custom media type created in Umbraco
18964
19006
 
18965
19007
  Source Types:
18966
- 1. filePath - Most efficient for local files, works with any size
18967
- SECURITY: Requires UMBRACO_ALLOWED_MEDIA_PATHS environment variable
18968
- to be configured with comma-separated allowed directories.
18969
- Example: UMBRACO_ALLOWED_MEDIA_PATHS="/tmp/uploads,/var/media"
18970
- 2. url - Fetch from web URL
18971
- 3. base64 - Only for small files (<10KB) due to token usage
19008
+ ${filePathSection}
18972
19009
 
18973
19010
  The tool automatically:
18974
19011
  - Creates temporary files
18975
19012
  - Detects and validates media types (auto-corrects SVG vs Image)
18976
19013
  - Configures correct property editors (ImageCropper vs UploadField)
18977
19014
  - Cleans up temporary files`,
18978
- inputSchema: createMediaSchema.shape,
18979
- outputSchema: createMediaOutputSchema.shape,
18980
- slices: ["create"],
18981
- handler: (async (model) => {
18982
- try {
18983
- const client = UmbracoManagementClient3.getClient();
18984
- const temporaryFileId = uuidv46();
18985
- const { name: actualName, id } = await uploadMediaFile(client, {
18986
- sourceType: model.sourceType,
18987
- name: model.name,
18988
- mediaTypeName: model.mediaTypeName,
18989
- filePath: model.filePath,
18990
- fileUrl: model.fileUrl,
18991
- fileAsBase64: model.fileAsBase64,
18992
- parentId: model.parentId,
18993
- temporaryFileId
18994
- });
18995
- return createToolResult20({
18996
- message: `Media "${actualName}" created successfully`,
18997
- name: actualName,
18998
- id
18999
- });
19000
- } catch (error) {
19001
- return createToolResultError10({
19002
- detail: `Error creating media: ${error.message}`
19003
- });
19004
- }
19005
- })
19006
- };
19007
- var create_media_default = withStandardDecorators160(CreateMediaTool);
19015
+ inputSchema: schema.shape,
19016
+ outputSchema: createMediaOutputSchema.shape,
19017
+ slices: ["create"],
19018
+ handler: (async (model) => {
19019
+ try {
19020
+ const client = UmbracoManagementClient3.getClient();
19021
+ const temporaryFileId = uuidv46();
19022
+ const { name: actualName, id } = await uploadMediaFile(client, {
19023
+ sourceType: model.sourceType,
19024
+ name: model.name,
19025
+ mediaTypeName: model.mediaTypeName,
19026
+ filePath: model.filePath,
19027
+ fileUrl: model.fileUrl,
19028
+ fileAsBase64: model.fileAsBase64,
19029
+ parentId: model.parentId,
19030
+ temporaryFileId
19031
+ });
19032
+ return createToolResult20({
19033
+ message: `Media "${actualName}" created successfully`,
19034
+ name: actualName,
19035
+ id
19036
+ });
19037
+ } catch (error) {
19038
+ return createToolResultError10({
19039
+ detail: `Error creating media: ${error.message}`
19040
+ });
19041
+ }
19042
+ })
19043
+ };
19044
+ return withStandardDecorators160(tool);
19045
+ }
19046
+ var create_media_default = createCreateMediaTool({ allowFilePath: true });
19008
19047
 
19009
19048
  // src/umb-management-api/tools/media/post/create-media-multiple.ts
19010
19049
  import { z as z72 } from "zod";
@@ -19020,16 +19059,6 @@ import {
19020
19059
  MEDIA_TYPE_VIDEO as MEDIA_TYPE_VIDEO2,
19021
19060
  withStandardDecorators as withStandardDecorators161
19022
19061
  } from "@umbraco-cms/mcp-server-sdk";
19023
- var createMediaMultipleSchema = z72.object({
19024
- sourceType: z72.enum(["filePath", "url"]).describe("Media source type: 'filePath' for local files (most efficient), 'url' for web files. Base64 not supported for batch uploads due to token usage."),
19025
- files: z72.array(z72.object({
19026
- name: z72.string().describe("The name of the media item"),
19027
- filePath: z72.string().optional().describe("Absolute path to the file (required if sourceType is 'filePath')"),
19028
- fileUrl: z72.string().url().optional().describe("URL to fetch the file from (required if sourceType is 'url')"),
19029
- mediaTypeName: z72.string().optional().describe(`Optional override: '${MEDIA_TYPE_IMAGE3}', '${MEDIA_TYPE_ARTICLE2}', '${MEDIA_TYPE_AUDIO2}', '${MEDIA_TYPE_VIDEO2}', '${MEDIA_TYPE_VECTOR_GRAPHICS3}', '${MEDIA_TYPE_FILE2}', or custom media type name. If not specified, defaults to '${MEDIA_TYPE_FILE2}'`)
19030
- })).describe("Array of files to upload (maximum 20 files per batch)"),
19031
- parentId: z72.string().uuid().optional().describe("Parent folder ID (defaults to root)")
19032
- });
19033
19062
  var createMediaMultipleOutputSchema = z72.object({
19034
19063
  summary: z72.string(),
19035
19064
  results: z72.array(z72.object({
@@ -19039,70 +19068,84 @@ var createMediaMultipleOutputSchema = z72.object({
19039
19068
  error: z72.string().optional()
19040
19069
  }))
19041
19070
  });
19042
- var CreateMediaMultipleTool = {
19043
- name: "create-media-multiple",
19044
- description: `Batch upload multiple media files to Umbraco (maximum 20 files per batch).
19071
+ function createCreateMediaMultipleTool(options) {
19072
+ const sourceTypeValues = options.allowFilePath ? ["filePath", "url"] : ["url"];
19073
+ const sourceTypeDescription = options.allowFilePath ? "Media source type: 'filePath' for local files (most efficient), 'url' for web files. Base64 not supported for batch uploads due to token usage." : "Media source type: 'url' for web files. Base64 not supported for batch uploads due to token usage.";
19074
+ const schema = z72.object({
19075
+ sourceType: z72.enum(sourceTypeValues).describe(sourceTypeDescription),
19076
+ files: z72.array(z72.object({
19077
+ name: z72.string().describe("The name of the media item"),
19078
+ filePath: z72.string().optional().describe("Absolute path to the file (required if sourceType is 'filePath')"),
19079
+ fileUrl: z72.string().url().optional().describe("URL to fetch the file from (required if sourceType is 'url')"),
19080
+ mediaTypeName: z72.string().optional().describe(`Optional override: '${MEDIA_TYPE_IMAGE3}', '${MEDIA_TYPE_ARTICLE2}', '${MEDIA_TYPE_AUDIO2}', '${MEDIA_TYPE_VIDEO2}', '${MEDIA_TYPE_VECTOR_GRAPHICS3}', '${MEDIA_TYPE_FILE2}', or custom media type name. If not specified, defaults to '${MEDIA_TYPE_FILE2}'`)
19081
+ })).describe("Array of files to upload (maximum 20 files per batch)"),
19082
+ parentId: z72.string().uuid().optional().describe("Parent folder ID (defaults to root)")
19083
+ });
19084
+ const filePathSection = buildSourceTypeSection(options.allowFilePath, [
19085
+ "url - Fetch from web URL"
19086
+ ]);
19087
+ const tool = {
19088
+ name: "create-media-multiple",
19089
+ description: `Batch upload multiple media files to Umbraco (maximum 20 files per batch).
19045
19090
 
19046
19091
  Supports any file type: images, documents, audio, video, SVG, or custom types.
19047
19092
 
19048
19093
  Source Types:
19049
- 1. filePath - Most efficient for local files, works with any size
19050
- SECURITY: Requires UMBRACO_ALLOWED_MEDIA_PATHS environment variable
19051
- to be configured with comma-separated allowed directories.
19052
- Example: UMBRACO_ALLOWED_MEDIA_PATHS="/tmp/uploads,/var/media"
19053
- 2. url - Fetch from web URL
19094
+ ${filePathSection}
19054
19095
 
19055
19096
  Note: base64 is not supported for batch uploads due to token usage.
19056
19097
 
19057
19098
  The tool processes files sequentially and returns detailed results for each file.
19058
19099
  If some files fail, others will continue processing (continue-on-error strategy).`,
19059
- inputSchema: createMediaMultipleSchema.shape,
19060
- outputSchema: createMediaMultipleOutputSchema.shape,
19061
- slices: ["create"],
19062
- handler: (async (model) => {
19063
- if (model.files.length > 20) {
19064
- return createToolResultError11({
19065
- detail: `Batch upload limited to 20 files per call. You provided ${model.files.length} files. Please split into multiple batches.`
19066
- });
19067
- }
19068
- const results = [];
19069
- const client = UmbracoManagementClient3.getClient();
19070
- for (const file of model.files) {
19071
- try {
19072
- const temporaryFileId = uuidv47();
19073
- const defaultMediaType = file.mediaTypeName || MEDIA_TYPE_FILE2;
19074
- const { name: actualName, id: mediaId } = await uploadMediaFile(client, {
19075
- sourceType: model.sourceType,
19076
- name: file.name,
19077
- mediaTypeName: defaultMediaType,
19078
- filePath: file.filePath,
19079
- fileUrl: file.fileUrl,
19080
- fileAsBase64: void 0,
19081
- parentId: model.parentId,
19082
- temporaryFileId
19083
- });
19084
- results.push({
19085
- success: true,
19086
- name: actualName,
19087
- id: mediaId
19088
- });
19089
- } catch (error) {
19090
- results.push({
19091
- success: false,
19092
- name: file.name,
19093
- error: error.message
19100
+ inputSchema: schema.shape,
19101
+ outputSchema: createMediaMultipleOutputSchema.shape,
19102
+ slices: ["create"],
19103
+ handler: (async (model) => {
19104
+ if (model.files.length > 20) {
19105
+ return createToolResultError11({
19106
+ detail: `Batch upload limited to 20 files per call. You provided ${model.files.length} files. Please split into multiple batches.`
19094
19107
  });
19095
19108
  }
19096
- }
19097
- const successCount = results.filter((r) => r.success).length;
19098
- const failureCount = results.filter((r) => !r.success).length;
19099
- return createToolResult21({
19100
- summary: `Processed ${model.files.length} files: ${successCount} succeeded, ${failureCount} failed`,
19101
- results
19102
- });
19103
- })
19104
- };
19105
- var create_media_multiple_default = withStandardDecorators161(CreateMediaMultipleTool);
19109
+ const results = [];
19110
+ const client = UmbracoManagementClient3.getClient();
19111
+ for (const file of model.files) {
19112
+ try {
19113
+ const temporaryFileId = uuidv47();
19114
+ const defaultMediaType = file.mediaTypeName || MEDIA_TYPE_FILE2;
19115
+ const { name: actualName, id: mediaId } = await uploadMediaFile(client, {
19116
+ sourceType: model.sourceType,
19117
+ name: file.name,
19118
+ mediaTypeName: defaultMediaType,
19119
+ filePath: file.filePath,
19120
+ fileUrl: file.fileUrl,
19121
+ fileAsBase64: void 0,
19122
+ parentId: model.parentId,
19123
+ temporaryFileId
19124
+ });
19125
+ results.push({
19126
+ success: true,
19127
+ name: actualName,
19128
+ id: mediaId
19129
+ });
19130
+ } catch (error) {
19131
+ results.push({
19132
+ success: false,
19133
+ name: file.name,
19134
+ error: error.message
19135
+ });
19136
+ }
19137
+ }
19138
+ const successCount = results.filter((r) => r.success).length;
19139
+ const failureCount = results.filter((r) => !r.success).length;
19140
+ return createToolResult21({
19141
+ summary: `Processed ${model.files.length} files: ${successCount} succeeded, ${failureCount} failed`,
19142
+ results
19143
+ });
19144
+ })
19145
+ };
19146
+ return withStandardDecorators161(tool);
19147
+ }
19148
+ var create_media_multiple_default = createCreateMediaMultipleTool({ allowFilePath: true });
19106
19149
 
19107
19150
  // src/umb-management-api/tools/media/post/create-media-folder.ts
19108
19151
  import { z as z73 } from "zod";
@@ -19921,8 +19964,9 @@ var MediaCollection = {
19921
19964
  tools.push(get_root_default6);
19922
19965
  }
19923
19966
  if (AuthorizationPolicies.SectionAccessMedia(user)) {
19924
- tools.push(create_media_default);
19925
- tools.push(create_media_multiple_default);
19967
+ const allowFilePath = isFilePathUploadAllowed();
19968
+ tools.push(createCreateMediaTool({ allowFilePath }));
19969
+ tools.push(createCreateMediaMultipleTool({ allowFilePath }));
19926
19970
  tools.push(create_media_folder_default);
19927
19971
  tools.push(delete_media_default);
19928
19972
  tools.push(update_media_default);
@@ -21941,9 +21985,9 @@ var GetPartialViewByPathTool = {
21941
21985
  outputSchema: getPartialViewByPathResponse.shape,
21942
21986
  annotations: { readOnlyHint: true },
21943
21987
  slices: ["read"],
21944
- handler: (async ({ path: path4 }) => {
21988
+ handler: (async ({ path: path3 }) => {
21945
21989
  return executeGetApiCall117(
21946
- (client) => client.getPartialViewByPath(path4, CAPTURE_RAW_HTTP_RESPONSE235)
21990
+ (client) => client.getPartialViewByPath(path3, CAPTURE_RAW_HTTP_RESPONSE235)
21947
21991
  );
21948
21992
  })
21949
21993
  };
@@ -21962,9 +22006,9 @@ var GetPartialViewFolderByPathTool = {
21962
22006
  outputSchema: getPartialViewFolderByPathResponse.shape,
21963
22007
  annotations: { readOnlyHint: true },
21964
22008
  slices: ["read", "folders"],
21965
- handler: (async ({ path: path4 }) => {
22009
+ handler: (async ({ path: path3 }) => {
21966
22010
  return executeGetApiCall118(
21967
- (client) => client.getPartialViewFolderByPath(path4, CAPTURE_RAW_HTTP_RESPONSE236)
22011
+ (client) => client.getPartialViewFolderByPath(path3, CAPTURE_RAW_HTTP_RESPONSE236)
21968
22012
  );
21969
22013
  })
21970
22014
  };
@@ -22039,9 +22083,9 @@ var DeletePartialViewTool = {
22039
22083
  destructiveHint: true
22040
22084
  },
22041
22085
  slices: ["delete"],
22042
- handler: (async ({ path: path4 }) => {
22086
+ handler: (async ({ path: path3 }) => {
22043
22087
  return executeVoidApiCall76(
22044
- (client) => client.deletePartialViewByPath(path4, CAPTURE_RAW_HTTP_RESPONSE239)
22088
+ (client) => client.deletePartialViewByPath(path3, CAPTURE_RAW_HTTP_RESPONSE239)
22045
22089
  );
22046
22090
  })
22047
22091
  };
@@ -22061,9 +22105,9 @@ var DeletePartialViewFolderTool = {
22061
22105
  destructiveHint: true
22062
22106
  },
22063
22107
  slices: ["delete", "folders"],
22064
- handler: (async ({ path: path4 }) => {
22108
+ handler: (async ({ path: path3 }) => {
22065
22109
  return executeVoidApiCall77(
22066
- (client) => client.deletePartialViewFolderByPath(path4, CAPTURE_RAW_HTTP_RESPONSE240)
22110
+ (client) => client.deletePartialViewFolderByPath(path3, CAPTURE_RAW_HTTP_RESPONSE240)
22067
22111
  );
22068
22112
  })
22069
22113
  };
@@ -22549,9 +22593,9 @@ var GetScriptByPathTool = {
22549
22593
  outputSchema: getScriptByPathResponse.shape,
22550
22594
  annotations: { readOnlyHint: true },
22551
22595
  slices: ["read"],
22552
- handler: (async ({ path: path4 }) => {
22596
+ handler: (async ({ path: path3 }) => {
22553
22597
  return executeGetApiCall130(
22554
- (client) => client.getScriptByPath(path4, CAPTURE_RAW_HTTP_RESPONSE257)
22598
+ (client) => client.getScriptByPath(path3, CAPTURE_RAW_HTTP_RESPONSE257)
22555
22599
  );
22556
22600
  })
22557
22601
  };
@@ -22570,9 +22614,9 @@ var GetScriptFolderByPathTool = {
22570
22614
  outputSchema: getScriptFolderByPathResponse.shape,
22571
22615
  annotations: { readOnlyHint: true },
22572
22616
  slices: ["read", "folders"],
22573
- handler: (async ({ path: path4 }) => {
22617
+ handler: (async ({ path: path3 }) => {
22574
22618
  return executeGetApiCall131(
22575
- (client) => client.getScriptFolderByPath(path4, CAPTURE_RAW_HTTP_RESPONSE258)
22619
+ (client) => client.getScriptFolderByPath(path3, CAPTURE_RAW_HTTP_RESPONSE258)
22576
22620
  );
22577
22621
  })
22578
22622
  };
@@ -22870,9 +22914,9 @@ var DeleteScriptTool = {
22870
22914
  destructiveHint: true
22871
22915
  },
22872
22916
  slices: ["delete"],
22873
- handler: (async ({ path: path4 }) => {
22917
+ handler: (async ({ path: path3 }) => {
22874
22918
  return executeVoidApiCall82(
22875
- (client) => client.deleteScriptByPath(path4, CAPTURE_RAW_HTTP_RESPONSE266)
22919
+ (client) => client.deleteScriptByPath(path3, CAPTURE_RAW_HTTP_RESPONSE266)
22876
22920
  );
22877
22921
  })
22878
22922
  };
@@ -22892,9 +22936,9 @@ var DeleteScriptFolderTool = {
22892
22936
  destructiveHint: true
22893
22937
  },
22894
22938
  slices: ["delete", "folders"],
22895
- handler: (async ({ path: path4 }) => {
22939
+ handler: (async ({ path: path3 }) => {
22896
22940
  return executeVoidApiCall83(
22897
- (client) => client.deleteScriptFolderByPath(path4, CAPTURE_RAW_HTTP_RESPONSE267)
22941
+ (client) => client.deleteScriptFolderByPath(path3, CAPTURE_RAW_HTTP_RESPONSE267)
22898
22942
  );
22899
22943
  })
22900
22944
  };
@@ -23502,9 +23546,9 @@ var UpdateStylesheetTool = {
23502
23546
  annotations: { idempotentHint: true },
23503
23547
  slices: ["update"],
23504
23548
  handler: (async (model) => {
23505
- const { path: path4, ...updateModel } = model;
23549
+ const { path: path3, ...updateModel } = model;
23506
23550
  return executeVoidApiCall84(
23507
- (client) => client.putStylesheetByPath(path4, updateModel, CAPTURE_RAW_HTTP_RESPONSE281)
23551
+ (client) => client.putStylesheetByPath(path3, updateModel, CAPTURE_RAW_HTTP_RESPONSE281)
23508
23552
  );
23509
23553
  })
23510
23554
  };
@@ -23528,8 +23572,8 @@ var RenameStylesheetTool = {
23528
23572
  annotations: { idempotentHint: true },
23529
23573
  slices: ["rename"],
23530
23574
  handler: (async (model) => {
23531
- const { path: path4, ...renameModel } = model;
23532
- const normalizedPath = encodeURIComponent(path4);
23575
+ const { path: path3, ...renameModel } = model;
23576
+ const normalizedPath = encodeURIComponent(path3);
23533
23577
  return executeVoidApiCall85(
23534
23578
  (client) => client.putStylesheetByPathRename(normalizedPath, renameModel, CAPTURE_RAW_HTTP_RESPONSE282)
23535
23579
  );
@@ -24140,9 +24184,6 @@ var TemplateCollection = {
24140
24184
 
24141
24185
  // src/umb-management-api/tools/temporary-file/post/create-temporary-file.ts
24142
24186
  import { z as z143 } from "zod";
24143
- import * as fs3 from "fs";
24144
- import * as os2 from "os";
24145
- import * as path3 from "path";
24146
24187
  import {
24147
24188
  createToolResult as createToolResult42,
24148
24189
  createToolResultError as createToolResultError27,
@@ -24171,7 +24212,6 @@ var CreateTemporaryFileTool = {
24171
24212
  outputSchema: createTemporaryFileOutputSchema.shape,
24172
24213
  slices: ["create"],
24173
24214
  handler: (async (model) => {
24174
- let tempFilePath = null;
24175
24215
  try {
24176
24216
  const fileContent = Buffer.from(model.fileAsBase64, "base64");
24177
24217
  let fileName = model.fileName;
@@ -24179,13 +24219,11 @@ var CreateTemporaryFileTool = {
24179
24219
  const extension = detectFileExtensionFromBuffer2(fileContent);
24180
24220
  fileName = `${fileName}${extension}`;
24181
24221
  }
24182
- tempFilePath = path3.join(os2.tmpdir(), `umbraco-upload-${model.id}-${fileName}`);
24183
- fs3.writeFileSync(tempFilePath, fileContent);
24184
- const readStream = fs3.createReadStream(tempFilePath);
24185
24222
  const client = UmbracoManagementClient3.getClient();
24186
24223
  await client.postTemporaryFile({
24187
24224
  Id: model.id,
24188
- File: readStream
24225
+ File: fileContent,
24226
+ FileName: fileName
24189
24227
  });
24190
24228
  return createToolResult42({
24191
24229
  message: "Temporary file created successfully",
@@ -24195,14 +24233,6 @@ var CreateTemporaryFileTool = {
24195
24233
  return createToolResultError27({
24196
24234
  detail: `Error creating temporary file: ${error.message}`
24197
24235
  });
24198
- } finally {
24199
- if (tempFilePath && fs3.existsSync(tempFilePath)) {
24200
- try {
24201
- fs3.unlinkSync(tempFilePath);
24202
- } catch (e) {
24203
- console.error("Failed to cleanup temp file:", e);
24204
- }
24205
- }
24206
24236
  }
24207
24237
  })
24208
24238
  };
@@ -24213,14 +24243,15 @@ import { ReadStream } from "fs";
24213
24243
  import { z as zod2 } from "zod";
24214
24244
  var postTemporaryFileBody = zod2.object({
24215
24245
  Id: zod2.string().uuid(),
24216
- File: zod2.instanceof(ReadStream)
24246
+ File: zod2.union([zod2.instanceof(Buffer), zod2.instanceof(ReadStream)]),
24247
+ FileName: zod2.string().min(1)
24217
24248
  });
24218
24249
  var getTemporaryFileByIdParams = zod2.object({
24219
24250
  id: zod2.string().uuid()
24220
24251
  });
24221
24252
  var getTemporaryFileByIdResponse = zod2.object({
24222
24253
  id: zod2.string().guid(),
24223
- availableUntil: zod2.string().datetime({ local: true }).nullish(),
24254
+ availableUntil: zod2.string().datetime({ local: true, offset: true }).nullish(),
24224
24255
  fileName: zod2.string().min(1)
24225
24256
  });
24226
24257
  var deleteTemporaryFileByIdParams = zod2.object({
@@ -25470,10 +25501,11 @@ export {
25470
25501
  __commonJS,
25471
25502
  __toESM,
25472
25503
  UmbracoManagementClient3 as UmbracoManagementClient,
25504
+ setAllowFilePathUploads,
25473
25505
  setUmbracoVersion,
25474
25506
  availableCollections,
25475
25507
  allModes,
25476
25508
  allModeNames,
25477
25509
  allSliceNames
25478
25510
  };
25479
- //# sourceMappingURL=chunk-6NEKTCPS.js.map
25511
+ //# sourceMappingURL=chunk-XVBYRUFE.js.map