1 Commits

Author SHA1 Message Date
c3b81f9e47 chore(deps): update dependency vue to v3.5.34
Some checks failed
Build Test / test (pull_request) Successful in 29s
JS Unit Tests / test (pull_request) Failing after 28s
PHP Unit Tests / test (pull_request) Successful in 1m13s
2026-05-21 03:45:11 +00:00
8 changed files with 98 additions and 723 deletions

View File

@@ -13,7 +13,6 @@ use InvalidArgumentException;
use KTXC\Http\Response\JsonResponse; use KTXC\Http\Response\JsonResponse;
use KTXC\Http\Response\Response; use KTXC\Http\Response\Response;
use KTXC\Http\Response\StreamedNdJsonResponse; use KTXC\Http\Response\StreamedNdJsonResponse;
use KTXC\Http\Response\StreamedResponse;
use KTXC\SessionIdentity; use KTXC\SessionIdentity;
use KTXC\SessionTenant; use KTXC\SessionTenant;
use KTXF\Controller\ControllerAbstract; use KTXF\Controller\ControllerAbstract;
@@ -32,6 +31,12 @@ use KTXM\MailManager\Manager;
use Psr\Log\LoggerInterface; use Psr\Log\LoggerInterface;
use Throwable; use Throwable;
/**
* Default Controller - Unified Mail API
*
* Handles all mail operations in JMAP-style API pattern.
* Supports both single operations and batches with result references.
*/
class DefaultController extends ControllerAbstract { class DefaultController extends ControllerAbstract {
private const ERR_MISSING_PROVIDER = 'Missing parameter: provider'; private const ERR_MISSING_PROVIDER = 'Missing parameter: provider';
@@ -163,7 +168,6 @@ class DefaultController extends ControllerAbstract {
'entity.move' => $this->entityMove($tenantId, $userId, $data), 'entity.move' => $this->entityMove($tenantId, $userId, $data),
'entity.copy' => throw new InvalidArgumentException('Operation not implemented: ' . $operation), 'entity.copy' => throw new InvalidArgumentException('Operation not implemented: ' . $operation),
'entity.transmit' => $this->entityTransmit($tenantId, $userId, $data), 'entity.transmit' => $this->entityTransmit($tenantId, $userId, $data),
'entity.download' => $this->entityDownload($tenantId, $userId, $data),
default => throw new InvalidArgumentException(self::ERR_INVALID_OPERATION . $operation) default => throw new InvalidArgumentException(self::ERR_INVALID_OPERATION . $operation)
}; };
@@ -554,14 +558,14 @@ class DefaultController extends ControllerAbstract {
if (is_bool($result)) { if (is_bool($result)) {
return [ return [
'disposition' => 'deleted' 'outcome' => 'deleted'
]; ];
} }
if ($result instanceof JsonSerializable) { if ($result instanceof JsonSerializable) {
return [ return [
'disposition' => 'moved', 'outcome' => 'moved',
'mutation' => $result 'data' => $result
]; ];
} }
@@ -769,21 +773,21 @@ class DefaultController extends ControllerAbstract {
} }
private function entityDelete(string $tenantId, string $userId, array $data): mixed { private function entityDelete(string $tenantId, string $userId, array $data): mixed {
if (!isset($data['targets'])) { if (!isset($data['sources'])) {
throw new InvalidArgumentException(self::ERR_MISSING_TARGETS); throw new InvalidArgumentException(self::ERR_MISSING_SOURCES);
} }
if (!is_array($data['targets'])) { if (!is_array($data['sources'])) {
throw new InvalidArgumentException(self::ERR_INVALID_TARGETS); throw new InvalidArgumentException(self::ERR_INVALID_SOURCES);
} }
$targets = ResourceIdentifiers::fromArray($data['targets']); $sources = ResourceIdentifiers::fromArray($data['sources']);
foreach ($targets as $target) { foreach ($sources as $source) {
if (!$target instanceof EntityIdentifier) { if (!$source instanceof EntityIdentifier) {
throw new InvalidArgumentException('Invalid parameter: targets must contain provider:service:collection:entity identifiers'); throw new InvalidArgumentException('Invalid parameter: sources must contain provider:service:collection:entity identifiers');
} }
} }
return $this->mailManager->entityDelete($tenantId, $userId, ...$targets->all()); return $this->mailManager->entityDelete($tenantId, $userId, ...$sources->all());
} }
private function entityPatch(string $tenantId, string $userId, array $data): mixed { private function entityPatch(string $tenantId, string $userId, array $data): mixed {
@@ -864,46 +868,4 @@ class DefaultController extends ControllerAbstract {
return ['jobId' => $jobId]; return ['jobId' => $jobId];
} }
private function entityDownload(string $tenantId, string $userId, array $data): mixed {
if (!isset($data['target'])) {
throw new InvalidArgumentException(self::ERR_MISSING_TARGET);
}
if (!is_string($data['target'])) {
throw new InvalidArgumentException(self::ERR_INVALID_IDENTIFIER);
}
// 'part' is optional — null means full RFC 822 message download
$part = isset($data['part']) && is_array($data['part']) ? $data['part'] : null;
$target = ResourceIdentifier::fromString($data['target']);
$logger = $this->logger;
$result = $this->mailManager->entityDownload($tenantId, $userId, $target, $part);
$filename = $result->filename();
$asciiFilename = preg_replace('/[^\x20-\x7E]|[\\\\"]/', '_', $filename);
$encodedFilename = rawurlencode($filename);
$disposition = sprintf(
'attachment; filename="%s"; filename*=UTF-8\'\'%s',
$asciiFilename,
$encodedFilename,
);
$responseGenerator = (static function () use ($result, $logger): \Generator {
try {
yield from $result->stream();
} catch (\Throwable $t) {
$logger->error('Error streaming entity download', ['exception' => $t]);
// Headers already sent — cannot change status code; stop output cleanly
}
})();
return new StreamedResponse($responseGenerator, 200, [
'Content-Disposition' => $disposition,
'Content-Type' => $result->mimeType(),
'Content-Transfer-Encoding' => 'binary',
'Cache-Control' => 'no-store',
]);
}
} }

View File

