20 Commits

Author SHA1 Message Date
6dadd13acf Merge pull request 'chore(deps): update dependency @vue/test-utils to v2.4.11' (#100) from renovate/vue-test-utils-2.x-lockfile into main
Some checks failed
Renovate / renovate (push) Failing after 1m38s
Reviewed-on: #100
2026-06-06 04:08:49 +00:00
2d1ee97afe Merge pull request 'chore(deps): update dependency dompurify to v3.4.8' (#101) from renovate/dompurify-3.x-lockfile into main
Reviewed-on: #101
2026-06-06 04:08:34 +00:00
8432f5a823 chore(deps): update dependency dompurify to v3.4.8
All checks were successful
JS Unit Tests / test (pull_request) Successful in 32s
Build Test / build (pull_request) Successful in 36s
PHP Unit Tests / test (pull_request) Successful in 1m0s
2026-06-05 03:05:06 +00:00
30cfd06594 chore(deps): update dependency @vue/test-utils to v2.4.11
All checks were successful
Build Test / build (pull_request) Successful in 20s
JS Unit Tests / test (pull_request) Successful in 20s
PHP Unit Tests / test (pull_request) Successful in 58s
2026-06-05 03:05:04 +00:00
175981b5b2 Merge pull request 'chore(deps): update dependency dompurify to v3.4.5' (#96) from renovate/dompurify-3.x-lockfile into main
Some checks failed
Renovate / renovate (push) Failing after 1m13s
Reviewed-on: #96
2026-05-29 03:06:09 +00:00
0e8c91e82d Merge pull request 'chore(deps): update dependency vite to v8.0.14' (#97) from renovate/vite-8.x-lockfile into main
Reviewed-on: #97
2026-05-29 03:05:59 +00:00
2fc9cbe033 Merge pull request 'chore(deps): update vitest monorepo to v4.1.7' (#98) from renovate/vitest-monorepo into main
Reviewed-on: #98
2026-05-29 03:05:49 +00:00
9deac1682e Merge pull request 'feat: mail entity download' (#99) from feat/mail-entity-download into main
Reviewed-on: #99
2026-05-29 03:05:38 +00:00
812a6680a8 feat: mail entity download
All checks were successful
Build Test / build (pull_request) Successful in 20s
JS Unit Tests / test (pull_request) Successful in 18s
PHP Unit Tests / test (pull_request) Successful in 40s
Signed-off-by: Sebastian Krupinski <krupinski01@gmail.com>
2026-05-28 23:02:37 -04:00
a7f57aecf7 chore(deps): update vitest monorepo to v4.1.7
All checks were successful
JS Unit Tests / test (pull_request) Successful in 23s
Build Test / build (pull_request) Successful in 26s
PHP Unit Tests / test (pull_request) Successful in 47s
2026-05-26 03:04:32 +00:00
9a234fb758 chore(deps): update dependency vite to v8.0.14
All checks were successful
Build Test / build (pull_request) Successful in 31s
JS Unit Tests / test (pull_request) Successful in 30s
PHP Unit Tests / test (pull_request) Successful in 49s
2026-05-24 03:04:36 +00:00
87940f8eaf chore(deps): update dependency dompurify to v3.4.5
All checks were successful
Build Test / build (pull_request) Successful in 23s
JS Unit Tests / test (pull_request) Successful in 32s
PHP Unit Tests / test (pull_request) Successful in 1m6s
2026-05-24 03:04:30 +00:00
8d716e3c72 Merge pull request 'refactor: list and fetch' (#95) from refactor/list-and-fetch into main
Some checks failed
Renovate / renovate (push) Failing after 1m55s
Reviewed-on: #95
2026-05-17 21:58:01 +00:00
4e1d6d65d0 refactor: list and fetch
All checks were successful
Build Test / build (pull_request) Successful in 13s
JS Unit Tests / test (pull_request) Successful in 12s
PHP Unit Tests / test (pull_request) Successful in 33s
Signed-off-by: Sebastian Krupinski <krupinski01@gmail.com>
2026-05-17 17:57:44 -04:00
a4a87dd82d Merge pull request 'chore(deps): update dependency eslint to v10.4.0' (#92) from renovate/eslint-monorepo into main
All checks were successful
Renovate / renovate (push) Successful in 2m55s
Reviewed-on: #92
2026-05-16 04:16:19 +00:00
f8fb84dd11 chore(deps): update dependency eslint to v10.4.0
All checks were successful
JS Unit Tests / test (pull_request) Successful in 23s
Build Test / build (pull_request) Successful in 26s
PHP Unit Tests / test (pull_request) Successful in 1m4s
2026-05-16 03:02:33 +00:00
b2a1a17acd Merge pull request 'chore: bump packages' (#91) from chore/bump-packages into main
All checks were successful
Renovate / renovate (push) Successful in 2m33s
Reviewed-on: #91
2026-05-15 13:34:57 +00:00
cf10ad0a50 chore: bump packages
All checks were successful
Build Test / build (pull_request) Successful in 11s
JS Unit Tests / test (pull_request) Successful in 10s
PHP Unit Tests / test (pull_request) Successful in 40s
Signed-off-by: Sebastian Krupinski <krupinski01@gmail.com>
2026-05-15 09:33:59 -04:00
8bb57052cd Merge pull request 'chore(deps): update dependency @vitejs/plugin-vue to v6.0.7' (#90) from renovate/vitejs-plugin-vue-6.x into main
Reviewed-on: #90
2026-05-15 12:56:22 +00:00
dd105767d4 chore(deps): update dependency @vitejs/plugin-vue to v6.0.7
All checks were successful
JS Unit Tests / test (pull_request) Successful in 23s
Build Test / build (pull_request) Successful in 28s
PHP Unit Tests / test (pull_request) Successful in 1m2s
2026-05-15 12:55:34 +00:00
10 changed files with 583 additions and 578 deletions

989
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -21,45 +21,45 @@
"test:coverage": "vitest run --coverage --config tests/js/vitest.config.ts" "test:coverage": "vitest run --coverage --config tests/js/vitest.config.ts"
}, },
"dependencies": { "dependencies": {
"@fontsource/inter": "5.2.8", "@fontsource/inter": "^5.2.8",
"@fontsource/poppins": "5.2.7", "@fontsource/poppins": "^5.2.7",
"@fontsource/public-sans": "5.2.7", "@fontsource/public-sans": "^5.2.7",
"@fontsource/roboto": "5.2.10", "@fontsource/roboto": "^5.2.10",
"@mdi/font": "7.4.47", "@mdi/font": "^7.4.47",
"@tsconfig/node24": "24.0.4", "@tsconfig/node24": "^24.0.4",
"@typescript-eslint/parser": "^8.55.0", "@typescript-eslint/parser": "^8.59.3",
"@vue/compiler-sfc": "^3.5.33", "@vue/compiler-sfc": "^3.5.34",
"dompurify": "^3.4.1", "dompurify": "^3.4.3",
"pinia": "3.0.4", "pinia": "^3.0.4",
"vee-validate": "^4.15.1", "vee-validate": "^4.15.1",
"vite-plugin-vuetify": "2.1.3", "vite-plugin-vuetify": "^2.1.3",
"vue": "3.5.28", "vue": "^3.5.34",
"vue-router": "5.0.7", "vue-router": "^5.0.7",
"vue3-perfect-scrollbar": "2.0.0", "vue3-perfect-scrollbar": "^2.0.0",
"vuetify": "4.0.7" "vuetify": "^4.0.7"
}, },
"devDependencies": { "devDependencies": {
"@eslint/js": "^10.0.0", "@eslint/js": "^10.0.1",
"@types/dompurify": "^3.2.0", "@types/dompurify": "^3.2.0",
"@types/node": "25.8.0", "@types/node": "^25.8.0",
"@vitejs/plugin-vue": "6.0.6", "@vitejs/plugin-vue": "^6.0.7",
"@vitest/coverage-v8": "^4.0.18", "@vitest/coverage-v8": "^4.1.6",
"@vitest/ui": "^4.0.18", "@vitest/ui": "^4.1.6",
"@vue/eslint-config-prettier": "10.2.0", "@vue/eslint-config-prettier": "^10.2.0",
"@vue/test-utils": "^2.4.8", "@vue/test-utils": "^2.4.10",
"@vue/tsconfig": "0.9.1", "@vue/tsconfig": "^0.9.1",
"eslint": "^10.0.0", "eslint": "^10.3.0",
"eslint-plugin-vue": "10.9.1", "eslint-plugin-vue": "^10.9.1",
"jsdom": "^29.0.0", "jsdom": "^29.1.1",
"prettier": "3.8.3", "prettier": "^3.8.3",
"sass": "1.99.0", "sass": "^1.99.0",
"sass-loader": "16.0.8", "sass-loader": "^16.0.8",
"typescript": "6.0.3", "typescript": "^6.0.3",
"typescript-eslint": "^8.59.0", "typescript-eslint": "^8.59.3",
"vite": "8.0.13", "vite": "^8.0.13",
"vite-plugin-static-copy": "^4.0.0", "vite-plugin-static-copy": "^4.1.0",
"vitest": "^4.0.18", "vitest": "^4.1.6",
"vue-cli-plugin-vuetify": "2.5.8", "vue-cli-plugin-vuetify": "^2.5.8",
"vue-tsc": "^3.2.7" "vue-tsc": "^3.2.9"
} }
} }

View File

@@ -28,6 +28,8 @@ use KTXF\Resource\Provider\ResourceServiceLocationInterface;
*/ */
interface ProviderServiceDiscoverInterface { interface ProviderServiceDiscoverInterface {
public const CAPABILITY_SERVICE_DISCOVER = 'ServiceDiscover';
/** /**
* Attempts to discover service configuration using provider-specific methods. * Attempts to discover service configuration using provider-specific methods.
* *

View File

@@ -28,6 +28,8 @@ use KTXF\Mail\Service\ServiceMutableInterface;
*/ */
interface ProviderServiceTestInterface { interface ProviderServiceTestInterface {
public const CAPABILITY_SERVICE_TEST = 'ServiceTest';
/** /**
* Test a service connection * Test a service connection
* *

View File

@@ -12,8 +12,10 @@ namespace KTXF\Mail\Service;
use Generator; use Generator;
use KTXF\Mail\Collection\CollectionBaseInterface; use KTXF\Mail\Collection\CollectionBaseInterface;
use KTXF\Mail\Object\AddressInterface; use KTXF\Mail\Object\AddressInterface;
use KTXF\Resource\BinaryResource;
use KTXF\Resource\Delta\Delta; use KTXF\Resource\Delta\Delta;
use KTXF\Resource\Filter\IFilter; use KTXF\Resource\Filter\IFilter;
use KTXF\Resource\Identifier\EntityIdentifierInterface;
use KTXF\Resource\Provider\ResourceServiceBaseInterface; use KTXF\Resource\Provider\ResourceServiceBaseInterface;
use KTXF\Resource\Range\IRange; use KTXF\Resource\Range\IRange;
use KTXF\Resource\Range\RangeType; use KTXF\Resource\Range\RangeType;
@@ -166,9 +168,9 @@ interface ServiceBaseInterface extends ResourceServiceBaseInterface {
* @param IRange|null $range Optional pagination * @param IRange|null $range Optional pagination
* @param array|null $properties Optional message properties to fetch * @param array|null $properties Optional message properties to fetch
* *
* @return array<string|int,EntityBaseInterface> Messages indexed by ID * @return array<string,EntityBaseInterface> Messages indexed by Urn
*/ */
public function entityList(string|int $collection, ?IFilter $filter = null, ?ISort $sort = null, ?IRange $range = null, ?array $properties = null): array; public function entityListBulk(string|int $collection, ?IFilter $filter = null, ?ISort $sort = null, ?IRange $range = null, ?array $properties = null): array;
/** /**
* Lists messages in a collection * Lists messages in a collection
@@ -244,11 +246,33 @@ interface ServiceBaseInterface extends ResourceServiceBaseInterface {
* *
* @since 2025.05.01 * @since 2025.05.01
* *
* @param string|int $collection Collection ID * @param EntityIdentifierInterface ...$identifiers Message identifiers to fetch
* @param string|int ...$identifiers Message IDs to fetch
* *
* @return array<string|int,EntityBaseInterface> Messages indexed by ID * @return array<string,EntityBaseInterface> Messages indexed by Urn
*/ */
public function entityFetch(string|int $collection, string|int ...$identifiers): array; public function entityFetchBulk(EntityIdentifierInterface ...$identifiers): array;
/**
* Fetches one or more entities
*
* @since 2025.05.01
*
* @param EntityIdentifierInterface ...$identifiers Message identifiers to fetch
*
* @return Generator<string,EntityBaseInterface> Yields messages one by one
*/
public function entityFetchStream(EntityIdentifierInterface ...$identifiers): Generator;
/**
* Downloads a message or part of a message
*
* @since 2025.05.01
*
* @param EntityIdentifierInterface $target Message identifier
* @param array|null $part Optional part to download
*
* @return BinaryResource
*/
public function entityDownload(EntityIdentifierInterface $target, array|null $part): BinaryResource;
} }

View File

@@ -0,0 +1,37 @@
<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: Sebastian Krupinski <krupinski01@gmail.com>
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace KTXF\Resource;
/**
* Carries file-like binary content metadata and a byte stream.
*/
final class BinaryResource
{
public function __construct(
private readonly string $filename,
private readonly string $mimeType,
private readonly \Generator $stream,
) {}
public function filename(): string
{
return $this->filename;
}
public function mimeType(): string
{
return $this->mimeType;
}
public function stream(): \Generator
{
return $this->stream;
}
}

View File

@@ -71,6 +71,13 @@ abstract class NodeBaseAbstract implements NodeBaseInterface {
return $this->data[static::PROPERTY_TYPE]; return $this->data[static::PROPERTY_TYPE];
} }
/**
* @inheritDoc
*/
public function urn(): string {
return (string) $this->nodeIdentifier();
}
/** /**
* @inheritDoc * @inheritDoc
*/ */

View File

@@ -35,6 +35,13 @@ interface NodeBaseInterface extends JsonSerializable {
* @since 2025.05.01 * @since 2025.05.01
*/ */
public function type(): string; public function type(): string;
/**
* Node URN
*
* @since 2025.05.01
*/
public function urn(): string;
/** /**
* Provider identifier * Provider identifier

View File

@@ -14,11 +14,6 @@ interface ResourceProviderBaseInterface extends ProviderInterface, JsonSerializa
public const CAPABILITY_SERVICE_LIST = 'ServiceList'; public const CAPABILITY_SERVICE_LIST = 'ServiceList';
public const CAPABILITY_SERVICE_FETCH = 'ServiceFetch'; public const CAPABILITY_SERVICE_FETCH = 'ServiceFetch';
public const CAPABILITY_SERVICE_EXTANT = 'ServiceExtant'; public const CAPABILITY_SERVICE_EXTANT = 'ServiceExtant';
public const CAPABILITY_SERVICE_CREATE = 'ServiceCreate';
public const CAPABILITY_SERVICE_MODIFY = 'ServiceModify';
public const CAPABILITY_SERVICE_DESTROY = 'ServiceDestroy';
public const CAPABILITY_SERVICE_DISCOVER = 'ServiceDiscover';
public const CAPABILITY_SERVICE_TEST = 'ServiceTest';
public const JSON_TYPE = 'resource.provider'; public const JSON_TYPE = 'resource.provider';
public const JSON_PROPERTY_TYPE = '@type'; public const JSON_PROPERTY_TYPE = '@type';

View File

@@ -12,6 +12,10 @@ namespace KTXF\Resource\Provider;
use KTXF\Json\JsonDeserializable; use KTXF\Json\JsonDeserializable;
interface ResourceProviderServiceMutateInterface extends JsonDeserializable { interface ResourceProviderServiceMutateInterface extends JsonDeserializable {
public const CAPABILITY_SERVICE_CREATE = 'ServiceCreate';
public const CAPABILITY_SERVICE_MODIFY = 'ServiceModify';
public const CAPABILITY_SERVICE_DESTROY = 'ServiceDestroy';
/** /**
* construct and new blank service instance * construct and new blank service instance