@@ -20,7 +20,6 @@ use KTXF\Mail\Service\ServiceCollectionMutableInterface;
use KTXF\Mail\Service\ServiceConfigurableInterface; use KTXF\Mail\Service\ServiceConfigurableInterface;
use KTXF\Mail\Service\ServiceEntityMutableInterface; use KTXF\Mail\Service\ServiceEntityMutableInterface;
use KTXF\Mail\Service\ServiceMutableInterface; use KTXF\Mail\Service\ServiceMutableInterface;
use KTXF\Resource\BinaryResource;
use KTXF\Resource\Filter\IFilter; use KTXF\Resource\Filter\IFilter;
use KTXF\Resource\Identifier\CollectionIdentifier; use KTXF\Resource\Identifier\CollectionIdentifier;
use KTXF\Resource\Identifier\EntityIdentifier; use KTXF\Resource\Identifier\EntityIdentifier;
@@ -952,13 +951,6 @@ class Manager {
} }
} }
public function entityDownload(string $tenantId, string $userId, EntityIdentifier $targetEntity, array|null $targetPart): BinaryResource {
// retrieve service
$service = $this->serviceFetch($tenantId, $userId, $targetEntity->provider(), $targetEntity->service());
// download entity
return $service->entityDownload($targetEntity, $targetPart);
}
/** /**
* Check if messages exist * Check if messages exist
* *
@@ -1302,4 +1294,5 @@ class Manager {
return $operationOutcome; return $operationOutcome;
} }
} }

565
package-lock.json generated
View File

@@ -11,7 +11,7 @@
"dependencies": { "dependencies": {
"pinia": "^3.0.0", "pinia": "^3.0.0",
"vue": "^3.5.18", "vue": "^3.5.18",
"vue-router": "^5.0.0", "vue-router": "^4.5.1",
"vuetify": "^4.0.0" "vuetify": "^4.0.0"
}, },
"devDependencies": { "devDependencies": {
@@ -24,69 +24,6 @@
"vue-tsc": "^3.0.5" "vue-tsc": "^3.0.5"
} }
}, },
"node_modules/@babel/generator": {
"version": "8.0.0-rc.5",
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-8.0.0-rc.5.tgz",
"integrity": "sha512-nFZPWz3FHIS7y6rMIVoa/WBwjdutfIaRJIBQjzn+t3RnecZoRNlGmGcyR2wb0T/IgSd50Kz/6dG8/LvMCRunjg==",
"license": "MIT",
"dependencies": {
"@babel/parser": "^8.0.0-rc.5",
"@babel/types": "^8.0.0-rc.5",
"@jridgewell/gen-mapping": "^0.3.12",
"@jridgewell/trace-mapping": "^0.3.28",
"@types/jsesc": "^2.5.0",
"jsesc": "^3.0.2"
},
"engines": {
"node": "^22.18.0 || >=24.11.0"
}
},
"node_modules/@babel/generator/node_modules/@babel/helper-string-parser": {
"version": "8.0.0-rc.5",
"resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-8.0.0-rc.5.tgz",
"integrity": "sha512-sN7R8rBvDurfaziNfDEIjIntlazmlkCDGO4SNl2RJ3wRCn+QxspLV7hzYAE8WWVd2joVuT8sUxeePdLp2idI1A==",
"license": "MIT",
"engines": {
"node": "^22.18.0 || >=24.11.0"
}
},
"node_modules/@babel/generator/node_modules/@babel/helper-validator-identifier": {
"version": "8.0.0-rc.5",
"resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-8.0.0-rc.5.tgz",
"integrity": "sha512-ehJDxHvtbZ85RtX/L2fi0h9AGsBNqB5Euv1EB8RMAvGYvD+2X+QbpzzOpbklnNXO+WSZJNOaetw2BBj27xsWVg==",
"license": "MIT",
"engines": {
"node": "^22.18.0 || >=24.11.0"
}
},
"node_modules/@babel/generator/node_modules/@babel/parser": {
"version": "8.0.0-rc.5",
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-8.0.0-rc.5.tgz",
"integrity": "sha512-/Mfg83rK3+jsRbl4Vbd0jqxc6M1A1/WNFtgrowRM1unEsD3XcNnrBdMM0JWakd0/RN9lseQKwPduW1TiEwKOlQ==",
"license": "MIT",
"dependencies": {
"@babel/types": "^8.0.0-rc.5"
},
"bin": {
"parser": "bin/babel-parser.js"
},
"engines": {
"node": "^22.18.0 || >=24.11.0"
}
},
"node_modules/@babel/generator/node_modules/@babel/types": {
"version": "8.0.0-rc.5",
"resolved": "https://registry.npmjs.org/@babel/types/-/types-8.0.0-rc.5.tgz",
"integrity": "sha512-JeSVu/m8x/zpp4CLjYHVNXuhEyOkhPXuxM8YOXjh6L4LlvQNKuUNOTo5KdBuKAcTDHw8DquToTaEkhsBqPXOaA==",
"license": "MIT",
"dependencies": {
"@babel/helper-string-parser": "^8.0.0-rc.5",
"@babel/helper-validator-identifier": "^8.0.0-rc.5"
},
"engines": {
"node": "^22.18.0 || >=24.11.0"
}
},
"node_modules/@babel/helper-string-parser": { "node_modules/@babel/helper-string-parser": {
"version": "7.27.1", "version": "7.27.1",
"resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz",
@@ -177,30 +114,11 @@
"tslib": "^2.4.0" "tslib": "^2.4.0"
} }
}, },
"node_modules/@jridgewell/gen-mapping": {
"version": "0.3.13",
"resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz",
"integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==",
"license": "MIT",
"dependencies": {
"@jridgewell/sourcemap-codec": "^1.5.0",
"@jridgewell/trace-mapping": "^0.3.24"
}
},
"node_modules/@jridgewell/remapping": {
"version": "2.3.5",
"resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz",
"integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==",
"license": "MIT",
"dependencies": {
"@jridgewell/gen-mapping": "^0.3.5",
"@jridgewell/trace-mapping": "^0.3.24"
}
},
"node_modules/@jridgewell/resolve-uri": { "node_modules/@jridgewell/resolve-uri": {
"version": "3.1.2", "version": "3.1.2",
"resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
"integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
"dev": true,
"license": "MIT", "license": "MIT",
"engines": { "engines": {
"node": ">=6.0.0" "node": ">=6.0.0"
@@ -216,6 +134,7 @@
"version": "0.3.31", "version": "0.3.31",
"resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz",
"integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==",
"dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/resolve-uri": "^3.1.0",
@@ -568,12 +487,6 @@
"dev": true, "dev": true,
"license": "MIT" "license": "MIT"
}, },
"node_modules/@types/jsesc": {
"version": "2.5.1",
"resolved": "https://registry.npmjs.org/@types/jsesc/-/jsesc-2.5.1.tgz",
"integrity": "sha512-9VN+6yxLOPLOav+7PwjZbxiID2bVaeq0ED4qSQmdQTdjnXJSaCVKTR58t15oqH1H5t8Ng2ZX1SabJVoN9Q34bw==",
"license": "MIT"
},
"node_modules/@vitejs/plugin-vue": { "node_modules/@vitejs/plugin-vue": {
"version": "6.0.7", "version": "6.0.7",
"resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-6.0.7.tgz", "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-6.0.7.tgz",
@@ -802,114 +715,60 @@
"vscode-uri": "^3.0.8" "vscode-uri": "^3.0.8"
} }
}, },
"node_modules/@vue-macros/common": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/@vue-macros/common/-/common-3.1.2.tgz",
"integrity": "sha512-h9t4ArDdniO9ekYHAD95t9AZcAbb19lEGK+26iAjUODOIJKmObDNBSe4+6ELQAA3vtYiFPPBtHh7+cQCKi3Dng==",
"license": "MIT",
"dependencies": {
"@vue/compiler-sfc": "^3.5.22",
"ast-kit": "^2.1.2",
"local-pkg": "^1.1.2",
"magic-string-ast": "^1.0.2",
"unplugin-utils": "^0.3.0"
},
"engines": {
"node": ">=20.19.0"
},
"funding": {
"url": "https://github.com/sponsors/vue-macros"
},
"peerDependencies": {
"vue": "^2.7.0 || ^3.2.25"
},
"peerDependenciesMeta": {
"vue": {
"optional": true
}
}
},
"node_modules/@vue/compiler-core": { "node_modules/@vue/compiler-core": {
"version": "3.5.35", "version": "3.5.34",
"resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.35.tgz", "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.34.tgz",
"integrity": "sha512-BUmHaR1J+O+CKZ9uJucdVTEr1LHsdyvv7vG3eNRhK3CczEHeMd/LtsHAuD7PbrxvI2envCY2v7HI1vC1aBRzKw==", "integrity": "sha512-s9cLyK5mLcvZ4Agva5QgRsQyLKvts9WbU9DB6NqiZkkGEdwmcEiylj5Jbwkp680drF/NNCV8OlAJSe+yMLxaJw==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@babel/parser": "^7.29.3", "@babel/parser": "^7.29.3",
"@vue/shared": "3.5.35", "@vue/shared": "3.5.34",
"entities": "^7.0.1", "entities": "^7.0.1",
"estree-walker": "^2.0.2", "estree-walker": "^2.0.2",
"source-map-js": "^1.2.1" "source-map-js": "^1.2.1"
} }
}, },
"node_modules/@vue/compiler-dom": { "node_modules/@vue/compiler-dom": {
"version": "3.5.35", "version": "3.5.34",
"resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.35.tgz", "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.34.tgz",
"integrity": "sha512-k+bprkXxuqhVajgTx5mUHuir7TwQzUKOWR40ng1ncAqQRPnrLngGGgqVEEhOnTMlc8btHYVKmrP8s5Qyg0hvYA==", "integrity": "sha512-EbF/T++k0e2MMZlJsBhzK8Sgwt0HcIPOhzn1CTB/lv6sQcyk+OWf8YeiLxZp3ro7MbbLcAfAJ6sEvjFWuNgUCw==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@vue/compiler-core": "3.5.35", "@vue/compiler-core": "3.5.34",
"@vue/shared": "3.5.35" "@vue/shared": "3.5.34"
} }
}, },
"node_modules/@vue/compiler-sfc": { "node_modules/@vue/compiler-sfc": {
"version": "3.5.35", "version": "3.5.34",
"resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.35.tgz", "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.34.tgz",
"integrity": "sha512-G5VPMcXTSywXBgtFOZOnHKBxKSrwXUcvY1iaF5/hRcy7t0J6CH/d8ha9F4nzi00Fax1eLV0QHM7v4mQu68jydw==", "integrity": "sha512-D/ihr6uZeIt6r+pVZf46RWT1fAsLFMbUP7k8G1VkiiWexriED9GrX3echHd4Abbt17zjlfiFJ8z7a3BxZOPNjg==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@babel/parser": "^7.29.3", "@babel/parser": "^7.29.3",
"@vue/compiler-core": "3.5.35", "@vue/compiler-core": "3.5.34",
"@vue/compiler-dom": "3.5.35", "@vue/compiler-dom": "3.5.34",
"@vue/compiler-ssr": "3.5.35", "@vue/compiler-ssr": "3.5.34",
"@vue/shared": "3.5.35", "@vue/shared": "3.5.34",
"estree-walker": "^2.0.2", "estree-walker": "^2.0.2",
"magic-string": "^0.30.21", "magic-string": "^0.30.21",
"postcss": "^8.5.15", "postcss": "^8.5.14",
"source-map-js": "^1.2.1" "source-map-js": "^1.2.1"
} }
}, },
"node_modules/@vue/compiler-ssr": { "node_modules/@vue/compiler-ssr": {
"version": "3.5.35", "version": "3.5.34",
"resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.35.tgz", "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.34.tgz",
"integrity": "sha512-rGhAeXgdM7/ffTJGXT69rCCdTmjDewnFuUZfBQQHTdcEBeWdT5HCGY60y2ytLJr9/Dsu7IntUi5z/w0h6Rjnzw==", "integrity": "sha512-cDtTHKibkThKGHH1SP+WdccquNRYQDFH6rRjQCqT9G2ltFAfoR5pUftpab/z+aM5mW9HLLVQW7hfKKQe/1GBeQ==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@vue/compiler-dom": "3.5.35", "@vue/compiler-dom": "3.5.34",
"@vue/shared": "3.5.35" "@vue/shared": "3.5.34"
} }
}, },
"node_modules/@vue/devtools-api": { "node_modules/@vue/devtools-api": {
"version": "8.1.2", "version": "6.6.4",
"resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-8.1.2.tgz", "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-6.6.4.tgz",
"integrity": "sha512-vA0O112YqyDuNA1s7Yb2gCgToQ/OxOWiFDO5ThLCcDy0ldHnSd1dUTaSYhOldbqoNgumE4dxtGAoAaSUKUD1Zg==", "integrity": "sha512-sGhTPMuXqZ1rVOk32RylztWkfXTRhuS7vgAKv0zjqk8gbsHkJ7xfFf+jbySxt7tWObEJwyKaHMikV/WGDiQm8g==",
"license": "MIT",
"dependencies": {
"@vue/devtools-kit": "^8.1.2"
}
},
"node_modules/@vue/devtools-api/node_modules/@vue/devtools-kit": {
"version": "8.1.2",
"resolved": "https://registry.npmjs.org/@vue/devtools-kit/-/devtools-kit-8.1.2.tgz",
"integrity": "sha512-f75/upc+GCyjXErpgPGz4582ujS0L/adAltGy+tqXMGUJpgAcfGr6CxnnhpZY8BHuMYt6KpbF8uaFrrQG66rGQ==",
"license": "MIT",
"dependencies": {
"@vue/devtools-shared": "^8.1.2",
"birpc": "^2.6.1",
"hookable": "^5.5.3",
"perfect-debounce": "^2.0.0"
}
},
"node_modules/@vue/devtools-api/node_modules/@vue/devtools-shared": {
"version": "8.1.2",
"resolved": "https://registry.npmjs.org/@vue/devtools-shared/-/devtools-shared-8.1.2.tgz",
"integrity": "sha512-X9RyVFYAdkBe4IUf5v48TxBF/6QPmF8CmWrDAjXzfUHrgQ/HGfTC1A6TqgXqZ03ye66l3AD51BAGD69IvKM9sw==",
"license": "MIT"
},
"node_modules/@vue/devtools-api/node_modules/perfect-debounce": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/perfect-debounce/-/perfect-debounce-2.1.0.tgz",
"integrity": "sha512-LjgdTytVFXeUgtHZr9WYViYSM/g8MkcTPYDlPa3cDqMirHjKiSZPYd6DoL7pK8AJQr+uWkQvCjHNdiMqsrJs+g==",
"license": "MIT" "license": "MIT"
}, },
"node_modules/@vue/devtools-kit": { "node_modules/@vue/devtools-kit": {
@@ -953,53 +812,53 @@
} }
}, },
"node_modules/@vue/reactivity": { "node_modules/@vue/reactivity": {
"version": "3.5.35", "version": "3.5.34",
"resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.5.35.tgz", "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.5.34.tgz",
"integrity": "sha512-tVc+SsHConvh/Lz64qq1pP3rYArBmK42xonovEcxY74SQtvctZodG/zhq54P5dr38cVuw25d27cPNRdlMidpGQ==", "integrity": "sha512-y9XDjCEuBp+98k+UL5dbYkh57AHU4o6cxZedOPXw3bmrZZYLQsVHguGurq7hVrPCSrQtrnz1f9dssyFr+dMXfQ==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@vue/shared": "3.5.35" "@vue/shared": "3.5.34"
} }
}, },
"node_modules/@vue/runtime-core": { "node_modules/@vue/runtime-core": {
"version": "3.5.35", "version": "3.5.34",
"resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.5.35.tgz", "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.5.34.tgz",
"integrity": "sha512-A/xFNX9loIcWDygeQuNCfKuh0CoYBzxhqEMNah5TSFg9Z53DrFYEN2qi5CU9necjM1OWYegYREUTHmXTmhfXtg==", "integrity": "sha512-mKeBYvu8tcMSLhypAHBmriUFfWXKTCF/23Z4jiCoYK3UtWepkliViNLuR90V9XOyD62mUxs9p1jsrpK3CCGIzw==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@vue/reactivity": "3.5.35", "@vue/reactivity": "3.5.34",
"@vue/shared": "3.5.35" "@vue/shared": "3.5.34"
} }
}, },
"node_modules/@vue/runtime-dom": { "node_modules/@vue/runtime-dom": {
"version": "3.5.35", "version": "3.5.34",
"resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.5.35.tgz", "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.5.34.tgz",
"integrity": "sha512-odrJ1C391dbGnyDRh8U+rnP7J2amIEzfmRk5vXy7xi3aZhEXofTvpi0T4HJb6jlNqQZTNPR5MPHSB3RHNkIORA==", "integrity": "sha512-e8kZzERmCwUnBRVsgSQlAfrfU2rGoy0FFKPBXSlfEjc/O3KfA7QP0t1/2ZylrbchjmIKB4dPTd07A6WPr0eOrg==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@vue/reactivity": "3.5.35", "@vue/reactivity": "3.5.34",
"@vue/runtime-core": "3.5.35", "@vue/runtime-core": "3.5.34",
"@vue/shared": "3.5.35", "@vue/shared": "3.5.34",
"csstype": "^3.2.3" "csstype": "^3.2.3"
} }
}, },
"node_modules/@vue/server-renderer": { "node_modules/@vue/server-renderer": {
"version": "3.5.35", "version": "3.5.34",
"resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.5.35.tgz", "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.5.34.tgz",
"integrity": "sha512-NkebSOYdB97wi8OQcO3HqzZSlymJi/aWsN/7h74OSVhRTm6qGs3Jp3e0rCXynmWwSlKeRrnlIug+ilYoHBmQDA==", "integrity": "sha512-nHxmJoTrKsmrkbILRhkC9gY1G3moZbJTqCzDd7DOOzG5KH9oeJ0Unqrff5f9v0pW//jES05ZkJcNtfE8JjOIew==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@vue/compiler-ssr": "3.5.35", "@vue/compiler-ssr": "3.5.34",
"@vue/shared": "3.5.35" "@vue/shared": "3.5.34"
}, },
"peerDependencies": { "peerDependencies": {
"vue": "3.5.35" "vue": "3.5.34"
} }
}, },
"node_modules/@vue/shared": { "node_modules/@vue/shared": {
"version": "3.5.35", "version": "3.5.34",
"resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.35.tgz", "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.34.tgz",
"integrity": "sha512-zSbjL7gRXwks2ZQLRGCajBtBXEOXW9Ddhn/HvSdrGkE2dqGnumzW8XtusRrxrE9LvqtiqDXQ+A60Hp6mvdYxfA==", "integrity": "sha512-24uqU4OIiX29ryC3MeWid/Xf2fa2EFRUVLb77nRhk+UrTVrh/XiGtFAFmJBAtBRbjwNdsPRP+jj/OL27Eg1NDA==",
"license": "MIT" "license": "MIT"
}, },
"node_modules/@vue/tsconfig": { "node_modules/@vue/tsconfig": {
@@ -1021,18 +880,6 @@
} }
} }
}, },
"node_modules/acorn": {
"version": "8.16.0",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz",
"integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==",
"license": "MIT",
"bin": {
"acorn": "bin/acorn"
},
"engines": {
"node": ">=0.4.0"
}
},
"node_modules/alien-signals": { "node_modules/alien-signals": {
"version": "3.2.1", "version": "3.2.1",
"resolved": "https://registry.npmjs.org/alien-signals/-/alien-signals-3.2.1.tgz", "resolved": "https://registry.npmjs.org/alien-signals/-/alien-signals-3.2.1.tgz",
@@ -1051,22 +898,6 @@
"node": ">=12" "node": ">=12"
} }
}, },
"node_modules/ast-kit": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/ast-kit/-/ast-kit-2.2.0.tgz",
"integrity": "sha512-m1Q/RaVOnTp9JxPX+F+Zn7IcLYMzM8kZofDImfsKZd8MbR+ikdOzTeztStWqfrqIxZnYWryyI9ePm3NGjnZgGw==",
"license": "MIT",
"dependencies": {
"@babel/parser": "^7.28.5",
"pathe": "^2.0.3"
},
"engines": {
"node": ">=20.19.0"
},
"funding": {
"url": "https://github.com/sponsors/sxzz"
}
},
"node_modules/ast-v8-to-istanbul": { "node_modules/ast-v8-to-istanbul": {
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/ast-v8-to-istanbul/-/ast-v8-to-istanbul-1.0.0.tgz", "resolved": "https://registry.npmjs.org/ast-v8-to-istanbul/-/ast-v8-to-istanbul-1.0.0.tgz",
@@ -1089,22 +920,6 @@
"@types/estree": "^1.0.0" "@types/estree": "^1.0.0"
} }
}, },
"node_modules/ast-walker-scope": {
"version": "0.8.3",
"resolved": "https://registry.npmjs.org/ast-walker-scope/-/ast-walker-scope-0.8.3.tgz",
"integrity": "sha512-cbdCP0PGOBq0ASG+sjnKIoYkWMKhhz+F/h9pRexUdX2Hd38+WOlBkRKlqkGOSm0YQpcFMQBJeK4WspUAkwsEdg==",
"license": "MIT",
"dependencies": {
"@babel/parser": "^7.28.4",
"ast-kit": "^2.1.3"
},
"engines": {
"node": ">=20.19.0"
},
"funding": {
"url": "https://github.com/sponsors/sxzz"
}
},
"node_modules/birpc": { "node_modules/birpc": {
"version": "2.9.0", "version": "2.9.0",
"resolved": "https://registry.npmjs.org/birpc/-/birpc-2.9.0.tgz", "resolved": "https://registry.npmjs.org/birpc/-/birpc-2.9.0.tgz",
@@ -1125,27 +940,6 @@
"node": ">=18" "node": ">=18"
} }
}, },
"node_modules/chokidar": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-5.0.0.tgz",
"integrity": "sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw==",
"license": "MIT",
"dependencies": {
"readdirp": "^5.0.0"
},
"engines": {
"node": ">= 20.19.0"
},
"funding": {
"url": "https://paulmillr.com/funding/"
}
},
"node_modules/confbox": {
"version": "0.2.4",
"resolved": "https://registry.npmjs.org/confbox/-/confbox-0.2.4.tgz",
"integrity": "sha512-ysOGlgTFbN2/Y6Cg3Iye8YKulHw+R2fNXHrgSmXISQdMnomY6eNDprVdW9R5xBguEqI954+S6709UyiO7B+6OQ==",
"license": "MIT"
},
"node_modules/convert-source-map": { "node_modules/convert-source-map": {
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz",
@@ -1221,16 +1015,11 @@
"node": ">=12.0.0" "node": ">=12.0.0"
} }
}, },
"node_modules/exsolve": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/exsolve/-/exsolve-1.0.8.tgz",
"integrity": "sha512-LmDxfWXwcTArk8fUEnOfSZpHOJ6zOMUJKOtFLFqJLoKJetuQG874Uc7/Kki7zFLzYybmZhp1M7+98pfMqeX8yA==",
"license": "MIT"
},
"node_modules/fdir": { "node_modules/fdir": {
"version": "6.5.0", "version": "6.5.0",
"resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz",
"integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==",
"dev": true,
"license": "MIT", "license": "MIT",
"engines": { "engines": {
"node": ">=12.0.0" "node": ">=12.0.0"
@@ -1354,30 +1143,6 @@
"dev": true, "dev": true,
"license": "MIT" "license": "MIT"
}, },
"node_modules/jsesc": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz",
"integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==",
"license": "MIT",
"bin": {
"jsesc": "bin/jsesc"
},
"engines": {
"node": ">=6"
}
},
"node_modules/json5": {
"version": "2.2.3",
"resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
"integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
"license": "MIT",
"bin": {
"json5": "lib/cli.js"
},
"engines": {
"node": ">=6"
}
},
"node_modules/lightningcss": { "node_modules/lightningcss": {
"version": "1.32.0", "version": "1.32.0",
"resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.32.0.tgz", "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.32.0.tgz",
@@ -1639,23 +1404,6 @@
"url": "https://opencollective.com/parcel" "url": "https://opencollective.com/parcel"
} }
}, },
"node_modules/local-pkg": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/local-pkg/-/local-pkg-1.2.1.tgz",
"integrity": "sha512-++gUqRDEvcnN6Zhqrr+y/CkVEHhlrR96vZn3nZZPYzMcBUyBtTKzB9NadClFIsIVSsu+3i9tfk/erqy9kAmt7Q==",
"license": "MIT",
"dependencies": {
"mlly": "^1.7.4",
"pkg-types": "^2.3.0",
"quansync": "^0.2.11"
},
"engines": {
"node": ">=14"
},
"funding": {
"url": "https://github.com/sponsors/antfu"
}
},
"node_modules/magic-string": { "node_modules/magic-string": {
"version": "0.30.21", "version": "0.30.21",
"resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz",
@@ -1665,21 +1413,6 @@
"@jridgewell/sourcemap-codec": "^1.5.5" "@jridgewell/sourcemap-codec": "^1.5.5"
} }
}, },
"node_modules/magic-string-ast": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/magic-string-ast/-/magic-string-ast-1.0.3.tgz",
"integrity": "sha512-CvkkH1i81zl7mmb94DsRiFeG9V2fR2JeuK8yDgS8oiZSFa++wWLEgZ5ufEOyLHbvSbD1gTRKv9NdX69Rnvr9JA==",
"license": "MIT",
"dependencies": {
"magic-string": "^0.30.19"
},
"engines": {
"node": ">=20.19.0"
},
"funding": {
"url": "https://github.com/sponsors/sxzz"
}
},
"node_modules/magicast": { "node_modules/magicast": {
"version": "0.5.2", "version": "0.5.2",
"resolved": "https://registry.npmjs.org/magicast/-/magicast-0.5.2.tgz", "resolved": "https://registry.npmjs.org/magicast/-/magicast-0.5.2.tgz",
@@ -1714,35 +1447,6 @@
"integrity": "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==", "integrity": "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==",
"license": "MIT" "license": "MIT"
}, },
"node_modules/mlly": {
"version": "1.8.2",
"resolved": "https://registry.npmjs.org/mlly/-/mlly-1.8.2.tgz",
"integrity": "sha512-d+ObxMQFmbt10sretNDytwt85VrbkhhUA/JBGm1MPaWJ65Cl4wOgLaB1NYvJSZ0Ef03MMEU/0xpPMXUIQ29UfA==",
"license": "MIT",
"dependencies": {
"acorn": "^8.16.0",
"pathe": "^2.0.3",
"pkg-types": "^1.3.1",
"ufo": "^1.6.3"
}
},
"node_modules/mlly/node_modules/confbox": {
"version": "0.1.8",
"resolved": "https://registry.npmjs.org/confbox/-/confbox-0.1.8.tgz",
"integrity": "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==",
"license": "MIT"
},
"node_modules/mlly/node_modules/pkg-types": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.3.1.tgz",
"integrity": "sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==",
"license": "MIT",
"dependencies": {
"confbox": "^0.1.8",
"mlly": "^1.7.4",
"pathe": "^2.0.1"
}
},
"node_modules/mrmime": { "node_modules/mrmime": {
"version": "2.0.1", "version": "2.0.1",
"resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.1.tgz", "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.1.tgz",
@@ -1757,6 +1461,7 @@
"version": "0.4.1", "version": "0.4.1",
"resolved": "https://registry.npmjs.org/muggle-string/-/muggle-string-0.4.1.tgz", "resolved": "https://registry.npmjs.org/muggle-string/-/muggle-string-0.4.1.tgz",
"integrity": "sha512-VNTrAak/KhO2i8dqqnqnAHOa3cYBwXEZe9h+D5h/1ZqFSTEFHdM65lR7RoIqq3tBBYavsOXV84NoHXZ0AkPyqQ==", "integrity": "sha512-VNTrAak/KhO2i8dqqnqnAHOa3cYBwXEZe9h+D5h/1ZqFSTEFHdM65lR7RoIqq3tBBYavsOXV84NoHXZ0AkPyqQ==",
"dev": true,
"license": "MIT" "license": "MIT"
}, },
"node_modules/nanoid": { "node_modules/nanoid": {
@@ -1799,6 +1504,7 @@
"version": "2.0.3", "version": "2.0.3",
"resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz",
"integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==",
"dev": true,
"license": "MIT" "license": "MIT"
}, },
"node_modules/perfect-debounce": { "node_modules/perfect-debounce": {
@@ -1817,6 +1523,7 @@
"version": "4.0.4", "version": "4.0.4",
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz",
"integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==",
"dev": true,
"license": "MIT", "license": "MIT",
"engines": { "engines": {
"node": ">=12" "node": ">=12"
@@ -1855,17 +1562,6 @@
"@vue/devtools-kit": "^7.7.9" "@vue/devtools-kit": "^7.7.9"
} }
}, },
"node_modules/pkg-types": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-2.3.1.tgz",
"integrity": "sha512-y+ichcgc2LrADuhLNAx8DFjVfgz91pRxfZdI3UDhxHvcVEZsenLO+7XaU5vOp0u/7V/wZ+plyuQxtrDlZJ+yeg==",
"license": "MIT",
"dependencies": {
"confbox": "^0.2.4",
"exsolve": "^1.0.8",
"pathe": "^2.0.3"
}
},
"node_modules/postcss": { "node_modules/postcss": {
"version": "8.5.15", "version": "8.5.15",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.15.tgz", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.15.tgz",
@@ -1894,35 +1590,6 @@
"node": "^10 || ^12 || >=14" "node": "^10 || ^12 || >=14"
} }
}, },
"node_modules/quansync": {
"version": "0.2.11",
"resolved": "https://registry.npmjs.org/quansync/-/quansync-0.2.11.tgz",
"integrity": "sha512-AifT7QEbW9Nri4tAwR5M/uzpBuqfZf+zwaEM/QkzEjj7NBuFD2rBuy0K3dE+8wltbezDV7JMA0WfnCPYRSYbXA==",
"funding": [
{
"type": "individual",
"url": "https://github.com/sponsors/antfu"
},
{
"type": "individual",
"url": "https://github.com/sponsors/sxzz"
}
],
"license": "MIT"
},
"node_modules/readdirp": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-5.0.0.tgz",
"integrity": "sha512-9u/XQ1pvrQtYyMpZe7DXKv2p5CNvyVwzUB6uhLAnQwHMSgKMBR62lc7AHljaeteeHXn11XTAaLLUVZYVZyuRBQ==",
"license": "MIT",
"engines": {
"node": ">= 20.19.0"
},
"funding": {
"type": "individual",
"url": "https://paulmillr.com/funding/"
}
},
"node_modules/rfdc": { "node_modules/rfdc": {
"version": "1.4.1", "version": "1.4.1",
"resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz", "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz",
@@ -1963,12 +1630,6 @@
"@rolldown/binding-win32-x64-msvc": "1.0.1" "@rolldown/binding-win32-x64-msvc": "1.0.1"
} }
}, },
"node_modules/scule": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/scule/-/scule-1.3.0.tgz",
"integrity": "sha512-6FtHJEvt+pVMIB9IBY+IcCJ6Z5f1iQnytgyfKMhDKgmzYG+TeH/wx1y3l27rshSbLiSanrR9ffZDrEsmjlQF2g==",
"license": "MIT"
},
"node_modules/semver": { "node_modules/semver": {
"version": "7.7.4", "version": "7.7.4",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz",
@@ -2086,6 +1747,7 @@
"version": "0.2.16", "version": "0.2.16",
"resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.16.tgz", "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.16.tgz",
"integrity": "sha512-pn99VhoACYR8nFHhxqix+uvsbXineAasWm5ojXoN8xEwK5Kd3/TrhNn1wByuD52UxWRLy8pu+kRMniEi6Eq9Zg==", "integrity": "sha512-pn99VhoACYR8nFHhxqix+uvsbXineAasWm5ojXoN8xEwK5Kd3/TrhNn1wByuD52UxWRLy8pu+kRMniEi6Eq9Zg==",
"dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"fdir": "^6.5.0", "fdir": "^6.5.0",
@@ -2140,42 +1802,6 @@
"node": ">=14.17" "node": ">=14.17"
} }
}, },
"node_modules/ufo": {
"version": "1.6.4",
"resolved": "https://registry.npmjs.org/ufo/-/ufo-1.6.4.tgz",
"integrity": "sha512-JFNbkD1Svwe0KvGi8GOeLcP4kAWQ609twvCdcHxq1oSL8svv39ZuSvajcD8B+5D0eL4+s1Is2D/O6KN3qcTeRA==",
"license": "MIT"
},
"node_modules/unplugin": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/unplugin/-/unplugin-3.0.0.tgz",
"integrity": "sha512-0Mqk3AT2TZCXWKdcoaufeXNukv2mTrEZExeXlHIOZXdqYoHHr4n51pymnwV8x2BOVxwXbK2HLlI7usrqMpycdg==",
"license": "MIT",
"dependencies": {
"@jridgewell/remapping": "^2.3.5",
"picomatch": "^4.0.3",
"webpack-virtual-modules": "^0.6.2"
},
"engines": {
"node": "^20.19.0 || >=22.12.0"
}
},
"node_modules/unplugin-utils": {
"version": "0.3.1",
"resolved": "https://registry.npmjs.org/unplugin-utils/-/unplugin-utils-0.3.1.tgz",
"integrity": "sha512-5lWVjgi6vuHhJ526bI4nlCOmkCIF3nnfXkCMDeMJrtdvxTs6ZFCM8oNufGTsDbKv/tJ/xj8RpvXjRuPBZJuJog==",
"license": "MIT",
"dependencies": {
"pathe": "^2.0.3",
"picomatch": "^4.0.3"
},
"engines": {
"node": ">=20.19.0"
},
"funding": {
"url": "https://github.com/sponsors/sxzz"
}
},
"node_modules/vite": { "node_modules/vite": {
"version": "8.0.13", "version": "8.0.13",
"resolved": "https://registry.npmjs.org/vite/-/vite-8.0.13.tgz", "resolved": "https://registry.npmjs.org/vite/-/vite-8.0.13.tgz",
@@ -2353,16 +1979,16 @@
"license": "MIT" "license": "MIT"
}, },
"node_modules/vue": { "node_modules/vue": {
"version": "3.5.35", "version": "3.5.34",
"resolved": "https://registry.npmjs.org/vue/-/vue-3.5.35.tgz", "resolved": "https://registry.npmjs.org/vue/-/vue-3.5.34.tgz",
"integrity": "sha512-cx89fnr+0kVGHiNFG6y6s0bdjypJRFNZn6x3WPstNdQR1bi1mbB7h4v5IBGTsPJU3nK1+0Iqj3Zf+hZWMieR4Q==", "integrity": "sha512-WdLBG9gm02OgJIG9axd5Hpx0TFLdzVgfG2evFFu8Rur5O/IoGc5cMjnjh3tPL6GnRGsYvUhBSKVPYVcxRKpMCA==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@vue/compiler-dom": "3.5.35", "@vue/compiler-dom": "3.5.34",
"@vue/compiler-sfc": "3.5.35", "@vue/compiler-sfc": "3.5.34",
"@vue/runtime-dom": "3.5.35", "@vue/runtime-dom": "3.5.34",
"@vue/server-renderer": "3.5.35", "@vue/server-renderer": "3.5.34",
"@vue/shared": "3.5.35" "@vue/shared": "3.5.34"
}, },
"peerDependencies": { "peerDependencies": {
"typescript": "*" "typescript": "*"
@@ -2374,48 +2000,18 @@
} }
}, },
"node_modules/vue-router": { "node_modules/vue-router": {
"version": "5.0.7", "version": "4.6.4",
"resolved": "https://registry.npmjs.org/vue-router/-/vue-router-5.0.7.tgz", "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-4.6.4.tgz",
"integrity": "sha512-dqfk8kvRbCutmCOCj/XLDqDEYxc1wBdAOGLuVy5M93ifYMsBd5fIjfaPN4tQAbxr5IprdBDIox1gr4wYyOx/SA==", "integrity": "sha512-Hz9q5sa33Yhduglwz6g9skT8OBPii+4bFn88w6J+J4MfEo4KRRpmiNG/hHHkdbRFlLBOqxN8y8gf2Fb0MTUgVg==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@babel/generator": "^8.0.0-rc.4", "@vue/devtools-api": "^6.6.4"
"@vue-macros/common": "^3.1.1",
"@vue/devtools-api": "^8.1.1",
"ast-walker-scope": "^0.8.3",
"chokidar": "^5.0.0",
"json5": "^2.2.3",
"local-pkg": "^1.1.2",
"magic-string": "^0.30.21",
"mlly": "^1.8.0",
"muggle-string": "^0.4.1",
"pathe": "^2.0.3",
"picomatch": "^4.0.3",
"scule": "^1.3.0",
"tinyglobby": "^0.2.15",
"unplugin": "^3.0.0",
"unplugin-utils": "^0.3.1",
"yaml": "^2.8.2"
}, },
"funding": { "funding": {
"url": "https://github.com/sponsors/posva" "url": "https://github.com/sponsors/posva"
}, },
"peerDependencies": { "peerDependencies": {
"@pinia/colada": ">=0.21.2", "vue": "^3.5.0"
"@vue/compiler-sfc": "^3.5.34",
"pinia": "^3.0.4",
"vue": "^3.5.34"
},
"peerDependenciesMeta": {
"@pinia/colada": {
"optional": true
},
"@vue/compiler-sfc": {
"optional": true
},
"pinia": {
"optional": true
}
} }
}, },
"node_modules/vue-tsc": { "node_modules/vue-tsc": {
@@ -2462,12 +2058,6 @@
} }
} }
}, },
"node_modules/webpack-virtual-modules": {
"version": "0.6.2",
"resolved": "https://registry.npmjs.org/webpack-virtual-modules/-/webpack-virtual-modules-0.6.2.tgz",
"integrity": "sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==",
"license": "MIT"
},
"node_modules/why-is-node-running": { "node_modules/why-is-node-running": {
"version": "2.3.0", "version": "2.3.0",
"resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz", "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz",
@@ -2485,21 +2075,6 @@
"engines": { "engines": {
"node": ">=8" "node": ">=8"
} }
},
"node_modules/yaml": {
"version": "2.9.0",
"resolved": "https://registry.npmjs.org/yaml/-/yaml-2.9.0.tgz",
"integrity": "sha512-2AvhNX3mb8zd6Zy7INTtSpl1F15HW6Wnqj0srWlkKLcpYl/gMIMJiyuGq2KeI2YFxUPjdlB+3Lc10seMLtL4cA==",
"license": "ISC",
"bin": {
"yaml": "bin.mjs"
},
"engines": {
"node": ">= 14.6"
},
"funding": {
"url": "https://github.com/sponsors/eemeli"
}
} }
} }
} }

View File

@@ -20,7 +20,7 @@
"dependencies": { "dependencies": {
"pinia": "^3.0.0", "pinia": "^3.0.0",
"vue": "^3.5.18", "vue": "^3.5.18",
"vue-router": "^5.0.0", "vue-router": "^4.5.1",
"vuetify": "^4.0.0" "vuetify": "^4.0.0"
}, },
"devDependencies": { "devDependencies": {

View File

@@ -2,7 +2,7 @@
* Entity management service * Entity management service
*/ */
import { transceivePost, transceiveStream, transceiveDownload } from './transceive'; import { transceivePost, transceiveStream } from './transceive';
import type { import type {
EntityFetchRequest, EntityFetchRequest,
EntityFetchResponse, EntityFetchResponse,
@@ -27,7 +27,6 @@ import type {
EntityListBulkRequest, EntityListBulkRequest,
EntityPatchResponse, EntityPatchResponse,
EntityPatchRequest, EntityPatchRequest,
EntityDownloadRequest,
} from '../types/entity'; } from '../types/entity';
import { useIntegrationStore } from '@KTXC/stores/integrationStore'; import { useIntegrationStore } from '@KTXC/stores/integrationStore';
import { EntityObject } from '../models'; import { EntityObject } from '../models';
@@ -111,7 +110,7 @@ export const entityService = {
// Convert response to EntityObject instances // Convert response to EntityObject instances
const list: Record<string, EntityObject> = {}; const list: Record<string, EntityObject> = {};
Object.entries(response).forEach(([, entity]) => { Object.entries(response).forEach(([identifier, entity]) => {
list[entity.identifier] = createEntityObject(entity); list[entity.identifier] = createEntityObject(entity);
}); });
@@ -217,16 +216,6 @@ export const entityService = {
async transmit(request: EntityTransmitRequest): Promise<EntityTransmitResponse> { async transmit(request: EntityTransmitRequest): Promise<EntityTransmitResponse> {
return await transceivePost<EntityTransmitRequest, EntityTransmitResponse>('entity.transmit', request); return await transceivePost<EntityTransmitRequest, EntityTransmitResponse>('entity.transmit', request);
}, },
/**
* Submit a browser-native attachment download request.
*
* The backend download endpoint is expected to honor the supplied selector
* and respond with an attachment payload rather than JSON.
*/
download(request: EntityDownloadRequest): { transaction: string } {
return transceiveDownload<EntityDownloadRequest>('entity.download', request);
},
}; };
export default entityService; export default entityService;

View File

@@ -141,84 +141,3 @@ export async function transceiveStream<TRequest, TData>(
return { total }; return { total };
} }
/**
* Submit a browser-native file download request via a top-level form POST.
*
* This avoids buffering the response body in application-managed JavaScript
* memory. The backend is expected to accept form fields where `data` contains
* the serialized operation payload and to return an attachment response.
*/
export function transceiveDownload<TRequest>(
operation: string,
data: TRequest,
user?: string,
): { transaction: string } {
if (typeof document === 'undefined' || typeof window === 'undefined') {
throw new Error('Browser window is not available for download submission');
}
const request: ApiRequest<TRequest> = {
version: API_VERSION,
transaction: generateTransactionId(),
operation,
data,
user,
};
const form = document.createElement('form');
form.method = 'POST';
form.action = API_URL;
form.target = '_blank';
form.style.display = 'none';
appendHiddenField(form, 'version', String(request.version));
appendHiddenField(form, 'transaction', request.transaction);
appendHiddenField(form, 'operation', request.operation);
appendFormValue(form, 'data', request.data);
if (request.user) {
appendHiddenField(form, 'user', request.user);
}
document.body.appendChild(form);
form.submit();
form.remove();
return { transaction: request.transaction };
}
function appendHiddenField(form: HTMLFormElement, name: string, value: string): void {
const input = document.createElement('input');
input.type = 'hidden';
input.name = name;
input.value = value;
form.appendChild(input);
}
function appendFormValue(form: HTMLFormElement, name: string, value: unknown): void {
if (value === undefined) {
return;
}
if (value === null) {
appendHiddenField(form, name, '');
return;
}
if (Array.isArray(value)) {
value.forEach((item, index) => {
appendFormValue(form, `${name}[${index}]`, item);
});
return;
}
if (typeof value === 'object') {
Object.entries(value as Record<string, unknown>).forEach(([key, nestedValue]) => {
appendFormValue(form, `${name}[${key}]`, nestedValue);
});
return;
}
appendHiddenField(form, name, String(value));
}

View File

@@ -7,8 +7,7 @@ import { defineStore } from 'pinia'
import { entityService } from '../services' import { entityService } from '../services'
import { EntityObject, MessageObject } from '../models' import { EntityObject, MessageObject } from '../models'
import type { import type {
EntityBlobSelector, EntityListStreamRequest,
EntityDownloadRequest,
EntityTransmitRequest, EntityTransmitRequest,
EntityTransmitResponse, EntityTransmitResponse,
} from '../types/entity' } from '../types/entity'
@@ -19,7 +18,7 @@ import type {
ListRange, ListRange,
ListSort, ListSort,
} from '../types/common' } from '../types/common'
import type { MessageInterface, MessagePartInterface } from '@/types/message' import type { MessageInterface } from '@/types/message'
export const useEntitiesStore = defineStore('mailEntitiesStore', () => { export const useEntitiesStore = defineStore('mailEntitiesStore', () => {
// State // State
@@ -185,15 +184,15 @@ export const useEntitiesStore = defineStore('mailEntitiesStore', () => {
const response = await entityService.delta({ sources }) const response = await entityService.delta({ sources })
// Process delta and update store // Process delta and update store
Object.entries(response).forEach(([, providerData]) => { Object.entries(response).forEach(([provider, providerData]) => {
// Skip if no changes for provider // Skip if no changes for provider
if (providerData === false) return if (providerData === false) return
Object.entries(providerData).forEach(([, serviceData]) => { Object.entries(providerData).forEach(([service, serviceData]) => {
// Skip if no changes for service // Skip if no changes for service
if (serviceData === false) return if (serviceData === false) return
Object.entries(serviceData).forEach(([, collectionData]) => { Object.entries(serviceData).forEach(([collection, collectionData]) => {
// Skip if no changes for collection // Skip if no changes for collection
if (collectionData === false) return if (collectionData === false) return
@@ -475,39 +474,6 @@ export const useEntitiesStore = defineStore('mailEntitiesStore', () => {
} }
} }
async function download(target: EntityIdentifier, part?: Partial<MessagePartInterface>) {
let targetPart: EntityBlobSelector | undefined = undefined
if (part && (part.blobId || part.partId || part.cid)) {
targetPart = {
blobId: part.blobId ?? undefined,
partId: part.partId ?? undefined,
cid: part.cid ?? undefined,
}
}
let filename: string
if (part && part.name && part.name.trim().length > 0) {
filename = part.name.trim()
} else if (part) {
filename = `attachment-${part.partId || part.blobId || part.cid || 'unknown'}`
} else {
filename = 'message.eml'
}
const request: EntityDownloadRequest = {
target,
part: targetPart,
filename,
}
try {
entityService.download(request)
} catch (error: any) {
console.error('[Mail Manager][Store] - Failed to submit attachment download:', error)
throw error
}
}
// Return public API // Return public API
return { return {
// State (readonly) // State (readonly)
@@ -529,6 +495,5 @@ export const useEntitiesStore = defineStore('mailEntitiesStore', () => {
delta, delta,
move, move,
transmit, transmit,
download,
} }
}) })

View File

@@ -205,32 +205,4 @@ export interface EntityTransmitRequest {
export interface EntityTransmitResponse { export interface EntityTransmitResponse {
id: string; id: string;
status: 'queued' | 'sent'; status: 'queued' | 'sent';
} }
/**
* Entity Blob Fetch
*/
export interface EntityBlobSelector {
blobId?: string;
partId?: string;
cid?: string;
}
export interface EntityDownloadRequest {
target: EntityIdentifier;
part?: EntityBlobSelector;
filename?: string | null;
}
export interface EntityBlobsRequest {
target: EntityIdentifier;
parts: EntityBlobSelector[];
}
export interface EntityBlobsResult {
source: EntityIdentifier;
part: EntityBlobSelector;
blob: Blob;
}
export interface EntityBlobsResponse extends Array<EntityBlobsResult> {}