diff --git a/.env b/.env index 1a3442d142..4903a8b491 100644 --- a/.env +++ b/.env @@ -50,9 +50,9 @@ _APP_DB_ROOT_PASS=rootsecretpassword _APP_DB_ADAPTER_DOCUMENTSDB=mongodb _APP_DB_HOST_DOCUMENTSDB=mongodb _APP_DB_PORT_DOCUMENTSDB=27017 -_APP_DB_ADAPTER_VECTORDB=postgresql -_APP_DB_HOST_VECTORDB=postgresql -_APP_DB_PORT_VECTORDB=5432 +_APP_DB_ADAPTER_VECTORSDB=postgresql +_APP_DB_HOST_VECTORSDB=postgresql +_APP_DB_PORT_VECTORSDB=5432 _APP_EMBEDDING_MODELS=embeddinggemma _APP_EMBEDDING_ENDPOINT='http://ollama:11434/api/embed' _APP_EMBEDDING_TIMEOUT=30000 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index c6837673d5..0ccc8e8372 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -111,7 +111,7 @@ $ git push origin [name_of_your_new_branch] ## Setup From Source -To set up a working **development environment**, just fork the project git repository and install the backend and frontend dependencies using the proper package manager and create run the docker-compose stack. +To set up a working **development environment**, just fork the project git repository and install the backend and frontend dependencies using the proper package manager and run the docker-compose stack. > If you just want to install Appwrite for day-to-day use and not as a contributor, you can reference the [installation guide](https://github.com/appwrite/appwrite#installation), the [getting started guide](https://appwrite.io/docs/quick-starts), or the main [README](README.md) file. @@ -173,12 +173,12 @@ Learn more at our [Technology Stack](#technology-stack) section. - [MVVM](https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93viewmodel) - Appwrite console architecture ##### Container Namespace Conventions -To keep our services easy to understand within Docker we follow a naming convention for all our containers depending on it's intended use. +To keep our services easy to understand within Docker we follow a naming convention for all our containers depending on its intended use. `appwrite-worker-X` - Workers (`src/Appwrite/Platform/Workers/*`) `appwrite-task-X` - Tasks (`src/Appwrite/Platform/Tasks/*`) -Other containes should be named the same as their service, for example `redis` should just be called `redis`. +Other containers should be named the same as their service, for example `redis` should just be called `redis`. ##### Security @@ -189,7 +189,7 @@ Other containes should be named the same as their service, for example `redis` s ## Modules -As Appwrite grows, we noticed approach of having all service endpoints in `app/controllers/api/[service].php` is not maintainable. Not only it creates massive files, it also doesnt contain all product's features such as workers or tasks. While there might still be some occurances of those controller files, we avoid it in all new development, and gradually migrate existing controllers to **HTTP modules**. +As Appwrite grows, we noticed approach of having all service endpoints in `app/controllers/api/[service].php` is not maintainable. Not only it creates massive files, it also doesn't contain all product's features such as workers or tasks. While there might still be some occurrences of those controller files, we avoid it in all new development, and gradually migrate existing controllers to **HTTP modules**. ### HTTP Endpoints @@ -204,7 +204,7 @@ Tips and tricks: 1. If endpoint doesn't have resource, use service name as resource name too > Example: `Modules/Sites/Http/Sites/Get.php` -2. If there are multiple resources, use then all in folder structure +2. If there are multiple resources, use them all in folder structure > Example: `Modules/Sites/Http/Deployments/Builds/Create.php` 3. Action can only be `Get`, `Create`, `Update`, `Delete` or `XList` @@ -395,7 +395,7 @@ These are the current metrics we collect usage stats for: > Note: The curly brackets in the metric name represents a template and is replaced with a value when the metric is processed. -Metrics are collected within 3 scopes Daily, monthly, an infinity. Adding new usage metric in order to aggregate usage stats is very simple, but very much dependent on where do you want to collect +Metrics are collected within 3 scopes Daily, monthly, and infinity. Adding new usage metric in order to aggregate usage stats is very simple, but very much dependent on where do you want to collect statistics ,via API or via background worker. For both cases you will need to add a `const` variable in `app/init.php` under the usage metrics list using the naming convention `METRIC_` as shown below. ```php @@ -661,7 +661,7 @@ docker compose exec redis redis-cli FLUSHALL ## Using preview domains locally -Appwrite Functions are automatically given a domain you can visit to execute the function. This domain has format `[SOMETHING].functions.localhost` unless you changed `_APP_DOMAIN_FUNCTIONS` environment variable. This default value works great when running Appwrite locally, but it can be impossible to use preview domains with Cloud woekspaces such as Gitpod or GitHub Codespaces. +Appwrite Functions are automatically given a domain you can visit to execute the function. This domain has format `[SOMETHING].functions.localhost` unless you changed `_APP_DOMAIN_FUNCTIONS` environment variable. This default value works great when running Appwrite locally, but it can be impossible to use preview domains with Cloud workspaces such as Gitpod or GitHub Codespaces. To use preview domains on Cloud workspaces, you can visit hostname provided by them, and supply function's preview domain as URL parameter: diff --git a/Dockerfile b/Dockerfile index 161a425e80..266d4501d0 100755 --- a/Dockerfile +++ b/Dockerfile @@ -70,6 +70,7 @@ RUN chmod +x /usr/local/bin/doctor && \ chmod +x /usr/local/bin/sdks && \ chmod +x /usr/local/bin/specs && \ chmod +x /usr/local/bin/ssl && \ + chmod +x /usr/local/bin/time-travel && \ chmod +x /usr/local/bin/screenshot && \ chmod +x /usr/local/bin/test && \ chmod +x /usr/local/bin/upgrade && \ diff --git a/app/config/collections.php b/app/config/collections.php index b30388997c..3af20ff2ac 100644 --- a/app/config/collections.php +++ b/app/config/collections.php @@ -4,7 +4,7 @@ $common = include __DIR__ . '/collections/common.php'; $projects = include __DIR__ . '/collections/projects.php'; $databases = include __DIR__ . '/collections/databases.php'; -$vectordb = include __DIR__ . '/collections/vectordb.php'; +$vectorsdb = include __DIR__ . '/collections/vectorsdb.php'; $platform = include __DIR__ . '/collections/platform.php'; $logs = include __DIR__ . '/collections/logs.php'; @@ -27,7 +27,7 @@ unset($common['files']); $collections = [ 'buckets' => $buckets, 'databases' => $databases, - 'vectordb' => $vectordb, + 'vectorsdb' => $vectorsdb, 'projects' => array_merge_recursive($projects, $common), 'console' => array_merge_recursive($platform, $common), 'logs' => $logs, diff --git a/app/config/collections/projects.php b/app/config/collections/projects.php index 7b4774ff6a..e3d8d6baec 100644 --- a/app/config/collections/projects.php +++ b/app/config/collections/projects.php @@ -786,6 +786,7 @@ return [ 'filters' => [], ], [ + // At the moment, always empty (no runtime supports it yet) 'array' => false, '$id' => ID::custom('startCommand'), 'type' => Database::VAR_STRING, @@ -796,17 +797,6 @@ return [ 'default' => null, 'filters' => [], ], - [ - 'array' => false, - '$id' => ID::custom('specification'), - 'type' => Database::VAR_STRING, - 'format' => '', - 'size' => 128, - 'signed' => false, - 'required' => false, - 'default' => APP_COMPUTE_SPECIFICATION_DEFAULT, - 'filters' => [], - ], [ 'array' => false, '$id' => ID::custom('buildSpecification'), @@ -1264,17 +1254,6 @@ return [ 'array' => false, 'filters' => [], ], - [ - 'array' => false, - '$id' => ID::custom('specification'), - 'type' => Database::VAR_STRING, - 'format' => '', - 'size' => 128, - 'signed' => false, - 'required' => false, - 'default' => APP_COMPUTE_SPECIFICATION_DEFAULT, - 'filters' => [], - ], [ 'array' => false, '$id' => ID::custom('buildSpecification'), diff --git a/app/config/collections/vectordb.php b/app/config/collections/vectorsdb.php similarity index 100% rename from app/config/collections/vectordb.php rename to app/config/collections/vectorsdb.php diff --git a/app/controllers/api/project.php b/app/controllers/api/project.php index 2480de5686..b79180c91c 100644 --- a/app/controllers/api/project.php +++ b/app/controllers/api/project.php @@ -77,13 +77,13 @@ Http::get('/v1/project/usage') METRIC_DATABASES_OPERATIONS_WRITES, METRIC_DATABASES_OPERATIONS_WRITES_DOCUMENTSDB, METRIC_FILES_IMAGES_TRANSFORMED, - // VectorDB totals - METRIC_DATABASES_VECTORDB, - METRIC_COLLECTIONS_VECTORDB, - METRIC_DOCUMENTS_VECTORDB, - METRIC_DATABASES_STORAGE_VECTORDB, - METRIC_DATABASES_OPERATIONS_READS_VECTORDB, - METRIC_DATABASES_OPERATIONS_WRITES_VECTORDB, + // VectorsDB totals + METRIC_DATABASES_VECTORSDB, + METRIC_COLLECTIONS_VECTORSDB, + METRIC_DOCUMENTS_VECTORSDB, + METRIC_DATABASES_STORAGE_VECTORSDB, + METRIC_DATABASES_OPERATIONS_READS_VECTORSDB, + METRIC_DATABASES_OPERATIONS_WRITES_VECTORSDB, // Embeddings totals METRIC_EMBEDDINGS_TEXT, METRIC_EMBEDDINGS_TEXT_TOTAL_TOKENS, @@ -105,13 +105,13 @@ Http::get('/v1/project/usage') METRIC_DATABASES_OPERATIONS_WRITES, METRIC_DATABASES_OPERATIONS_WRITES_DOCUMENTSDB, METRIC_FILES_IMAGES_TRANSFORMED, - // VectorDB time series - METRIC_DATABASES_VECTORDB, - METRIC_COLLECTIONS_VECTORDB, - METRIC_DOCUMENTS_VECTORDB, - METRIC_DATABASES_STORAGE_VECTORDB, - METRIC_DATABASES_OPERATIONS_READS_VECTORDB, - METRIC_DATABASES_OPERATIONS_WRITES_VECTORDB, + // VectorsDB time series + METRIC_DATABASES_VECTORSDB, + METRIC_COLLECTIONS_VECTORSDB, + METRIC_DOCUMENTS_VECTORSDB, + METRIC_DATABASES_STORAGE_VECTORSDB, + METRIC_DATABASES_OPERATIONS_READS_VECTORSDB, + METRIC_DATABASES_OPERATIONS_WRITES_VECTORSDB, // Embeddings time series METRIC_EMBEDDINGS_TEXT, METRIC_EMBEDDINGS_TEXT_TOTAL_TOKENS, @@ -404,12 +404,12 @@ Http::get('/v1/project/usage') 'databasesWritesTotal' => $total[METRIC_DATABASES_OPERATIONS_WRITES], 'documentsdbDatabasesReadsTotal' => $total[METRIC_DATABASES_OPERATIONS_READS_DOCUMENTSDB], 'documentsdbDatabasesWritesTotal' => $total[METRIC_DATABASES_OPERATIONS_WRITES_DOCUMENTSDB], - 'vectordbDatabasesTotal' => $total[METRIC_DATABASES_VECTORDB] ?? 0, - 'vectordbCollectionsTotal' => $total[METRIC_COLLECTIONS_VECTORDB] ?? 0, - 'vectordbDocumentsTotal' => $total[METRIC_DOCUMENTS_VECTORDB] ?? 0, - 'vectordbDatabasesStorageTotal' => $total[METRIC_DATABASES_STORAGE_VECTORDB] ?? 0, - 'vectordbDatabasesReadsTotal' => $total[METRIC_DATABASES_OPERATIONS_READS_VECTORDB] ?? 0, - 'vectordbDatabasesWritesTotal' => $total[METRIC_DATABASES_OPERATIONS_WRITES_VECTORDB] ?? 0, + 'vectorsdbDatabasesTotal' => $total[METRIC_DATABASES_VECTORSDB] ?? 0, + 'vectorsdbCollectionsTotal' => $total[METRIC_COLLECTIONS_VECTORSDB] ?? 0, + 'vectorsdbDocumentsTotal' => $total[METRIC_DOCUMENTS_VECTORSDB] ?? 0, + 'vectorsdbDatabasesStorageTotal' => $total[METRIC_DATABASES_STORAGE_VECTORSDB] ?? 0, + 'vectorsdbDatabasesReadsTotal' => $total[METRIC_DATABASES_OPERATIONS_READS_VECTORSDB] ?? 0, + 'vectorsdbDatabasesWritesTotal' => $total[METRIC_DATABASES_OPERATIONS_WRITES_VECTORSDB] ?? 0, 'executionsBreakdown' => $executionsBreakdown, 'bucketsBreakdown' => $bucketsBreakdown, 'databasesReads' => $usage[METRIC_DATABASES_OPERATIONS_READS], @@ -417,12 +417,12 @@ Http::get('/v1/project/usage') 'documentsdbDatabasesReads' => $usage[METRIC_DATABASES_OPERATIONS_READS_DOCUMENTSDB], 'documentsdbDatabasesWrites' => $usage[METRIC_DATABASES_OPERATIONS_WRITES_DOCUMENTSDB], 'documentsdbDatabasesStorage' => $usage[METRIC_DATABASES_STORAGE_DOCUMENTSDB], - 'vectordbDatabases' => $usage[METRIC_DATABASES_VECTORDB] ?? [], - 'vectordbCollections' => $usage[METRIC_COLLECTIONS_VECTORDB] ?? [], - 'vectordbDocuments' => $usage[METRIC_DOCUMENTS_VECTORDB] ?? [], - 'vectordbDatabasesStorage' => $usage[METRIC_DATABASES_STORAGE_VECTORDB] ?? [], - 'vectordbDatabasesReads' => $usage[METRIC_DATABASES_OPERATIONS_READS_VECTORDB] ?? [], - 'vectordbDatabasesWrites' => $usage[METRIC_DATABASES_OPERATIONS_WRITES_VECTORDB] ?? [], + 'vectorsdbDatabases' => $usage[METRIC_DATABASES_VECTORSDB] ?? [], + 'vectorsdbCollections' => $usage[METRIC_COLLECTIONS_VECTORSDB] ?? [], + 'vectorsdbDocuments' => $usage[METRIC_DOCUMENTS_VECTORSDB] ?? [], + 'vectorsdbDatabasesStorage' => $usage[METRIC_DATABASES_STORAGE_VECTORSDB] ?? [], + 'vectorsdbDatabasesReads' => $usage[METRIC_DATABASES_OPERATIONS_READS_VECTORSDB] ?? [], + 'vectorsdbDatabasesWrites' => $usage[METRIC_DATABASES_OPERATIONS_WRITES_VECTORSDB] ?? [], 'databasesStorageBreakdown' => $databasesStorageBreakdown, 'executionsMbSecondsBreakdown' => $executionsMbSecondsBreakdown, 'buildsMbSecondsBreakdown' => $buildsMbSecondsBreakdown, diff --git a/app/controllers/general.php b/app/controllers/general.php index a4618fe982..57edd98bc4 100644 --- a/app/controllers/general.php +++ b/app/controllers/general.php @@ -30,6 +30,8 @@ use Appwrite\Utopia\Response\Filters\V16 as ResponseV16; use Appwrite\Utopia\Response\Filters\V17 as ResponseV17; use Appwrite\Utopia\Response\Filters\V18 as ResponseV18; use Appwrite\Utopia\Response\Filters\V19 as ResponseV19; +use Appwrite\Utopia\Response\Filters\V20 as ResponseV20; +use Appwrite\Utopia\Response\Filters\V21 as ResponseV21; use Appwrite\Utopia\View; use Executor\Executor; use MaxMind\Db\Reader; @@ -322,7 +324,7 @@ function router(Http $utopia, Database $dbForPlatform, callable $getProjectDB, S }; $runtimes = Config::getParam($version === 'v2' ? 'runtimes-v2' : 'runtimes', []); - $spec = Config::getParam('specifications')[$resource->getAttribute('specification', APP_COMPUTE_SPECIFICATION_DEFAULT)]; + $spec = Config::getParam('specifications')[$resource->getAttribute('runtimeSpecification', APP_COMPUTE_SPECIFICATION_DEFAULT)]; $runtime = match ($type) { 'function' => $runtimes[$resource->getAttribute('runtime')] ?? null, @@ -552,6 +554,10 @@ function router(Http $utopia, Database $dbForPlatform, callable $getProjectDB, S } } + if (!empty($deployment->getAttribute('startCommand', ''))) { + $startCommand = 'cd /usr/local/server/src/function/ && ' . $deployment->getAttribute('startCommand', ''); + } + $runtimeEntrypoint = match ($version) { 'v2' => '', default => "cp /tmp/code.$extension /mnt/code/code.$extension && nohup helpers/start.sh \"$startCommand\"", @@ -933,17 +939,23 @@ Http::init() */ $responseFormat = $request->getHeader('x-appwrite-response-format', System::getEnv('_APP_SYSTEM_RESPONSE_FORMAT', '')); if ($responseFormat) { - if (version_compare($responseFormat, '1.4.0', '<')) { - $response->addFilter(new ResponseV16()); + if (version_compare($responseFormat, '1.9.0', '<')) { + $response->addFilter(new ResponseV21()); } - if (version_compare($responseFormat, '1.5.0', '<')) { - $response->addFilter(new ResponseV17()); + if (version_compare($responseFormat, '1.8.0', '<')) { + $response->addFilter(new ResponseV20()); + } + if (version_compare($responseFormat, '1.7.0', '<')) { + $response->addFilter(new ResponseV19()); } if (version_compare($responseFormat, '1.6.0', '<')) { $response->addFilter(new ResponseV18()); } - if (version_compare($responseFormat, '1.7.0', '<')) { - $response->addFilter(new ResponseV19()); + if (version_compare($responseFormat, '1.5.0', '<')) { + $response->addFilter(new ResponseV17()); + } + if (version_compare($responseFormat, '1.4.0', '<')) { + $response->addFilter(new ResponseV16()); } if (version_compare($responseFormat, APP_VERSION_STABLE, '>')) { $warnings[] = "The current SDK is built for Appwrite " . $responseFormat . ". However, the current Appwrite server version is " . APP_VERSION_STABLE . ". Please downgrade your SDK to match the Appwrite version: https://appwrite.io/docs/sdks"; diff --git a/app/controllers/shared/api.php b/app/controllers/shared/api.php index 5554c8e694..f1d6aea50a 100644 --- a/app/controllers/shared/api.php +++ b/app/controllers/shared/api.php @@ -214,6 +214,8 @@ Http::init() } if (!$dbKey) { + \var_dump($apiKey); + \var_dump($request->getHeader('x-appwrite-key', '')); throw new Exception(Exception::USER_UNAUTHORIZED); } @@ -471,7 +473,7 @@ Http::init() $path = $route->getMatchedPath(); $databaseType = match (true) { str_contains($path, '/documentsdb') => DATABASE_TYPE_DOCUMENTSDB, - str_contains($path, '/vectordb') => DATABASE_TYPE_VECTORDB, + str_contains($path, '/vectorsdb') => DATABASE_TYPE_VECTORSDB, default => '', }; diff --git a/app/http.php b/app/http.php index 77f9bb2881..a2ec1a93b0 100644 --- a/app/http.php +++ b/app/http.php @@ -420,8 +420,8 @@ $http->on(Constant::EVENT_START, function (Server $http) use ($payloadSize, $tot $documentsSharedTablesV1 = \explode(',', System::getEnv('_APP_DATABASE_DOCUMENTSDB_SHARED_TABLES_V1', '')); $documentsSharedTablesV2 = \array_diff($documentsSharedTables, $documentsSharedTablesV1); - $vectorSharedTables = \explode(',', System::getEnv('_APP_DATABASE_VECTORDB_SHARED_TABLES', '')); - $vectorSharedTablesV1 = \explode(',', System::getEnv('_APP_DATABASE_VECTORDB_SHARED_TABLES_V1', '')); + $vectorSharedTables = \explode(',', System::getEnv('_APP_DATABASE_VECTORSDB_SHARED_TABLES', '')); + $vectorSharedTablesV1 = \explode(',', System::getEnv('_APP_DATABASE_VECTORSDB_SHARED_TABLES_V1', '')); $vectorSharedTablesV2 = \array_diff($vectorSharedTables, $vectorSharedTablesV1); $cache = $app->getResource('cache'); diff --git a/app/init/constants.php b/app/init/constants.php index 9a31dfa4ce..d62ff0d6b5 100644 --- a/app/init/constants.php +++ b/app/init/constants.php @@ -93,6 +93,7 @@ const APP_SOCIAL_YOUTUBE = 'https://www.youtube.com/c/appwrite?sub_confirmation= const APP_COMPUTE_CPUS_DEFAULT = 0.5; const APP_COMPUTE_MEMORY_DEFAULT = 512; const APP_COMPUTE_SPECIFICATION_DEFAULT = Specification::S_1VCPU_512MB; +const APP_COMPUTE_DEPLOYMENT_MAX_RETENTION = 100 * 365; // 100 years const APP_SDK_PLATFORM_SERVER = 'server'; const APP_SDK_PLATFORM_CLIENT = 'client'; const APP_SDK_PLATFORM_CONSOLE = 'console'; @@ -303,20 +304,20 @@ const METRIC_DATABASE_ID_OPERATIONS_READS_DOCUMENTSDB = 'documentsdb.{databaseIn const METRIC_DATABASES_OPERATIONS_WRITES_DOCUMENTSDB = 'documentsdb.databases.operations.writes'; const METRIC_DATABASE_ID_OPERATIONS_WRITES_DOCUMENTSDB = 'documentsdb.{databaseInternalId}.databases.operations.writes'; -// vectordb -const METRIC_DATABASES_VECTORDB = 'vectordb.databases'; -const METRIC_COLLECTIONS_VECTORDB = 'vectordb.collections'; -const METRIC_DATABASES_STORAGE_VECTORDB = 'vectordb.databases.storage'; -const METRIC_DATABASE_ID_COLLECTIONS_VECTORDB = 'vectordb.{databaseInternalId}.collections'; -const METRIC_DATABASE_ID_STORAGE_VECTORDB = 'vectordb.{databaseInternalId}.databases.storage'; -const METRIC_DOCUMENTS_VECTORDB = 'vectordb.documents'; -const METRIC_DATABASE_ID_DOCUMENTS_VECTORDB = 'vectordb.{databaseInternalId}.documents'; -const METRIC_DATABASE_ID_COLLECTION_ID_DOCUMENTS_VECTORDB = 'vectordb.{databaseInternalId}.{collectionInternalId}.documents'; -const METRIC_DATABASE_ID_COLLECTION_ID_STORAGE_VECTORDB = 'vectordb.{databaseInternalId}.{collectionInternalId}.databases.storage'; -const METRIC_DATABASES_OPERATIONS_READS_VECTORDB = 'vectordb.databases.operations.reads'; -const METRIC_DATABASE_ID_OPERATIONS_READS_VECTORDB = 'vectordb.{databaseInternalId}.databases.operations.reads'; -const METRIC_DATABASES_OPERATIONS_WRITES_VECTORDB = 'vectordb.databases.operations.writes'; -const METRIC_DATABASE_ID_OPERATIONS_WRITES_VECTORDB = 'vectordb.{databaseInternalId}.databases.operations.writes'; +// vectorsdb +const METRIC_DATABASES_VECTORSDB = 'vectorsdb.databases'; +const METRIC_COLLECTIONS_VECTORSDB = 'vectorsdb.collections'; +const METRIC_DATABASES_STORAGE_VECTORSDB = 'vectorsdb.databases.storage'; +const METRIC_DATABASE_ID_COLLECTIONS_VECTORSDB = 'vectorsdb.{databaseInternalId}.collections'; +const METRIC_DATABASE_ID_STORAGE_VECTORSDB = 'vectorsdb.{databaseInternalId}.databases.storage'; +const METRIC_DOCUMENTS_VECTORSDB = 'vectorsdb.documents'; +const METRIC_DATABASE_ID_DOCUMENTS_VECTORSDB = 'vectorsdb.{databaseInternalId}.documents'; +const METRIC_DATABASE_ID_COLLECTION_ID_DOCUMENTS_VECTORSDB = 'vectorsdb.{databaseInternalId}.{collectionInternalId}.documents'; +const METRIC_DATABASE_ID_COLLECTION_ID_STORAGE_VECTORSDB = 'vectorsdb.{databaseInternalId}.{collectionInternalId}.databases.storage'; +const METRIC_DATABASES_OPERATIONS_READS_VECTORSDB = 'vectorsdb.databases.operations.reads'; +const METRIC_DATABASE_ID_OPERATIONS_READS_VECTORSDB = 'vectorsdb.{databaseInternalId}.databases.operations.reads'; +const METRIC_DATABASES_OPERATIONS_WRITES_VECTORSDB = 'vectorsdb.databases.operations.writes'; +const METRIC_DATABASE_ID_OPERATIONS_WRITES_VECTORSDB = 'vectorsdb.{databaseInternalId}.databases.operations.writes'; const METRIC_EMBEDDINGS_TEXT = 'embeddings.text'; const METRIC_EMBEDDINGS_MODEL_TEXT = 'embeddings.text.{embeddingModel}'; const METRIC_EMBEDDINGS_TEXT_TOTAL_ERROR = 'embeddings.text.totalErrors'; @@ -439,11 +440,11 @@ const PROJECT_STATUS_ACTIVE = 'active'; const DATABASE_TYPE_LEGACY = 'legacy'; const DATABASE_TYPE_TABLESDB = 'tablesdb'; const DATABASE_TYPE_DOCUMENTSDB = 'documentsdb'; -const DATABASE_TYPE_VECTORDB = 'vectordb'; +const DATABASE_TYPE_VECTORSDB = 'vectorsdb'; // CSV import/export allowed database types const CSV_ALLOWED_DATABASE_TYPES = [ DATABASE_TYPE_LEGACY, DATABASE_TYPE_TABLESDB, - DATABASE_TYPE_VECTORDB + DATABASE_TYPE_VECTORSDB ]; diff --git a/app/init/models.php b/app/init/models.php index 3d755ac58a..095699ac67 100644 --- a/app/init/models.php +++ b/app/init/models.php @@ -149,12 +149,12 @@ use Appwrite\Utopia\Response\Model\UsageSites; use Appwrite\Utopia\Response\Model\UsageStorage; use Appwrite\Utopia\Response\Model\UsageTable; use Appwrite\Utopia\Response\Model\UsageUsers; -use Appwrite\Utopia\Response\Model\UsageVectorDB; -use Appwrite\Utopia\Response\Model\UsageVectorDBs; +use Appwrite\Utopia\Response\Model\UsageVectorsDB; +use Appwrite\Utopia\Response\Model\UsageVectorsDBs; use Appwrite\Utopia\Response\Model\User; use Appwrite\Utopia\Response\Model\Variable; use Appwrite\Utopia\Response\Model\VcsContent; -use Appwrite\Utopia\Response\Model\VectorDBCollection; +use Appwrite\Utopia\Response\Model\VectorsDBCollection; use Appwrite\Utopia\Response\Model\Webhook; // General @@ -219,7 +219,7 @@ Response::setModel(new BaseList('Migrations List', Response::MODEL_MIGRATION_LIS Response::setModel(new BaseList('Migrations Firebase Projects List', Response::MODEL_MIGRATION_FIREBASE_PROJECT_LIST, 'projects', Response::MODEL_MIGRATION_FIREBASE_PROJECT)); Response::setModel(new BaseList('Specifications List', Response::MODEL_SPECIFICATION_LIST, 'specifications', Response::MODEL_SPECIFICATION)); Response::setModel(new BaseList('VCS Content List', Response::MODEL_VCS_CONTENT_LIST, 'contents', Response::MODEL_VCS_CONTENT)); -Response::setModel(new BaseList('VectorDB Collections List', Response::MODEL_VECTORDB_COLLECTION_LIST, 'collections', Response::MODEL_VECTORDB_COLLECTION)); +Response::setModel(new BaseList('VectorsDB Collections List', Response::MODEL_VECTORSDB_COLLECTION_LIST, 'collections', Response::MODEL_VECTORSDB_COLLECTION)); Response::setModel(new BaseList('Embedding list', Response::MODEL_EMBEDDING_LIST, 'embeddings', Response::MODEL_EMBEDDING)); // Entities @@ -252,12 +252,12 @@ Response::setModel(new AttributeLongtext()); Response::setModel(new UsageDocumentsDBs()); Response::setModel(new UsageDocumentsDB()); -// VectorDB API Models -Response::setModel(new VectorDBCollection()); +// VectorsDB API Models +Response::setModel(new VectorsDBCollection()); Response::setModel(new AttributeObject()); Response::setModel(new AttributeVector()); -Response::setModel(new UsageVectorDBs()); -Response::setModel(new UsageVectorDB()); +Response::setModel(new UsageVectorsDBs()); +Response::setModel(new UsageVectorsDB()); // Table API Models Response::setModel(new Table()); diff --git a/app/init/registers.php b/app/init/registers.php index e166c167e7..7135e2c34c 100644 --- a/app/init/registers.php +++ b/app/init/registers.php @@ -176,10 +176,10 @@ $register->set('pools', function () { 'pass' => System::getEnv('_APP_DB_PASS', ''), 'path' => System::getEnv('_APP_DB_SCHEMA', ''), ]); - $fallbackForVectorDB = 'db_main=' . AppwriteURL::unparse([ - 'scheme' => System::getEnv('_APP_DB_ADAPTER_VECTORDB', 'postgresql'), - 'host' => System::getEnv('_APP_DB_HOST_VECTORDB', 'postgresql'), - 'port' => System::getEnv('_APP_DB_PORT_VECTORDB', '5432'), + $fallbackForVectorsDB = 'db_main=' . AppwriteURL::unparse([ + 'scheme' => System::getEnv('_APP_DB_ADAPTER_VECTORSDB', 'postgresql'), + 'host' => System::getEnv('_APP_DB_HOST_VECTORSDB', 'postgresql'), + 'port' => System::getEnv('_APP_DB_PORT_VECTORSDB', '5432'), 'user' => System::getEnv('_APP_DB_USER', ''), 'pass' => System::getEnv('_APP_DB_PASS', ''), 'path' => System::getEnv('_APP_DB_SCHEMA', ''), @@ -204,9 +204,9 @@ $register->set('pools', function () { 'multiple' => true, 'schemes' => ['mongodb'], ], - 'vectordb' => [ + 'vectorsdb' => [ 'type' => 'database', - 'dsns' => System::getEnv('_APP_CONNECTIONS_DATABASE_VECTORDB', $fallbackForVectorDB), + 'dsns' => System::getEnv('_APP_CONNECTIONS_DATABASE_VECTORSDB', $fallbackForVectorsDB), 'multiple' => true, 'schemes' => ['postgresql'], ], diff --git a/app/init/resources.php b/app/init/resources.php index 0fa116d5e7..9e09ef1ed2 100644 --- a/app/init/resources.php +++ b/app/init/resources.php @@ -680,7 +680,7 @@ Http::setResource('dbForProject', function (Group $pools, Database $dbForPlatfor $path = $request->getURI(); $databaseType = match (true) { str_contains($path, '/documentsdb') => DATABASE_TYPE_DOCUMENTSDB, - str_contains($path, '/vectordb') => DATABASE_TYPE_VECTORDB, + str_contains($path, '/vectorsdb') => DATABASE_TYPE_VECTORSDB, default => '', }; diff --git a/app/realtime.php b/app/realtime.php index e0591a2596..0239e70f22 100644 --- a/app/realtime.php +++ b/app/realtime.php @@ -763,7 +763,7 @@ $server->onMessage(function (int $connection, string $message) use ($server, $re $database = getConsoleDB(); $database->setAuthorization($authorization); - if ($projectId !== 'console') { + if (!empty($projectId) && $projectId !== 'console') { $project = $authorization->skip(fn () => $database->getDocument('projects', $projectId)); $database = getProjectDB($project); @@ -795,6 +795,11 @@ $server->onMessage(function (int $connection, string $message) use ($server, $re throw new Exception(Exception::REALTIME_MESSAGE_FORMAT_INVALID, 'Message format is not valid.'); } + // Ping does not require project context; other messages do (e.g. after unsubscribe during auth) + if (empty($projectId) && ($message['type'] ?? '') !== 'ping') { + throw new Exception(Exception::REALTIME_POLICY_VIOLATION, 'Missing project context. Reconnect to the project first.'); + } + switch ($message['type']) { case 'ping': $server->send([$connection], json_encode([ diff --git a/bin/time-travel b/bin/time-travel new file mode 100755 index 0000000000..6aa06601ac --- /dev/null +++ b/bin/time-travel @@ -0,0 +1,3 @@ +#!/bin/sh + +exec php /usr/src/code/app/cli.php time-travel "$@" diff --git a/composer.lock b/composer.lock index fc7f1c3958..73643fda23 100644 --- a/composer.lock +++ b/composer.lock @@ -9138,5 +9138,8 @@ "platform-dev": { "ext-fileinfo": "*" }, + "platform-overrides": { + "php": "8.3" + }, "plugin-api-version": "2.9.0" } diff --git a/docker-compose.yml b/docker-compose.yml index 279642e650..cc5c628ac0 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -153,12 +153,12 @@ services: - _APP_DB_SCHEMA - _APP_DB_USER - _APP_DB_PASS - - _APP_DB_ADAPTER_VECTORDB - - _APP_DB_HOST_VECTORDB - - _APP_DB_PORT_VECTORDB - - _APP_DB_SCHEMA_VECTORDB - - _APP_DB_USER_VECTORDB - - _APP_DB_PASS_VECTORDB + - _APP_DB_ADAPTER_VECTORSDB + - _APP_DB_HOST_VECTORSDB + - _APP_DB_PORT_VECTORSDB + - _APP_DB_SCHEMA_VECTORSDB + - _APP_DB_USER_VECTORSDB + - _APP_DB_PASS_VECTORSDB - _APP_SMTP_HOST - _APP_SMTP_PORT - _APP_SMTP_SECURE @@ -312,12 +312,12 @@ services: - _APP_DB_SCHEMA - _APP_DB_USER - _APP_DB_PASS - - _APP_DB_ADAPTER_VECTORDB - - _APP_DB_HOST_VECTORDB - - _APP_DB_PORT_VECTORDB - - _APP_DB_SCHEMA_VECTORDB - - _APP_DB_USER_VECTORDB - - _APP_DB_PASS_VECTORDB + - _APP_DB_ADAPTER_VECTORSDB + - _APP_DB_HOST_VECTORSDB + - _APP_DB_PORT_VECTORSDB + - _APP_DB_SCHEMA_VECTORSDB + - _APP_DB_USER_VECTORSDB + - _APP_DB_PASS_VECTORSDB - _APP_USAGE_STATS - _APP_LOGGING_CONFIG - _APP_LOGGING_CONFIG_REALTIME @@ -489,12 +489,12 @@ services: - _APP_DB_SCHEMA - _APP_DB_USER - _APP_DB_PASS - - _APP_DB_ADAPTER_VECTORDB - - _APP_DB_HOST_VECTORDB - - _APP_DB_PORT_VECTORDB - - _APP_DB_SCHEMA_VECTORDB - - _APP_DB_USER_VECTORDB - - _APP_DB_PASS_VECTORDB + - _APP_DB_ADAPTER_VECTORSDB + - _APP_DB_HOST_VECTORSDB + - _APP_DB_PORT_VECTORSDB + - _APP_DB_SCHEMA_VECTORSDB + - _APP_DB_USER_VECTORSDB + - _APP_DB_PASS_VECTORSDB - _APP_LOGGING_CONFIG - _APP_WORKERS_NUM - _APP_QUEUE_NAME diff --git a/src/Appwrite/Event/Event.php b/src/Appwrite/Event/Event.php index 3d76d58dd2..bf6339f8a0 100644 --- a/src/Appwrite/Event/Event.php +++ b/src/Appwrite/Event/Event.php @@ -534,7 +534,7 @@ class Event $parsed = self::parseEventPattern($pattern); // to switch the resource types from databases to the required prefix // eg; all databases events get fired with databases. prefix which mainly depicts legacy type - // so a projection from databases to the actual prefix(documentsdb, vectordb,etc) + // so a projection from databases to the actual prefix(documentsdb, vectorsdb,etc) if ((str_contains($pattern, 'databases.') && $database && $database->getAttribute('type') !== 'legacy')) { $parsed = self::getDatabaseTypeEvents($database, $parsed); } @@ -746,8 +746,8 @@ class Event ]; break; case 'documentsdb': - case 'vectordb': - // sending the type itself(eg: documentsdb, vectordb) + case 'vectorsdb': + // sending the type itself(eg: documentsdb, vectorsdb) $eventMap = [ 'databases' => $database->getAttribute('type') ]; diff --git a/src/Appwrite/Messaging/Adapter/Realtime.php b/src/Appwrite/Messaging/Adapter/Realtime.php index 62cd66de6d..7a2b6fe19a 100644 --- a/src/Appwrite/Messaging/Adapter/Realtime.php +++ b/src/Appwrite/Messaging/Adapter/Realtime.php @@ -493,7 +493,7 @@ class Realtime extends MessagingAdapter case 'databases': case 'tablesdb': case 'documentsdb': - case 'vectordb': + case 'vectorsdb': $resource = $parts[4] ?? ''; if (in_array($resource, ['columns', 'attributes', 'indexes'])) { $channels[] = 'console'; @@ -627,7 +627,7 @@ class Realtime extends MessagingAdapter break; case 'documentsdb': - case 'vectordb': + case 'vectorsdb': $channels[] = 'documents'; $channels[] = "{$basePrefix}.{$databaseId}.collections.{$resourceId}.documents"; $channels[] = "{$basePrefix}.{$databaseId}.collections.{$resourceId}.documents.{$payloadId}"; diff --git a/src/Appwrite/Platform/Modules/Databases/Constants.php b/src/Appwrite/Platform/Modules/Databases/Constants.php index 6bfbcae938..edc6b09cf0 100644 --- a/src/Appwrite/Platform/Modules/Databases/Constants.php +++ b/src/Appwrite/Platform/Modules/Databases/Constants.php @@ -26,7 +26,7 @@ const COLLECTIONS = 'collection'; const LEGACY = 'legacy'; const TABLESDB = 'tablesdb'; const DOCUMENTSDB = 'documentsdb'; -const VECTORDB = 'vectordb'; +const VECTORSDB = 'vectorsdb'; const MIN_VECTOR_DIMENSION = 1; const MAX_VECTOR_DIMENSION = 16000; diff --git a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Action.php b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Action.php index 3411e06b27..b2417871ed 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Action.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Action.php @@ -25,8 +25,8 @@ class Action extends AppwriteAction if (\str_contains($path, '/documentsdb')) { $this->context = DATABASE_TYPE_DOCUMENTSDB; } - if (\str_contains($path, '/vectordb')) { - $this->context = DATABASE_TYPE_VECTORDB; + if (\str_contains($path, '/vectorsdb')) { + $this->context = DATABASE_TYPE_VECTORSDB; } return parent::setHttpPath($path); } diff --git a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Action.php b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Action.php index b0574eff8b..2f541936a8 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Action.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Action.php @@ -27,8 +27,8 @@ abstract class Action extends UtopiaAction if (\str_contains($path, '/tablesdb')) { $this->context = TABLES; $this->databaseType = TABLESDB; - } elseif (\str_contains($path, '/vectordb')) { - $this->databaseType = VECTORDB; + } elseif (\str_contains($path, '/vectorsdb')) { + $this->databaseType = VECTORSDB; } return parent::setHttpPath($path); } diff --git a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Action.php b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Action.php index c09fc7f2e8..0bd4a2e080 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Action.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Action.php @@ -30,8 +30,8 @@ abstract class Action extends DatabasesAction $this->context = ROWS; } elseif (str_contains($path, '/documentsdb/')) { $this->databaseType = DATABASE_TYPE_DOCUMENTSDB; - } elseif (str_contains($path, '/vectordb/')) { - $this->databaseType = DATABASE_TYPE_VECTORDB; + } elseif (str_contains($path, '/vectorsdb/')) { + $this->databaseType = DATABASE_TYPE_VECTORSDB; } $contextId = '$' . $this->getCollectionsEventsContext() . 'Id'; diff --git a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Create.php b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Create.php index 592195cccb..3585bc4477 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Create.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Create.php @@ -64,13 +64,13 @@ class Create extends Action $databaseSharedTables = \explode(',', System::getEnv('_APP_DATABASE_DOCUMENTSDB_SHARED_TABLES', '')); $databaseSharedTablesV1 = \explode(',', System::getEnv('_APP_DATABASE_DOCUMENTSDB_SHARED_TABLES_V1', '')); break; - case VECTORDB: - $databases = Config::getParam('pools-vectordb', []); - $databaseKeys = System::getEnv('_APP_DATABASE_VECTORDB_KEYS', ''); - $databaseOverride = System::getEnv('_APP_DATABASE_VECTORDB_OVERRIDE'); - $dbScheme = System::getEnv('_APP_DB_HOST_VECTORDB', 'postgresql'); - $databaseSharedTables = \explode(',', System::getEnv('_APP_DATABASE_VECTORDB_SHARED_TABLES', '')); - $databaseSharedTablesV1 = \explode(',', System::getEnv('_APP_DATABASE_VECTORDB_SHARED_TABLES_V1', '')); + case VECTORSDB: + $databases = Config::getParam('pools-vectorsdb', []); + $databaseKeys = System::getEnv('_APP_DATABASE_VECTORSDB_KEYS', ''); + $databaseOverride = System::getEnv('_APP_DATABASE_VECTORSDB_OVERRIDE'); + $dbScheme = System::getEnv('_APP_DB_HOST_VECTORSDB', 'postgresql'); + $databaseSharedTables = \explode(',', System::getEnv('_APP_DATABASE_VECTORSDB_SHARED_TABLES', '')); + $databaseSharedTablesV1 = \explode(',', System::getEnv('_APP_DATABASE_VECTORSDB_SHARED_TABLES_V1', '')); break; default: // legacy/tablesdb @@ -143,7 +143,7 @@ class Create extends Action protected function getDatabaseCollection() { return match ($this->getDatabaseType()) { - 'vectordb' => (Config::getParam('collections', [])['vectordb'] ?? [])['collections'] ?? [], + 'vectorsdb' => (Config::getParam('collections', [])['vectorsdb'] ?? [])['collections'] ?? [], default => (Config::getParam('collections', [])['databases'] ?? [])['collections'] ?? [], }; } diff --git a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Transactions/Action.php b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Transactions/Action.php index 5863d3f8b9..f3edf010d4 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Transactions/Action.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Transactions/Action.php @@ -45,9 +45,9 @@ abstract class Action extends DatabasesAction $this->context = COLLECTIONS; $this->databaseType = DOCUMENTSDB; break; - case str_contains($path, '/vectordb'): + case str_contains($path, '/vectorsdb'): $this->context = COLLECTIONS; - $this->databaseType = VECTORDB; + $this->databaseType = VECTORSDB; break; } return parent::setHttpPath($path); diff --git a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Transactions/Update.php b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Transactions/Update.php index 72ba56aff8..d2f7124aa1 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Transactions/Update.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Transactions/Update.php @@ -169,7 +169,7 @@ class Update extends Action $databaseDoc = null; switch ($this->getDatabaseType()) { case DATABASE_TYPE_DOCUMENTSDB: - case DATABASE_TYPE_VECTORDB: + case DATABASE_TYPE_VECTORSDB: $databaseDoc = $authorization->skip(fn () => $dbForProject->findOne('databases', [ Query::equal('$sequence', [$firstOperation['databaseInternalId']]) ])); diff --git a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Usage/Get.php b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Usage/Get.php index 16e10f7530..18e6fd7a8b 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Usage/Get.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Usage/Get.php @@ -32,7 +32,7 @@ class Get extends Action { $this->databaseType = match (true) { str_contains($path, '/documentsdb') => DATABASE_TYPE_DOCUMENTSDB, - str_contains($path, '/vectordb') => DATABASE_TYPE_VECTORDB, + str_contains($path, '/vectorsdb') => DATABASE_TYPE_VECTORSDB, default => DATABASE_TYPE_LEGACY, }; diff --git a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Usage/XList.php b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Usage/XList.php index fd4440d7b3..b8cb774a3e 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Usage/XList.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Usage/XList.php @@ -30,7 +30,7 @@ class XList extends Action { $this->databaseType = match (true) { str_contains($path, '/documentsdb') => DATABASE_TYPE_DOCUMENTSDB, - str_contains($path, '/vectordb') => DATABASE_TYPE_VECTORDB, + str_contains($path, '/vectorsdb') => DATABASE_TYPE_VECTORSDB, default => DATABASE_TYPE_LEGACY, }; diff --git a/src/Appwrite/Platform/Modules/Databases/Http/VectorDB/Collections/Create.php b/src/Appwrite/Platform/Modules/Databases/Http/VectorsDB/Collections/Create.php similarity index 96% rename from src/Appwrite/Platform/Modules/Databases/Http/VectorDB/Collections/Create.php rename to src/Appwrite/Platform/Modules/Databases/Http/VectorsDB/Collections/Create.php index bde56aa6fb..b85a8b30b4 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/VectorDB/Collections/Create.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/VectorsDB/Collections/Create.php @@ -1,6 +1,6 @@ setHttpMethod(self::HTTP_REQUEST_METHOD_POST) - ->setHttpPath('/v1/vectordb/:databaseId/collections') + ->setHttpPath('/v1/vectorsdb/:databaseId/collections') ->desc('Create collection') ->groups(['api', 'database']) ->label('event', 'databases.[databaseId].collections.[collectionId].create') @@ -53,10 +53,10 @@ class Create extends CollectionAction ->label('audits.event', 'collection.create') ->label('audits.resource', 'database/{request.databaseId}/collection/{response.$id}') ->label('sdk', new Method( - namespace: 'vectorDB', + namespace: 'vectorsDB', group: 'collections', name: 'createCollection', - description: '/docs/references/vectordb/create-collection.md', + description: '/docs/references/vectorsdb/create-collection.md', auth: [AuthType::ADMIN, AuthType::KEY], responses: [ new SDKResponse( @@ -119,7 +119,7 @@ class Create extends CollectionAction $attributes = []; $indexes = []; - $collections = (Config::getParam('collections', [])['vectordb'] ?? [])['collections'] ?? []; + $collections = (Config::getParam('collections', [])['vectorsdb'] ?? [])['collections'] ?? []; foreach ($collections['defaultAttributes'] as $attribute) { if ($attribute['$id'] === 'embeddings') { $attribute['size'] = $dimension; diff --git a/src/Appwrite/Platform/Modules/Databases/Http/VectorDB/Collections/Delete.php b/src/Appwrite/Platform/Modules/Databases/Http/VectorsDB/Collections/Delete.php similarity index 84% rename from src/Appwrite/Platform/Modules/Databases/Http/VectorDB/Collections/Delete.php rename to src/Appwrite/Platform/Modules/Databases/Http/VectorsDB/Collections/Delete.php index c671bcc27c..f1188868aa 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/VectorDB/Collections/Delete.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/VectorsDB/Collections/Delete.php @@ -1,6 +1,6 @@ setHttpMethod(self::HTTP_REQUEST_METHOD_DELETE) - ->setHttpPath('/v1/vectordb/:databaseId/collections/:collectionId') + ->setHttpPath('/v1/vectorsdb/:databaseId/collections/:collectionId') ->desc('Delete collection') ->groups(['api', 'database', 'schema']) ->label('scope', 'collections.write') @@ -36,10 +36,10 @@ class Delete extends CollectionDelete ->label('audits.event', 'collection.delete') ->label('audits.resource', 'database/{request.databaseId}/collection/{request.collectionId}') ->label('sdk', new Method( - namespace: 'vectorDB', + namespace: 'vectorsDB', group: 'collections', name: 'deleteCollection', - description: '/docs/references/vectordb/delete-collection.md', + description: '/docs/references/vectorsdb/delete-collection.md', auth: [AuthType::ADMIN, AuthType::KEY], responses: [ new SDKResponse( diff --git a/src/Appwrite/Platform/Modules/Databases/Http/VectorDB/Collections/Documents/Bulk/Delete.php b/src/Appwrite/Platform/Modules/Databases/Http/VectorsDB/Collections/Documents/Bulk/Delete.php similarity index 89% rename from src/Appwrite/Platform/Modules/Databases/Http/VectorDB/Collections/Documents/Bulk/Delete.php rename to src/Appwrite/Platform/Modules/Databases/Http/VectorsDB/Collections/Documents/Bulk/Delete.php index d63382b40e..c8726711f2 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/VectorDB/Collections/Documents/Bulk/Delete.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/VectorsDB/Collections/Documents/Bulk/Delete.php @@ -1,6 +1,6 @@ setHttpMethod(self::HTTP_REQUEST_METHOD_DELETE) - ->setHttpPath('/v1/vectordb/:databaseId/collections/:collectionId/documents') + ->setHttpPath('/v1/vectorsdb/:databaseId/collections/:collectionId/documents') ->desc('Delete documents') ->groups(['api', 'database']) ->label('scope', 'documents.write') @@ -40,10 +40,10 @@ class Delete extends DocumentsDelete ->label('abuse-limit', APP_LIMIT_WRITE_RATE_DEFAULT) ->label('abuse-time', APP_LIMIT_WRITE_RATE_PERIOD_DEFAULT) ->label('sdk', new Method( - namespace: 'vectorDB', + namespace: 'vectorsDB', group: $this->getSdkGroup(), name: 'deleteDocuments', - description: '/docs/references/vectordb/delete-documents.md', + description: '/docs/references/vectorsdb/delete-documents.md', auth: [AuthType::ADMIN, AuthType::KEY], responses: [ new SDKResponse( diff --git a/src/Appwrite/Platform/Modules/Databases/Http/VectorDB/Collections/Documents/Bulk/Update.php b/src/Appwrite/Platform/Modules/Databases/Http/VectorsDB/Collections/Documents/Bulk/Update.php similarity index 89% rename from src/Appwrite/Platform/Modules/Databases/Http/VectorDB/Collections/Documents/Bulk/Update.php rename to src/Appwrite/Platform/Modules/Databases/Http/VectorsDB/Collections/Documents/Bulk/Update.php index 65a692d45d..b469316405 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/VectorDB/Collections/Documents/Bulk/Update.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/VectorsDB/Collections/Documents/Bulk/Update.php @@ -1,6 +1,6 @@ setHttpMethod(self::HTTP_REQUEST_METHOD_PATCH) - ->setHttpPath('/v1/vectordb/:databaseId/collections/:collectionId/documents') + ->setHttpPath('/v1/vectorsdb/:databaseId/collections/:collectionId/documents') ->desc('Update documents') ->groups(['api', 'database']) ->label('scope', 'documents.write') @@ -41,10 +41,10 @@ class Update extends DocumentsUpdate ->label('abuse-limit', APP_LIMIT_WRITE_RATE_DEFAULT * 2) ->label('abuse-time', APP_LIMIT_WRITE_RATE_PERIOD_DEFAULT) ->label('sdk', new Method( - namespace: 'vectorDB', + namespace: 'vectorsDB', group: $this->getSdkGroup(), name: 'updateDocuments', - description: '/docs/references/vectordb/update-documents.md', + description: '/docs/references/vectorsdb/update-documents.md', auth: [AuthType::ADMIN, AuthType::KEY], responses: [ new SDKResponse( diff --git a/src/Appwrite/Platform/Modules/Databases/Http/VectorDB/Collections/Documents/Bulk/Upsert.php b/src/Appwrite/Platform/Modules/Databases/Http/VectorsDB/Collections/Documents/Bulk/Upsert.php similarity index 88% rename from src/Appwrite/Platform/Modules/Databases/Http/VectorDB/Collections/Documents/Bulk/Upsert.php rename to src/Appwrite/Platform/Modules/Databases/Http/VectorsDB/Collections/Documents/Bulk/Upsert.php index 7a72b5372f..bb96a9675c 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/VectorDB/Collections/Documents/Bulk/Upsert.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/VectorsDB/Collections/Documents/Bulk/Upsert.php @@ -1,6 +1,6 @@ setHttpMethod(self::HTTP_REQUEST_METHOD_PUT) - ->setHttpPath('/v1/vectordb/:databaseId/collections/:collectionId/documents') + ->setHttpPath('/v1/vectorsdb/:databaseId/collections/:collectionId/documents') ->desc('Upsert documents') ->groups(['api', 'database']) ->label('scope', 'documents.write') @@ -41,10 +41,10 @@ class Upsert extends DocumentsUpsert ->label('abuse-time', APP_LIMIT_WRITE_RATE_PERIOD_DEFAULT) ->label('sdk', [ new Method( - namespace: 'vectorDB', + namespace: 'vectorsDB', group: $this->getSdkGroup(), name: 'upsertDocuments', - description: '/docs/references/vectordb/upsert-documents.md', + description: '/docs/references/vectorsdb/upsert-documents.md', auth: [AuthType::ADMIN, AuthType::KEY], responses: [ new SDKResponse( diff --git a/src/Appwrite/Platform/Modules/Databases/Http/VectorDB/Collections/Documents/Create.php b/src/Appwrite/Platform/Modules/Databases/Http/VectorsDB/Collections/Documents/Create.php similarity index 92% rename from src/Appwrite/Platform/Modules/Databases/Http/VectorDB/Collections/Documents/Create.php rename to src/Appwrite/Platform/Modules/Databases/Http/VectorsDB/Collections/Documents/Create.php index 42571b9f65..79ae43d087 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/VectorDB/Collections/Documents/Create.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/VectorsDB/Collections/Documents/Create.php @@ -1,6 +1,6 @@ setHttpMethod(self::HTTP_REQUEST_METHOD_POST) - ->setHttpPath('/v1/vectordb/:databaseId/collections/:collectionId/documents') + ->setHttpPath('/v1/vectorsdb/:databaseId/collections/:collectionId/documents') ->desc('Create document') ->groups(['api', 'database']) ->label('scope', 'documents.write') @@ -50,11 +50,11 @@ class Create extends DocumentCreate ->label('abuse-time', APP_LIMIT_WRITE_RATE_PERIOD_DEFAULT) ->label('sdk', [ new Method( - namespace: 'vectorDB', + namespace: 'vectorsDB', group: $this->getSdkGroup(), name: 'createDocument', desc: 'Create document', - description: '/docs/references/vectordb/create-document.md', + description: '/docs/references/vectorsdb/create-document.md', auth: [AuthType::ADMIN, AuthType::SESSION, AuthType::KEY, AuthType::JWT], responses: [ new SDKResponse( @@ -72,11 +72,11 @@ class Create extends DocumentCreate ] ), new Method( - namespace: 'vectorDB', + namespace: 'vectorsDB', group: $this->getSdkGroup(), name: 'createDocuments', desc: 'Create documents', - description: '/docs/references/vectordb/create-documents.md', + description: '/docs/references/vectorsdb/create-documents.md', auth: [AuthType::ADMIN, AuthType::KEY], responses: [ new SDKResponse( diff --git a/src/Appwrite/Platform/Modules/Databases/Http/VectorDB/Collections/Documents/Delete.php b/src/Appwrite/Platform/Modules/Databases/Http/VectorsDB/Collections/Documents/Delete.php similarity index 89% rename from src/Appwrite/Platform/Modules/Databases/Http/VectorDB/Collections/Documents/Delete.php rename to src/Appwrite/Platform/Modules/Databases/Http/VectorsDB/Collections/Documents/Delete.php index 0b5d5cac16..d7d7cdee00 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/VectorDB/Collections/Documents/Delete.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/VectorsDB/Collections/Documents/Delete.php @@ -1,6 +1,6 @@ setHttpMethod(self::HTTP_REQUEST_METHOD_DELETE) - ->setHttpPath('/v1/vectordb/:databaseId/collections/:collectionId/documents/:documentId') + ->setHttpPath('/v1/vectorsdb/:databaseId/collections/:collectionId/documents/:documentId') ->desc('Delete document') ->groups(['api', 'database']) ->label('scope', 'documents.write') @@ -45,10 +45,10 @@ class Delete extends DocumentDelete ->label('abuse-limit', APP_LIMIT_WRITE_RATE_DEFAULT) ->label('abuse-time', APP_LIMIT_WRITE_RATE_PERIOD_DEFAULT) ->label('sdk', new Method( - namespace: 'vectorDB', + namespace: 'vectorsDB', group: $this->getSdkGroup(), name: 'deleteDocument', - description: '/docs/references/vectordb/delete-document.md', + description: '/docs/references/vectorsdb/delete-document.md', auth: [AuthType::ADMIN, AuthType::SESSION, AuthType::KEY, AuthType::JWT], responses: [ new SDKResponse( diff --git a/src/Appwrite/Platform/Modules/Databases/Http/VectorDB/Collections/Documents/Get.php b/src/Appwrite/Platform/Modules/Databases/Http/VectorsDB/Collections/Documents/Get.php similarity index 88% rename from src/Appwrite/Platform/Modules/Databases/Http/VectorDB/Collections/Documents/Get.php rename to src/Appwrite/Platform/Modules/Databases/Http/VectorsDB/Collections/Documents/Get.php index bfa122c5fd..9a50d9a1b9 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/VectorDB/Collections/Documents/Get.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/VectorsDB/Collections/Documents/Get.php @@ -1,6 +1,6 @@ setHttpMethod(self::HTTP_REQUEST_METHOD_GET) - ->setHttpPath('/v1/vectordb/:databaseId/collections/:collectionId/documents/:documentId') + ->setHttpPath('/v1/vectorsdb/:databaseId/collections/:collectionId/documents/:documentId') ->desc('Get document') ->groups(['api', 'database']) ->label('scope', 'documents.read') ->label('resourceType', RESOURCE_TYPE_DATABASES) ->label('sdk', new Method( - namespace: 'vectorDB', + namespace: 'vectorsDB', group: $this->getSdkGroup(), name: 'getDocument', - description: '/docs/references/vectordb/get-document.md', + description: '/docs/references/vectorsdb/get-document.md', auth: [AuthType::ADMIN, AuthType::SESSION, AuthType::KEY, AuthType::JWT], responses: [ new SDKResponse( diff --git a/src/Appwrite/Platform/Modules/Databases/Http/VectorDB/Collections/Documents/Logs/XList.php b/src/Appwrite/Platform/Modules/Databases/Http/VectorsDB/Collections/Documents/Logs/XList.php similarity index 85% rename from src/Appwrite/Platform/Modules/Databases/Http/VectorDB/Collections/Documents/Logs/XList.php rename to src/Appwrite/Platform/Modules/Databases/Http/VectorsDB/Collections/Documents/Logs/XList.php index 3808b5a575..dea9d30119 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/VectorDB/Collections/Documents/Logs/XList.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/VectorsDB/Collections/Documents/Logs/XList.php @@ -1,6 +1,6 @@ setHttpMethod(self::HTTP_REQUEST_METHOD_GET) - ->setHttpPath('/v1/vectordb/:databaseId/collections/:collectionId/documents/:documentId/logs') + ->setHttpPath('/v1/vectorsdb/:databaseId/collections/:collectionId/documents/:documentId/logs') ->desc('List document logs') ->groups(['api', 'database']) ->label('scope', 'documents.read') ->label('resourceType', RESOURCE_TYPE_DATABASES) ->label('sdk', new Method( - namespace: 'vectorDB', + namespace: 'vectorsDB', group: 'logs', name: 'listDocumentLogs', - description: '/docs/references/vectordb/get-document-logs.md', + description: '/docs/references/vectorsdb/get-document-logs.md', auth: [AuthType::ADMIN], responses: [ new SDKResponse( diff --git a/src/Appwrite/Platform/Modules/Databases/Http/VectorDB/Collections/Documents/Update.php b/src/Appwrite/Platform/Modules/Databases/Http/VectorsDB/Collections/Documents/Update.php similarity index 90% rename from src/Appwrite/Platform/Modules/Databases/Http/VectorDB/Collections/Documents/Update.php rename to src/Appwrite/Platform/Modules/Databases/Http/VectorsDB/Collections/Documents/Update.php index 51be0ebf1d..c26b2a70b9 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/VectorDB/Collections/Documents/Update.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/VectorsDB/Collections/Documents/Update.php @@ -1,6 +1,6 @@ setHttpMethod(self::HTTP_REQUEST_METHOD_PATCH) - ->setHttpPath('/v1/vectordb/:databaseId/collections/:collectionId/documents/:documentId') + ->setHttpPath('/v1/vectorsdb/:databaseId/collections/:collectionId/documents/:documentId') ->desc('Update document') ->groups(['api', 'database']) ->label('event', 'databases.[databaseId].collections.[collectionId].documents.[documentId].update') @@ -42,10 +42,10 @@ class Update extends DocumentUpdate ->label('abuse-limit', APP_LIMIT_WRITE_RATE_DEFAULT * 2) ->label('abuse-time', APP_LIMIT_WRITE_RATE_PERIOD_DEFAULT) ->label('sdk', new Method( - namespace: 'vectorDB', + namespace: 'vectorsDB', group: $this->getSdkGroup(), name: 'updateDocument', - description: '/docs/references/vectordb/update-document.md', + description: '/docs/references/vectorsdb/update-document.md', auth: [AuthType::ADMIN, AuthType::SESSION, AuthType::KEY, AuthType::JWT], responses: [ new SDKResponse( diff --git a/src/Appwrite/Platform/Modules/Databases/Http/VectorDB/Collections/Documents/Upsert.php b/src/Appwrite/Platform/Modules/Databases/Http/VectorsDB/Collections/Documents/Upsert.php similarity index 90% rename from src/Appwrite/Platform/Modules/Databases/Http/VectorDB/Collections/Documents/Upsert.php rename to src/Appwrite/Platform/Modules/Databases/Http/VectorsDB/Collections/Documents/Upsert.php index 2369761ee2..df4cb0f191 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/VectorDB/Collections/Documents/Upsert.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/VectorsDB/Collections/Documents/Upsert.php @@ -1,6 +1,6 @@ setHttpMethod(self::HTTP_REQUEST_METHOD_PUT) - ->setHttpPath('/v1/vectordb/:databaseId/collections/:collectionId/documents/:documentId') + ->setHttpPath('/v1/vectorsdb/:databaseId/collections/:collectionId/documents/:documentId') ->desc('Upsert a document') ->groups(['api', 'database']) ->label('event', 'databases.[databaseId].collections.[collectionId].documents.[documentId].upsert') @@ -44,10 +44,10 @@ class Upsert extends DocumentUpsert ->label('abuse-time', APP_LIMIT_WRITE_RATE_PERIOD_DEFAULT) ->label('sdk', [ new Method( - namespace: 'vectorDB', + namespace: 'vectorsDB', group: $this->getSdkGroup(), name: 'upsertDocument', - description: '/docs/references/vectordb/upsert-document.md', + description: '/docs/references/vectorsdb/upsert-document.md', auth: [AuthType::ADMIN, AuthType::SESSION, AuthType::KEY, AuthType::JWT], responses: [ new SDKResponse( diff --git a/src/Appwrite/Platform/Modules/Databases/Http/VectorDB/Collections/Documents/XList.php b/src/Appwrite/Platform/Modules/Databases/Http/VectorsDB/Collections/Documents/XList.php similarity index 89% rename from src/Appwrite/Platform/Modules/Databases/Http/VectorDB/Collections/Documents/XList.php rename to src/Appwrite/Platform/Modules/Databases/Http/VectorsDB/Collections/Documents/XList.php index a58df90068..d4a5d06269 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/VectorDB/Collections/Documents/XList.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/VectorsDB/Collections/Documents/XList.php @@ -1,6 +1,6 @@ setHttpMethod(self::HTTP_REQUEST_METHOD_GET) - ->setHttpPath('/v1/vectordb/:databaseId/collections/:collectionId/documents') + ->setHttpPath('/v1/vectorsdb/:databaseId/collections/:collectionId/documents') ->desc('List documents') ->groups(['api', 'database']) ->label('scope', 'documents.read') ->label('resourceType', RESOURCE_TYPE_DATABASES) ->label('sdk', new Method( - namespace: 'vectorDB', + namespace: 'vectorsDB', group: $this->getSdkGroup(), name: 'listDocuments', - description: '/docs/references/vectordb/list-documents.md', + description: '/docs/references/vectorsdb/list-documents.md', auth: [AuthType::ADMIN, AuthType::SESSION, AuthType::KEY, AuthType::JWT], responses: [ new SDKResponse( diff --git a/src/Appwrite/Platform/Modules/Databases/Http/VectorDB/Collections/Get.php b/src/Appwrite/Platform/Modules/Databases/Http/VectorsDB/Collections/Get.php similarity index 80% rename from src/Appwrite/Platform/Modules/Databases/Http/VectorDB/Collections/Get.php rename to src/Appwrite/Platform/Modules/Databases/Http/VectorsDB/Collections/Get.php index 9f29d6b775..9619bb5048 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/VectorDB/Collections/Get.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/VectorsDB/Collections/Get.php @@ -1,6 +1,6 @@ setHttpMethod(self::HTTP_REQUEST_METHOD_GET) - ->setHttpPath('/v1/vectordb/:databaseId/collections/:collectionId') + ->setHttpPath('/v1/vectorsdb/:databaseId/collections/:collectionId') ->desc('Get collection') ->groups(['api', 'database']) ->label('scope', 'collections.read') ->label('resourceType', RESOURCE_TYPE_DATABASES) ->label('sdk', new Method( - namespace: 'vectorDB', + namespace: 'vectorsDB', group: 'collections', name: 'getCollection', - description: '/docs/references/vectordb/get-collection.md', + description: '/docs/references/vectorsdb/get-collection.md', auth: [AuthType::ADMIN, AuthType::KEY], responses: [ new SDKResponse( diff --git a/src/Appwrite/Platform/Modules/Databases/Http/VectorDB/Collections/Indexes/Create.php b/src/Appwrite/Platform/Modules/Databases/Http/VectorsDB/Collections/Indexes/Create.php similarity index 90% rename from src/Appwrite/Platform/Modules/Databases/Http/VectorDB/Collections/Indexes/Create.php rename to src/Appwrite/Platform/Modules/Databases/Http/VectorsDB/Collections/Indexes/Create.php index ed0b465a71..a535dd5724 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/VectorDB/Collections/Indexes/Create.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/VectorsDB/Collections/Indexes/Create.php @@ -1,6 +1,6 @@ setHttpMethod(self::HTTP_REQUEST_METHOD_POST) - ->setHttpPath('/v1/vectordb/:databaseId/collections/:collectionId/indexes') + ->setHttpPath('/v1/vectorsdb/:databaseId/collections/:collectionId/indexes') ->desc('Create index') ->groups(['api', 'database']) ->label('event', 'databases.[databaseId].tables.[tableId].indexes.[indexId].create') @@ -42,10 +42,10 @@ class Create extends IndexCreate ->label('audits.event', 'index.create') ->label('audits.resource', 'database/{request.databaseId}/collection/{request.tableId}') ->label('sdk', new Method( - namespace: 'vectorDB', + namespace: 'vectorsDB', group: $this->getSdkGroup(), name: 'createIndex', - description: '/docs/references/vectordb/create-index.md', + description: '/docs/references/vectorsdb/create-index.md', auth: [AuthType::ADMIN, AuthType::KEY], responses: [ new SDKResponse( diff --git a/src/Appwrite/Platform/Modules/Databases/Http/VectorDB/Collections/Indexes/Delete.php b/src/Appwrite/Platform/Modules/Databases/Http/VectorsDB/Collections/Indexes/Delete.php similarity index 88% rename from src/Appwrite/Platform/Modules/Databases/Http/VectorDB/Collections/Indexes/Delete.php rename to src/Appwrite/Platform/Modules/Databases/Http/VectorsDB/Collections/Indexes/Delete.php index 2145410810..5c7fc47ee0 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/VectorDB/Collections/Indexes/Delete.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/VectorsDB/Collections/Indexes/Delete.php @@ -1,6 +1,6 @@ setHttpMethod(self::HTTP_REQUEST_METHOD_DELETE) - ->setHttpPath('/v1/vectordb/:databaseId/collections/:collectionId/indexes/:key') + ->setHttpPath('/v1/vectorsdb/:databaseId/collections/:collectionId/indexes/:key') ->desc('Delete index') ->groups(['api', 'database']) ->label('scope', 'collections.write') @@ -41,10 +41,10 @@ class Delete extends IndexDelete ->label('audits.event', 'index.delete') ->label('audits.resource', 'database/{request.databaseId}/collection/{request.collectionId}') ->label('sdk', new Method( - namespace: 'vectorDB', + namespace: 'vectorsDB', group: $this->getSdkGroup(), name: 'deleteIndex', // getName needs to be different from parent action to avoid conflict in path name - description: '/docs/references/vectordb/delete-index.md', + description: '/docs/references/vectorsdb/delete-index.md', auth: [AuthType::ADMIN, AuthType::KEY], responses: [ new SDKResponse( diff --git a/src/Appwrite/Platform/Modules/Databases/Http/VectorDB/Collections/Indexes/Get.php b/src/Appwrite/Platform/Modules/Databases/Http/VectorsDB/Collections/Indexes/Get.php similarity index 85% rename from src/Appwrite/Platform/Modules/Databases/Http/VectorDB/Collections/Indexes/Get.php rename to src/Appwrite/Platform/Modules/Databases/Http/VectorsDB/Collections/Indexes/Get.php index 1959b23dfe..4cf646acba 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/VectorDB/Collections/Indexes/Get.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/VectorsDB/Collections/Indexes/Get.php @@ -1,6 +1,6 @@ setHttpMethod(self::HTTP_REQUEST_METHOD_GET) - ->setHttpPath('/v1/vectordb/:databaseId/collections/:collectionId/indexes/:key') + ->setHttpPath('/v1/vectorsdb/:databaseId/collections/:collectionId/indexes/:key') ->desc('Get index') ->groups(['api', 'database']) ->label('scope', 'collections.read') ->label('resourceType', RESOURCE_TYPE_DATABASES) ->label('sdk', new Method( - namespace: 'vectorDB', + namespace: 'vectorsDB', group: $this->getSdkGroup(), name: 'getIndex', // getName needs to be different from parent action to avoid conflict in path name - description: '/docs/references/vectordb/get-index.md', + description: '/docs/references/vectorsdb/get-index.md', auth: [AuthType::ADMIN, AuthType::KEY], responses: [ new SDKResponse( diff --git a/src/Appwrite/Platform/Modules/Databases/Http/VectorDB/Collections/Indexes/XList.php b/src/Appwrite/Platform/Modules/Databases/Http/VectorsDB/Collections/Indexes/XList.php similarity index 88% rename from src/Appwrite/Platform/Modules/Databases/Http/VectorDB/Collections/Indexes/XList.php rename to src/Appwrite/Platform/Modules/Databases/Http/VectorsDB/Collections/Indexes/XList.php index cf2565e217..acc46fb570 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/VectorDB/Collections/Indexes/XList.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/VectorsDB/Collections/Indexes/XList.php @@ -1,6 +1,6 @@ setHttpMethod(self::HTTP_REQUEST_METHOD_GET) - ->setHttpPath('/v1/vectordb/:databaseId/collections/:collectionId/indexes') + ->setHttpPath('/v1/vectorsdb/:databaseId/collections/:collectionId/indexes') ->desc('List indexes') ->groups(['api', 'database']) ->label('scope', 'collections.read') ->label('resourceType', RESOURCE_TYPE_DATABASES) ->label('sdk', new Method( - namespace: 'vectorDB', + namespace: 'vectorsDB', group: $this->getSdkGroup(), name: 'listIndexes', // getName needs to be different from parent action to avoid conflict in path name - description: '/docs/references/vectordb/list-indexes.md', + description: '/docs/references/vectorsdb/list-indexes.md', auth: [AuthType::ADMIN, AuthType::KEY], responses: [ new SDKResponse( diff --git a/src/Appwrite/Platform/Modules/Databases/Http/VectorDB/Collections/Logs/XList.php b/src/Appwrite/Platform/Modules/Databases/Http/VectorsDB/Collections/Logs/XList.php similarity index 85% rename from src/Appwrite/Platform/Modules/Databases/Http/VectorDB/Collections/Logs/XList.php rename to src/Appwrite/Platform/Modules/Databases/Http/VectorsDB/Collections/Logs/XList.php index 483f26cad0..cd0e45eb47 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/VectorDB/Collections/Logs/XList.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/VectorsDB/Collections/Logs/XList.php @@ -1,6 +1,6 @@ setHttpMethod(self::HTTP_REQUEST_METHOD_GET) - ->setHttpPath('/v1/vectordb/:databaseId/collections/:collectionId/logs') + ->setHttpPath('/v1/vectorsdb/:databaseId/collections/:collectionId/logs') ->desc('List collection logs') ->groups(['api', 'database']) ->label('scope', 'collections.read') ->label('resourceType', RESOURCE_TYPE_DATABASES) ->label('sdk', new Method( - namespace: 'vectorDB', + namespace: 'vectorsDB', group: $this->getSdkGroup(), name: 'listCollectionLogs', - description: '/docs/references/vectordb/get-collection-logs.md', + description: '/docs/references/vectorsdb/get-collection-logs.md', auth: [AuthType::ADMIN], responses: [ new SDKResponse( diff --git a/src/Appwrite/Platform/Modules/Databases/Http/VectorDB/Collections/Update.php b/src/Appwrite/Platform/Modules/Databases/Http/VectorsDB/Collections/Update.php similarity index 92% rename from src/Appwrite/Platform/Modules/Databases/Http/VectorDB/Collections/Update.php rename to src/Appwrite/Platform/Modules/Databases/Http/VectorsDB/Collections/Update.php index a3b59cd3a9..2ec5f8991f 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/VectorDB/Collections/Update.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/VectorsDB/Collections/Update.php @@ -1,6 +1,6 @@ setHttpMethod(self::HTTP_REQUEST_METHOD_PUT) - ->setHttpPath('/v1/vectordb/:databaseId/collections/:collectionId') + ->setHttpPath('/v1/vectorsdb/:databaseId/collections/:collectionId') ->desc('Update collection') ->groups(['api', 'database', 'schema']) ->label('scope', 'collections.write') @@ -45,15 +45,15 @@ class Update extends CollectionAction ->label('audits.event', 'collection.update') ->label('audits.resource', 'database/{request.databaseId}/collection/{request.collectionId}') ->label('sdk', new Method( - namespace: 'vectorDB', + namespace: 'vectorsDB', group: 'collections', name: 'updateCollection', - description: '/docs/references/vectordb/update-collection.md', + description: '/docs/references/vectorsdb/update-collection.md', auth: [AuthType::ADMIN, AuthType::KEY], responses: [ new SDKResponse( code: SwooleResponse::STATUS_CODE_OK, - model: UtopiaResponse::MODEL_VECTORDB_COLLECTION, + model: UtopiaResponse::MODEL_VECTORSDB_COLLECTION, ) ], contentType: ContentType::JSON diff --git a/src/Appwrite/Platform/Modules/Databases/Http/VectorDB/Collections/Usage/Get.php b/src/Appwrite/Platform/Modules/Databases/Http/VectorsDB/Collections/Usage/Get.php similarity index 85% rename from src/Appwrite/Platform/Modules/Databases/Http/VectorDB/Collections/Usage/Get.php rename to src/Appwrite/Platform/Modules/Databases/Http/VectorsDB/Collections/Usage/Get.php index 1b6cb27db4..7e0f79a9f1 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/VectorDB/Collections/Usage/Get.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/VectorsDB/Collections/Usage/Get.php @@ -1,6 +1,6 @@ setHttpMethod(self::HTTP_REQUEST_METHOD_GET) - ->setHttpPath('/v1/vectordb/:databaseId/collections/:collectionId/usage') + ->setHttpPath('/v1/vectorsdb/:databaseId/collections/:collectionId/usage') ->desc('Get collection usage stats') ->groups(['api', 'database', 'usage']) ->label('scope', 'collections.read') ->label('resourceType', RESOURCE_TYPE_DATABASES) ->label('sdk', new Method( - namespace: 'vectorDB', + namespace: 'vectorsDB', group: null, name: 'getCollectionUsage', - description: '/docs/references/vectordb/get-collection-usage.md', + description: '/docs/references/vectorsdb/get-collection-usage.md', auth: [AuthType::ADMIN], responses: [ new SDKResponse( diff --git a/src/Appwrite/Platform/Modules/Databases/Http/VectorDB/Collections/XList.php b/src/Appwrite/Platform/Modules/Databases/Http/VectorsDB/Collections/XList.php similarity index 86% rename from src/Appwrite/Platform/Modules/Databases/Http/VectorDB/Collections/XList.php rename to src/Appwrite/Platform/Modules/Databases/Http/VectorsDB/Collections/XList.php index e6c3ecf92b..7ba26b8b6a 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/VectorDB/Collections/XList.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/VectorsDB/Collections/XList.php @@ -1,6 +1,6 @@ setHttpMethod(self::HTTP_REQUEST_METHOD_GET) - ->setHttpPath('/v1/vectordb/:databaseId/collections') + ->setHttpPath('/v1/vectorsdb/:databaseId/collections') ->desc('List collections') ->groups(['api', 'database']) ->label('scope', 'collections.read') ->label('resourceType', RESOURCE_TYPE_DATABASES) ->label('sdk', new Method( - namespace: 'vectorDB', + namespace: 'vectorsDB', group: 'collections', name: 'listCollections', - description: '/docs/references/vectordb/list-collections.md', + description: '/docs/references/vectorsdb/list-collections.md', auth: [AuthType::ADMIN, AuthType::KEY], responses: [ new SDKResponse( diff --git a/src/Appwrite/Platform/Modules/Databases/Http/VectorDB/Create.php b/src/Appwrite/Platform/Modules/Databases/Http/VectorsDB/Create.php similarity index 88% rename from src/Appwrite/Platform/Modules/Databases/Http/VectorDB/Create.php rename to src/Appwrite/Platform/Modules/Databases/Http/VectorsDB/Create.php index 3776cf5222..cc2914fc10 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/VectorDB/Create.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/VectorsDB/Create.php @@ -1,6 +1,6 @@ setHttpMethod(self::HTTP_REQUEST_METHOD_POST) - ->setHttpPath('/v1/vectordb') + ->setHttpPath('/v1/vectorsdb') ->desc('Create database') ->groups(['api', 'database']) ->label('event', 'databases.[databaseId].create') @@ -33,10 +33,10 @@ class Create extends DatabaseCreate ->label('audits.event', 'database.create') ->label('audits.resource', 'database/{response.$id}') ->label('sdk', new Method( - namespace: 'vectorDB', - group: 'vectordb', + namespace: 'vectorsDB', + group: 'vectorsdb', name: 'create', - description: '/docs/references/vectordb/create.md', + description: '/docs/references/vectorsdb/create.md', auth: [AuthType::ADMIN, AuthType::KEY], responses: [ new SDKResponse( diff --git a/src/Appwrite/Platform/Modules/Databases/Http/VectorDB/Delete.php b/src/Appwrite/Platform/Modules/Databases/Http/VectorsDB/Delete.php similarity index 84% rename from src/Appwrite/Platform/Modules/Databases/Http/VectorDB/Delete.php rename to src/Appwrite/Platform/Modules/Databases/Http/VectorsDB/Delete.php index 768e1d78f2..2109e2bd68 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/VectorDB/Delete.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/VectorsDB/Delete.php @@ -1,6 +1,6 @@ setHttpMethod(self::HTTP_REQUEST_METHOD_DELETE) - ->setHttpPath('/v1/vectordb/:databaseId') + ->setHttpPath('/v1/vectorsdb/:databaseId') ->desc('Delete database') ->groups(['api', 'database', 'schema']) ->label('scope', 'databases.write') @@ -31,10 +31,10 @@ class Delete extends DatabaseDelete ->label('audits.event', 'database.delete') ->label('audits.resource', 'database/{request.databaseId}') ->label('sdk', new Method( - namespace: 'vectorDB', - group: 'vectordb', + namespace: 'vectorsDB', + group: 'vectorsdb', name: 'delete', - description: '/docs/references/vectordb/delete.md', + description: '/docs/references/vectorsdb/delete.md', auth: [AuthType::ADMIN, AuthType::KEY], responses: [ new SDKResponse( diff --git a/src/Appwrite/Platform/Modules/Databases/Http/VectorDB/Embeddings/Text/Create.php b/src/Appwrite/Platform/Modules/Databases/Http/VectorsDB/Embeddings/Text/Create.php similarity index 94% rename from src/Appwrite/Platform/Modules/Databases/Http/VectorDB/Embeddings/Text/Create.php rename to src/Appwrite/Platform/Modules/Databases/Http/VectorsDB/Embeddings/Text/Create.php index 2311dda6ce..98602efa3c 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/VectorDB/Embeddings/Text/Create.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/VectorsDB/Embeddings/Text/Create.php @@ -1,6 +1,6 @@ setHttpMethod(self::HTTP_REQUEST_METHOD_POST) - ->setHttpPath('/v1/vectordb/embeddings/text') + ->setHttpPath('/v1/vectorsdb/embeddings/text') ->desc('Create Text Embeddings') ->groups(['api', 'database']) ->label('scope', 'documents.write') ->label('resourceType', RESOURCE_TYPE_EMBEDDINGS_TEXT) ->label('audits.event', 'embedding.create') - ->label('audits.resource', 'vectordb/embeddings/text') + ->label('audits.resource', 'vectorsdb/embeddings/text') ->label('abuse-key', 'ip:{ip},method:{method},url:{url},userId:{userId}') ->label('abuse-limit', APP_LIMIT_WRITE_RATE_DEFAULT * 2) ->label('abuse-time', APP_LIMIT_WRITE_RATE_PERIOD_DEFAULT) ->label('sdk', [ new Method( - namespace: 'vectorDB', + namespace: 'vectorsDB', group: $this->getSdkGroup(), name: 'createTextEmbeddings', desc: 'Create Text Embedding', - description: '/docs/references/vectordb/create-document.md', + description: '/docs/references/vectorsdb/create-document.md', auth: [AuthType::ADMIN, AuthType::KEY, AuthType::JWT], responses: [ new SDKResponse( diff --git a/src/Appwrite/Platform/Modules/Databases/Http/VectorDB/Get.php b/src/Appwrite/Platform/Modules/Databases/Http/VectorsDB/Get.php similarity index 81% rename from src/Appwrite/Platform/Modules/Databases/Http/VectorDB/Get.php rename to src/Appwrite/Platform/Modules/Databases/Http/VectorsDB/Get.php index 8530d89844..a79632b105 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/VectorDB/Get.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/VectorsDB/Get.php @@ -1,6 +1,6 @@ setHttpMethod(self::HTTP_REQUEST_METHOD_GET) - ->setHttpPath('/v1/vectordb/:databaseId') + ->setHttpPath('/v1/vectorsdb/:databaseId') ->desc('Get database') ->groups(['api', 'database']) ->label('scope', 'databases.read') ->label('resourceType', RESOURCE_TYPE_DATABASES) ->label('sdk', new Method( - namespace: 'vectorDB', - group: 'vectordb', + namespace: 'vectorsDB', + group: 'vectorsdb', name: 'get', - description: '/docs/references/vectordb/get.md', + description: '/docs/references/vectorsdb/get.md', auth: [AuthType::ADMIN, AuthType::KEY], responses: [ new SDKResponse( diff --git a/src/Appwrite/Platform/Modules/Databases/Http/VectorDB/Logs/XList.php b/src/Appwrite/Platform/Modules/Databases/Http/VectorsDB/Logs/XList.php similarity index 87% rename from src/Appwrite/Platform/Modules/Databases/Http/VectorDB/Logs/XList.php rename to src/Appwrite/Platform/Modules/Databases/Http/VectorsDB/Logs/XList.php index 3961c5dfbe..d8c1df5f04 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/VectorDB/Logs/XList.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/VectorsDB/Logs/XList.php @@ -1,6 +1,6 @@ setHttpMethod(self::HTTP_REQUEST_METHOD_GET) - ->setHttpPath('/v1/vectordb/:databaseId/logs') + ->setHttpPath('/v1/vectorsdb/:databaseId/logs') ->desc('List database logs') ->groups(['api', 'database']) ->label('scope', 'databases.read') ->label('resourceType', RESOURCE_TYPE_DATABASES) ->label('sdk', [ new Method( - namespace: 'vectorDB', + namespace: 'vectorsDB', group: 'logs', name: 'listDatabaseLogs', - description: '/docs/references/vectordb/get-logs.md', + description: '/docs/references/vectorsdb/get-logs.md', auth: [AuthType::ADMIN], responses: [ new SDKResponse( diff --git a/src/Appwrite/Platform/Modules/Databases/Http/VectorDB/Transactions/Create.php b/src/Appwrite/Platform/Modules/Databases/Http/VectorsDB/Transactions/Create.php similarity index 85% rename from src/Appwrite/Platform/Modules/Databases/Http/VectorDB/Transactions/Create.php rename to src/Appwrite/Platform/Modules/Databases/Http/VectorsDB/Transactions/Create.php index b47dfe4f58..cb67d3f7f1 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/VectorDB/Transactions/Create.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/VectorsDB/Transactions/Create.php @@ -1,6 +1,6 @@ setHttpMethod(self::HTTP_REQUEST_METHOD_POST) - ->setHttpPath('/v1/vectordb/transactions') + ->setHttpPath('/v1/vectorsdb/transactions') ->desc('Create transaction') ->groups(['api', 'database', 'transactions']) ->label('scope', 'documents.write') ->label('resourceType', RESOURCE_TYPE_DATABASES) ->label('sdk', new Method( - namespace: 'vectorDB', + namespace: 'vectorsDB', group: 'transactions', name: 'createTransaction', - description: '/docs/references/vectordb/create-transaction.md', + description: '/docs/references/vectorsdb/create-transaction.md', auth: [AuthType::ADMIN, AuthType::KEY, AuthType::SESSION, AuthType::JWT], responses: [ new SDKResponse( diff --git a/src/Appwrite/Platform/Modules/Databases/Http/VectorDB/Transactions/Delete.php b/src/Appwrite/Platform/Modules/Databases/Http/VectorsDB/Transactions/Delete.php similarity index 84% rename from src/Appwrite/Platform/Modules/Databases/Http/VectorDB/Transactions/Delete.php rename to src/Appwrite/Platform/Modules/Databases/Http/VectorsDB/Transactions/Delete.php index d99b827f2b..0ac2caecba 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/VectorDB/Transactions/Delete.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/VectorsDB/Transactions/Delete.php @@ -1,6 +1,6 @@ setHttpMethod(self::HTTP_REQUEST_METHOD_DELETE) - ->setHttpPath('/v1/vectordb/transactions/:transactionId') + ->setHttpPath('/v1/vectorsdb/transactions/:transactionId') ->desc('Delete transaction') ->groups(['api', 'database', 'transactions']) ->label('scope', 'documents.write') ->label('resourceType', RESOURCE_TYPE_DATABASES) ->label('sdk', new Method( - namespace: 'vectorDB', + namespace: 'vectorsDB', group: 'transactions', name: 'deleteTransaction', - description: '/docs/references/vectordb/delete-transaction.md', + description: '/docs/references/vectorsdb/delete-transaction.md', auth: [AuthType::ADMIN, AuthType::KEY, AuthType::SESSION, AuthType::JWT], responses: [ new SDKResponse( diff --git a/src/Appwrite/Platform/Modules/Databases/Http/VectorDB/Transactions/Get.php b/src/Appwrite/Platform/Modules/Databases/Http/VectorsDB/Transactions/Get.php similarity index 83% rename from src/Appwrite/Platform/Modules/Databases/Http/VectorDB/Transactions/Get.php rename to src/Appwrite/Platform/Modules/Databases/Http/VectorsDB/Transactions/Get.php index 5c755577d8..fa4cc86cdd 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/VectorDB/Transactions/Get.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/VectorsDB/Transactions/Get.php @@ -1,6 +1,6 @@ setHttpMethod(self::HTTP_REQUEST_METHOD_GET) - ->setHttpPath('/v1/vectordb/transactions/:transactionId') + ->setHttpPath('/v1/vectorsdb/transactions/:transactionId') ->desc('Get transaction') ->groups(['api', 'database', 'transactions']) ->label('scope', 'documents.read') ->label('resourceType', RESOURCE_TYPE_DATABASES) ->label('sdk', new Method( - namespace: 'vectorDB', + namespace: 'vectorsDB', group: 'transactions', name: 'getTransaction', - description: '/docs/references/vectordb/get-transaction.md', + description: '/docs/references/vectorsdb/get-transaction.md', auth: [AuthType::ADMIN, AuthType::KEY, AuthType::SESSION, AuthType::JWT], responses: [ new SDKResponse( diff --git a/src/Appwrite/Platform/Modules/Databases/Http/VectorDB/Transactions/Operations/Create.php b/src/Appwrite/Platform/Modules/Databases/Http/VectorsDB/Transactions/Operations/Create.php similarity index 85% rename from src/Appwrite/Platform/Modules/Databases/Http/VectorDB/Transactions/Operations/Create.php rename to src/Appwrite/Platform/Modules/Databases/Http/VectorsDB/Transactions/Operations/Create.php index 12ee7d5695..830c0c3fe1 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/VectorDB/Transactions/Operations/Create.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/VectorsDB/Transactions/Operations/Create.php @@ -1,6 +1,6 @@ setHttpMethod(self::HTTP_REQUEST_METHOD_POST) - ->setHttpPath('/v1/vectordb/transactions/:transactionId/operations') + ->setHttpPath('/v1/vectorsdb/transactions/:transactionId/operations') ->desc('Create operations') ->groups(['api', 'database', 'transactions']) ->label('scope', 'documents.write') ->label('resourceType', RESOURCE_TYPE_DATABASES) ->label('sdk', new Method( - namespace: 'vectorDB', + namespace: 'vectorsDB', group: 'transactions', name: 'createOperations', - description: '/docs/references/vectordb/create-operations.md', + description: '/docs/references/vectorsdb/create-operations.md', auth: [AuthType::ADMIN, AuthType::KEY, AuthType::SESSION, AuthType::JWT], responses: [ new SDKResponse( diff --git a/src/Appwrite/Platform/Modules/Databases/Http/VectorDB/Transactions/Update.php b/src/Appwrite/Platform/Modules/Databases/Http/VectorsDB/Transactions/Update.php similarity index 87% rename from src/Appwrite/Platform/Modules/Databases/Http/VectorDB/Transactions/Update.php rename to src/Appwrite/Platform/Modules/Databases/Http/VectorsDB/Transactions/Update.php index 09429325ee..babfe11a3a 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/VectorDB/Transactions/Update.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/VectorsDB/Transactions/Update.php @@ -1,6 +1,6 @@ setHttpMethod(self::HTTP_REQUEST_METHOD_PATCH) - ->setHttpPath('/v1/vectordb/transactions/:transactionId') + ->setHttpPath('/v1/vectorsdb/transactions/:transactionId') ->desc('Update transaction') ->groups(['api', 'database', 'transactions']) ->label('scope', 'documents.write') ->label('resourceType', RESOURCE_TYPE_DATABASES) ->label('sdk', new Method( - namespace: 'vectorDB', + namespace: 'vectorsDB', group: 'transactions', name: 'updateTransaction', - description: '/docs/references/vectordb/update-transaction.md', + description: '/docs/references/vectorsdb/update-transaction.md', auth: [AuthType::ADMIN, AuthType::KEY, AuthType::SESSION, AuthType::JWT], responses: [ new SDKResponse( diff --git a/src/Appwrite/Platform/Modules/Databases/Http/VectorDB/Transactions/XList.php b/src/Appwrite/Platform/Modules/Databases/Http/VectorsDB/Transactions/XList.php similarity index 85% rename from src/Appwrite/Platform/Modules/Databases/Http/VectorDB/Transactions/XList.php rename to src/Appwrite/Platform/Modules/Databases/Http/VectorsDB/Transactions/XList.php index 72f7158707..fb95667ffb 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/VectorDB/Transactions/XList.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/VectorsDB/Transactions/XList.php @@ -1,6 +1,6 @@ setHttpMethod(self::HTTP_REQUEST_METHOD_GET) - ->setHttpPath('/v1/vectordb/transactions') + ->setHttpPath('/v1/vectorsdb/transactions') ->desc('List transactions') ->groups(['api', 'database', 'transactions']) ->label('scope', 'documents.read') ->label('resourceType', RESOURCE_TYPE_DATABASES) ->label('sdk', new Method( - namespace: 'vectorDB', + namespace: 'vectorsDB', group: 'transactions', name: 'listTransactions', - description: '/docs/references/vectordb/list-transactions.md', + description: '/docs/references/vectorsdb/list-transactions.md', auth: [AuthType::ADMIN, AuthType::KEY, AuthType::SESSION, AuthType::JWT], responses: [ new SDKResponse( diff --git a/src/Appwrite/Platform/Modules/Databases/Http/VectorDB/Update.php b/src/Appwrite/Platform/Modules/Databases/Http/VectorsDB/Update.php similarity index 86% rename from src/Appwrite/Platform/Modules/Databases/Http/VectorDB/Update.php rename to src/Appwrite/Platform/Modules/Databases/Http/VectorsDB/Update.php index b60de00349..0b10d6d98b 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/VectorDB/Update.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/VectorsDB/Update.php @@ -1,6 +1,6 @@ setHttpMethod(self::HTTP_REQUEST_METHOD_PUT) - ->setHttpPath('/v1/vectordb/:databaseId') + ->setHttpPath('/v1/vectorsdb/:databaseId') ->desc('Update database') ->groups(['api', 'database', 'schema']) ->label('scope', 'databases.write') @@ -33,10 +33,10 @@ class Update extends DatabaseUpdate ->label('audits.event', 'database.update') ->label('audits.resource', 'database/{response.$id}') ->label('sdk', new Method( - namespace: 'vectorDB', - group: 'vectordb', + namespace: 'vectorsDB', + group: 'vectorsdb', name: 'update', - description: '/docs/references/vectordb/update.md', + description: '/docs/references/vectorsdb/update.md', auth: [AuthType::ADMIN, AuthType::KEY], responses: [ new SDKResponse( diff --git a/src/Appwrite/Platform/Modules/Databases/Http/VectorDB/Usage/Get.php b/src/Appwrite/Platform/Modules/Databases/Http/VectorsDB/Usage/Get.php similarity index 80% rename from src/Appwrite/Platform/Modules/Databases/Http/VectorDB/Usage/Get.php rename to src/Appwrite/Platform/Modules/Databases/Http/VectorsDB/Usage/Get.php index 7ff4ec4933..051e2e39fa 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/VectorDB/Usage/Get.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/VectorsDB/Usage/Get.php @@ -1,6 +1,6 @@ setHttpMethod(self::HTTP_REQUEST_METHOD_GET) - ->setHttpPath('/v1/vectordb/:databaseId/usage') - ->desc('Get VectorDB usage stats') + ->setHttpPath('/v1/vectorsdb/:databaseId/usage') + ->desc('Get VectorsDB usage stats') ->groups(['api', 'database', 'usage']) ->label('scope', 'collections.read') ->label('resourceType', RESOURCE_TYPE_DATABASES) ->label('sdk', [ new Method( - namespace: 'vectorDB', + namespace: 'vectorsDB', group: null, name: 'getUsage', - description: '/docs/references/vectordb/get-database-usage.md', + description: '/docs/references/vectorsdb/get-database-usage.md', auth: [AuthType::ADMIN], responses: [ new SDKResponse( code: SwooleResponse::STATUS_CODE_OK, - model: UtopiaResponse::MODEL_USAGE_VECTORDB, + model: UtopiaResponse::MODEL_USAGE_VECTORSDB, ) ], contentType: ContentType::JSON, diff --git a/src/Appwrite/Platform/Modules/Databases/Http/VectorDB/Usage/XList.php b/src/Appwrite/Platform/Modules/Databases/Http/VectorsDB/Usage/XList.php similarity index 79% rename from src/Appwrite/Platform/Modules/Databases/Http/VectorDB/Usage/XList.php rename to src/Appwrite/Platform/Modules/Databases/Http/VectorsDB/Usage/XList.php index 97fbb00bd6..d91a5963c4 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/VectorDB/Usage/XList.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/VectorsDB/Usage/XList.php @@ -1,6 +1,6 @@ setHttpMethod(self::HTTP_REQUEST_METHOD_GET) - ->setHttpPath('/v1/vectordb/usage') - ->desc('Get VectorDB usage stats') + ->setHttpPath('/v1/vectorsdb/usage') + ->desc('Get VectorsDB usage stats') ->groups(['api', 'database', 'usage']) ->label('scope', 'collections.read') ->label('resourceType', RESOURCE_TYPE_DATABASES) ->label('sdk', [ new Method( - namespace: 'vectorDB', + namespace: 'vectorsDB', group: null, name: 'listUsage', - description: '/docs/references/vectordb/list-usage.md', + description: '/docs/references/vectorsdb/list-usage.md', auth: [AuthType::ADMIN], responses: [ new SDKResponse( code: SwooleResponse::STATUS_CODE_OK, - model: UtopiaResponse::MODEL_USAGE_VECTORDBS, + model: UtopiaResponse::MODEL_USAGE_VECTORSDBS, ) ], contentType: ContentType::JSON diff --git a/src/Appwrite/Platform/Modules/Databases/Http/VectorDB/XList.php b/src/Appwrite/Platform/Modules/Databases/Http/VectorsDB/XList.php similarity index 87% rename from src/Appwrite/Platform/Modules/Databases/Http/VectorDB/XList.php rename to src/Appwrite/Platform/Modules/Databases/Http/VectorsDB/XList.php index 90b0e170de..e18a89c6a4 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/VectorDB/XList.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/VectorsDB/XList.php @@ -1,6 +1,6 @@ setHttpMethod(self::HTTP_REQUEST_METHOD_GET) - ->setHttpPath('/v1/vectordb') + ->setHttpPath('/v1/vectorsdb') ->desc('List databases') ->groups(['api', 'database']) ->label('scope', 'databases.read') ->label('resourceType', RESOURCE_TYPE_DATABASES) ->label('sdk', new Method( - namespace: 'vectorDB', - group: 'vectordb', + namespace: 'vectorsDB', + group: 'vectorsdb', name: 'list', - description: '/docs/references/vectordb/list.md', + description: '/docs/references/vectorsdb/list.md', auth: [AuthType::ADMIN, AuthType::KEY], responses: [ new SDKResponse( diff --git a/src/Appwrite/Platform/Modules/Databases/Services/Http.php b/src/Appwrite/Platform/Modules/Databases/Services/Http.php index 682472128e..5146382b56 100644 --- a/src/Appwrite/Platform/Modules/Databases/Services/Http.php +++ b/src/Appwrite/Platform/Modules/Databases/Services/Http.php @@ -6,7 +6,7 @@ use Appwrite\Platform\Modules\Databases\Http\Init\Timeout; use Appwrite\Platform\Modules\Databases\Services\Registry\DocumentsDB as DocumentsDBRegistry; use Appwrite\Platform\Modules\Databases\Services\Registry\Legacy as LegacyRegistry; use Appwrite\Platform\Modules\Databases\Services\Registry\TablesDB as TablesDBDBRegistry; -use Appwrite\Platform\Modules\Databases\Services\Registry\VectorDB as VectorDBRegistry; +use Appwrite\Platform\Modules\Databases\Services\Registry\VectorsDB as VectorsDBRegistry; use Utopia\Platform\Service; class Http extends Service @@ -21,7 +21,7 @@ class Http extends Service LegacyRegistry::class, TablesDBDBRegistry::class, DocumentsDBRegistry::class, - VectorDBRegistry::class + VectorsDBRegistry::class ] as $registrar) { new $registrar($this); } diff --git a/src/Appwrite/Platform/Modules/Databases/Services/Registry/VectorDB.php b/src/Appwrite/Platform/Modules/Databases/Services/Registry/VectorsDB.php similarity index 53% rename from src/Appwrite/Platform/Modules/Databases/Services/Registry/VectorDB.php rename to src/Appwrite/Platform/Modules/Databases/Services/Registry/VectorsDB.php index f6fa731558..9496b1781a 100644 --- a/src/Appwrite/Platform/Modules/Databases/Services/Registry/VectorDB.php +++ b/src/Appwrite/Platform/Modules/Databases/Services/Registry/VectorsDB.php @@ -2,43 +2,43 @@ namespace Appwrite\Platform\Modules\Databases\Services\Registry; -use Appwrite\Platform\Modules\Databases\Http\VectorDB\Collections\Create as CreateCollection; -use Appwrite\Platform\Modules\Databases\Http\VectorDB\Collections\Delete as DeleteCollection; -use Appwrite\Platform\Modules\Databases\Http\VectorDB\Collections\Documents\Bulk\Delete as DeleteDocuments; -use Appwrite\Platform\Modules\Databases\Http\VectorDB\Collections\Documents\Bulk\Update as UpdateDocuments; -use Appwrite\Platform\Modules\Databases\Http\VectorDB\Collections\Documents\Bulk\Upsert as UpsertDocuments; -use Appwrite\Platform\Modules\Databases\Http\VectorDB\Collections\Documents\Create as CreateDocument; -use Appwrite\Platform\Modules\Databases\Http\VectorDB\Collections\Documents\Delete as DeleteDocument; -use Appwrite\Platform\Modules\Databases\Http\VectorDB\Collections\Documents\Get as GetDocument; -use Appwrite\Platform\Modules\Databases\Http\VectorDB\Collections\Documents\Update as UpdateDocument; -use Appwrite\Platform\Modules\Databases\Http\VectorDB\Collections\Documents\Upsert as UpsertDocument; -use Appwrite\Platform\Modules\Databases\Http\VectorDB\Collections\Documents\XList as ListDocuments; -use Appwrite\Platform\Modules\Databases\Http\VectorDB\Collections\Get as GetCollection; -use Appwrite\Platform\Modules\Databases\Http\VectorDB\Collections\Indexes\Create as CreateIndex; -use Appwrite\Platform\Modules\Databases\Http\VectorDB\Collections\Indexes\Delete as DeleteIndex; -use Appwrite\Platform\Modules\Databases\Http\VectorDB\Collections\Indexes\Get as GetIndex; -use Appwrite\Platform\Modules\Databases\Http\VectorDB\Collections\Indexes\XList as ListIndexes; -use Appwrite\Platform\Modules\Databases\Http\VectorDB\Collections\Logs\XList as ListCollectionLogs; -use Appwrite\Platform\Modules\Databases\Http\VectorDB\Collections\Update as UpdateCollection; -use Appwrite\Platform\Modules\Databases\Http\VectorDB\Collections\Usage\Get as GetCollectionUsage; -use Appwrite\Platform\Modules\Databases\Http\VectorDB\Collections\XList as ListCollections; -use Appwrite\Platform\Modules\Databases\Http\VectorDB\Create as CreateVectorDatabase; -use Appwrite\Platform\Modules\Databases\Http\VectorDB\Delete as DeleteVectorDatabase; -use Appwrite\Platform\Modules\Databases\Http\VectorDB\Embeddings\Text\Create as CreateTextEmbeddings; -use Appwrite\Platform\Modules\Databases\Http\VectorDB\Get as GetVectorDatabase; -use Appwrite\Platform\Modules\Databases\Http\VectorDB\Transactions\Create as CreateTransaction; -use Appwrite\Platform\Modules\Databases\Http\VectorDB\Transactions\Delete as DeleteTransaction; -use Appwrite\Platform\Modules\Databases\Http\VectorDB\Transactions\Get as GetTransaction; -use Appwrite\Platform\Modules\Databases\Http\VectorDB\Transactions\Operations\Create as CreateOperations; -use Appwrite\Platform\Modules\Databases\Http\VectorDB\Transactions\Update as UpdateTransaction; -use Appwrite\Platform\Modules\Databases\Http\VectorDB\Transactions\XList as ListTransactions; -use Appwrite\Platform\Modules\Databases\Http\VectorDB\Update as UpdateVectorDatabase; -use Appwrite\Platform\Modules\Databases\Http\VectorDB\Usage\Get as GetVectorDatabaseUsage; -use Appwrite\Platform\Modules\Databases\Http\VectorDB\Usage\XList as ListVectorDatabaseUsage; -use Appwrite\Platform\Modules\Databases\Http\VectorDB\XList as ListVectorDatabases; +use Appwrite\Platform\Modules\Databases\Http\VectorsDB\Collections\Create as CreateCollection; +use Appwrite\Platform\Modules\Databases\Http\VectorsDB\Collections\Delete as DeleteCollection; +use Appwrite\Platform\Modules\Databases\Http\VectorsDB\Collections\Documents\Bulk\Delete as DeleteDocuments; +use Appwrite\Platform\Modules\Databases\Http\VectorsDB\Collections\Documents\Bulk\Update as UpdateDocuments; +use Appwrite\Platform\Modules\Databases\Http\VectorsDB\Collections\Documents\Bulk\Upsert as UpsertDocuments; +use Appwrite\Platform\Modules\Databases\Http\VectorsDB\Collections\Documents\Create as CreateDocument; +use Appwrite\Platform\Modules\Databases\Http\VectorsDB\Collections\Documents\Delete as DeleteDocument; +use Appwrite\Platform\Modules\Databases\Http\VectorsDB\Collections\Documents\Get as GetDocument; +use Appwrite\Platform\Modules\Databases\Http\VectorsDB\Collections\Documents\Update as UpdateDocument; +use Appwrite\Platform\Modules\Databases\Http\VectorsDB\Collections\Documents\Upsert as UpsertDocument; +use Appwrite\Platform\Modules\Databases\Http\VectorsDB\Collections\Documents\XList as ListDocuments; +use Appwrite\Platform\Modules\Databases\Http\VectorsDB\Collections\Get as GetCollection; +use Appwrite\Platform\Modules\Databases\Http\VectorsDB\Collections\Indexes\Create as CreateIndex; +use Appwrite\Platform\Modules\Databases\Http\VectorsDB\Collections\Indexes\Delete as DeleteIndex; +use Appwrite\Platform\Modules\Databases\Http\VectorsDB\Collections\Indexes\Get as GetIndex; +use Appwrite\Platform\Modules\Databases\Http\VectorsDB\Collections\Indexes\XList as ListIndexes; +use Appwrite\Platform\Modules\Databases\Http\VectorsDB\Collections\Logs\XList as ListCollectionLogs; +use Appwrite\Platform\Modules\Databases\Http\VectorsDB\Collections\Update as UpdateCollection; +use Appwrite\Platform\Modules\Databases\Http\VectorsDB\Collections\Usage\Get as GetCollectionUsage; +use Appwrite\Platform\Modules\Databases\Http\VectorsDB\Collections\XList as ListCollections; +use Appwrite\Platform\Modules\Databases\Http\VectorsDB\Create as CreateVectorDatabase; +use Appwrite\Platform\Modules\Databases\Http\VectorsDB\Delete as DeleteVectorDatabase; +use Appwrite\Platform\Modules\Databases\Http\VectorsDB\Embeddings\Text\Create as CreateTextEmbeddings; +use Appwrite\Platform\Modules\Databases\Http\VectorsDB\Get as GetVectorDatabase; +use Appwrite\Platform\Modules\Databases\Http\VectorsDB\Transactions\Create as CreateTransaction; +use Appwrite\Platform\Modules\Databases\Http\VectorsDB\Transactions\Delete as DeleteTransaction; +use Appwrite\Platform\Modules\Databases\Http\VectorsDB\Transactions\Get as GetTransaction; +use Appwrite\Platform\Modules\Databases\Http\VectorsDB\Transactions\Operations\Create as CreateOperations; +use Appwrite\Platform\Modules\Databases\Http\VectorsDB\Transactions\Update as UpdateTransaction; +use Appwrite\Platform\Modules\Databases\Http\VectorsDB\Transactions\XList as ListTransactions; +use Appwrite\Platform\Modules\Databases\Http\VectorsDB\Update as UpdateVectorDatabase; +use Appwrite\Platform\Modules\Databases\Http\VectorsDB\Usage\Get as GetVectorDatabaseUsage; +use Appwrite\Platform\Modules\Databases\Http\VectorsDB\Usage\XList as ListVectorDatabaseUsage; +use Appwrite\Platform\Modules\Databases\Http\VectorsDB\XList as ListVectorDatabases; use Utopia\Platform\Service; -class VectorDB extends Base +class VectorsDB extends Base { protected function register(Service $service): void { diff --git a/src/Appwrite/Platform/Modules/Functions/Http/Executions/Create.php b/src/Appwrite/Platform/Modules/Functions/Http/Executions/Create.php index 1a4cc45081..bc506c654a 100644 --- a/src/Appwrite/Platform/Modules/Functions/Http/Executions/Create.php +++ b/src/Appwrite/Platform/Modules/Functions/Http/Executions/Create.php @@ -180,7 +180,8 @@ class Create extends Base $version = $function->getAttribute('version', 'v2'); $runtimes = Config::getParam($version === 'v2' ? 'runtimes-v2' : 'runtimes', []); - $spec = Config::getParam('specifications')[$function->getAttribute('specification', APP_COMPUTE_SPECIFICATION_DEFAULT)]; + + $spec = Config::getParam('specifications')[$function->getAttribute('runtimeSpecification', APP_COMPUTE_SPECIFICATION_DEFAULT)]; $runtime = (isset($runtimes[$function->getAttribute('runtime', '')])) ? $runtimes[$function->getAttribute('runtime', '')] : null; @@ -420,6 +421,11 @@ class Create extends Base try { $version = $function->getAttribute('version', 'v2'); $command = $runtime['startCommand']; + + if (!empty($deployment->getAttribute('startCommand', ''))) { + $command = 'cd /usr/local/server/src/function/ && ' . $deployment->getAttribute('startCommand', ''); + } + $source = $deployment->getAttribute('buildPath', ''); $extension = str_ends_with($source, '.tar') ? 'tar' : 'tar.gz'; $command = $version === 'v2' ? '' : "cp /tmp/code.$extension /mnt/code/code.$extension && nohup helpers/start.sh \"$command\""; diff --git a/src/Appwrite/Platform/Modules/Functions/Http/Functions/Create.php b/src/Appwrite/Platform/Modules/Functions/Http/Functions/Create.php index 8d657c1064..d281c64414 100644 --- a/src/Appwrite/Platform/Modules/Functions/Http/Functions/Create.php +++ b/src/Appwrite/Platform/Modules/Functions/Http/Functions/Create.php @@ -93,16 +93,23 @@ class Create extends Base ->param('providerBranch', '', new Text(128, 0), 'Production branch for the repo linked to the function.', true) ->param('providerSilentMode', false, new Boolean(), 'Is the VCS (Version Control System) connection in silent mode for the repo linked to the function? In silent mode, comments will not be made on commits and pull requests.', true) ->param('providerRootDirectory', '', new Text(128, 0), 'Path to function code in the linked repo.', true) - ->param('specification', fn (array $plan) => $this->getDefaultSpecification($plan), fn (array $plan) => new Specification( + ->param('buildSpecification', fn (array $plan) => $this->getDefaultSpecification($plan), fn (array $plan) => new Specification( $plan, Config::getParam('specifications', []), System::getEnv('_APP_COMPUTE_CPUS', 0), System::getEnv('_APP_COMPUTE_MEMORY', 0) - ), 'Runtime specification for the function and builds.', true, ['plan']) + ), 'Build specification for the function deployments.', true, ['plan']) + ->param('runtimeSpecification', fn (array $plan) => $this->getDefaultSpecification($plan), fn (array $plan) => new Specification( + $plan, + Config::getParam('specifications', []), + System::getEnv('_APP_COMPUTE_CPUS', 0), + System::getEnv('_APP_COMPUTE_MEMORY', 0) + ), 'Runtime specification for the function executions.', true, ['plan']) ->param('templateRepository', '', new Text(128, 0), 'Repository name of the template.', true, deprecated: true) ->param('templateOwner', '', new Text(128, 0), 'The name of the owner of the template.', true, deprecated: true) ->param('templateRootDirectory', '', new Text(128, 0), 'Path to function code in the template repo.', true, deprecated: true) ->param('templateVersion', '', new Text(128, 0), 'Version (tag) for the repo linked to the function template.', true, deprecated: true) + ->param('deploymentRetention', 0, new Range(0, APP_COMPUTE_DEPLOYMENT_MAX_RETENTION), 'Days to keep non-active deployments before deletion. Value 0 means all deployments will be kept.', true) ->inject('response') ->inject('dbForProject') ->inject('timelimit') @@ -138,11 +145,13 @@ class Create extends Base string $providerBranch, bool $providerSilentMode, string $providerRootDirectory, - string $specification, + string $buildSpecification, + string $runtimeSpecification, string $templateRepository, string $templateOwner, string $templateRootDirectory, string $templateVersion, + int $deploymentRetention, Response $response, Database $dbForProject, callable $timelimit, @@ -215,6 +224,7 @@ class Create extends Base 'logging' => $logging, 'name' => $name, 'runtime' => $runtime, + 'deploymentRetention' => $deploymentRetention, 'deploymentInternalId' => '', 'deploymentId' => '', 'events' => $events, @@ -225,7 +235,6 @@ class Create extends Base 'entrypoint' => $entrypoint, 'commands' => $commands, 'scopes' => $scopes, - 'deploymentRetention' => 0, 'startCommand' => '', 'search' => implode(' ', [$functionId, $name, $runtime]), 'version' => 'v5', @@ -237,9 +246,8 @@ class Create extends Base 'providerBranch' => $providerBranch, 'providerRootDirectory' => $providerRootDirectory, 'providerSilentMode' => $providerSilentMode, - 'specification' => $specification, - 'buildSpecification' => $specification, - 'runtimeSpecification' => $specification, + 'buildSpecification' => $buildSpecification, + 'runtimeSpecification' => $runtimeSpecification, ])); } catch (DuplicateException) { throw new Exception(Exception::FUNCTION_ALREADY_EXISTS); diff --git a/src/Appwrite/Platform/Modules/Functions/Http/Functions/Update.php b/src/Appwrite/Platform/Modules/Functions/Http/Functions/Update.php index 63d1a331ac..a627bae9dd 100644 --- a/src/Appwrite/Platform/Modules/Functions/Http/Functions/Update.php +++ b/src/Appwrite/Platform/Modules/Functions/Http/Functions/Update.php @@ -87,12 +87,19 @@ class Update extends Base ->param('providerBranch', '', new Text(128, 0), 'Production branch for the repo linked to the function', true) ->param('providerSilentMode', false, new Boolean(), 'Is the VCS (Version Control System) connection in silent mode for the repo linked to the function? In silent mode, comments will not be made on commits and pull requests.', true) ->param('providerRootDirectory', '', new Text(128, 0), 'Path to function code in the linked repo.', true) - ->param('specification', fn (array $plan) => $this->getDefaultSpecification($plan), fn (array $plan) => new Specification( + ->param('buildSpecification', fn (array $plan) => $this->getDefaultSpecification($plan), fn (array $plan) => new Specification( $plan, Config::getParam('specifications', []), System::getEnv('_APP_COMPUTE_CPUS', 0), System::getEnv('_APP_COMPUTE_MEMORY', 0) - ), 'Runtime specification for the function and builds.', true, ['plan']) + ), 'Build specification for the function deployments.', true, ['plan']) + ->param('runtimeSpecification', fn (array $plan) => $this->getDefaultSpecification($plan), fn (array $plan) => new Specification( + $plan, + Config::getParam('specifications', []), + System::getEnv('_APP_COMPUTE_CPUS', 0), + System::getEnv('_APP_COMPUTE_MEMORY', 0) + ), 'Runtime specification for the function executions.', true, ['plan']) + ->param('deploymentRetention', 0, new Range(0, APP_COMPUTE_DEPLOYMENT_MAX_RETENTION), 'Days to keep non-active deployments before deletion. Value 0 means all deployments will be kept.', true) ->inject('request') ->inject('response') ->inject('dbForProject') @@ -124,7 +131,9 @@ class Update extends Base string $providerBranch, bool $providerSilentMode, string $providerRootDirectory, - string $specification, + string $buildSpecification, + string $runtimeSpecification, + int $deploymentRetention, Request $request, Response $response, Database $dbForProject, @@ -209,7 +218,7 @@ class Update extends Base 'resourceId' => $function->getId(), 'resourceInternalId' => $function->getSequence(), 'resourceType' => 'function', - 'providerPullRequestIds' => [] + 'providerPullRequestIds' => [], ])); $repositoryId = $repository->getId(); @@ -229,13 +238,22 @@ class Update extends Base } // Enforce Cold Start if spec limits change. - if ($function->getAttribute('specification') !== $specification && !empty($function->getAttribute('deploymentId'))) { - try { - $executor->deleteRuntime($project->getId(), $function->getAttribute('deploymentId')); - } catch (\Throwable $th) { - // Don't throw if the deployment doesn't exist - if ($th->getCode() !== 404) { - throw $th; + if (!empty($function->getAttribute('deploymentId'))) { + $specsChanged = false; + if ($function->getAttribute('runtimeSpecification', '') !== $runtimeSpecification) { + $specsChanged = true; + } elseif ($function->getAttribute('buildSpecification', '') !== $buildSpecification) { + $specsChanged = true; + } + + if ($specsChanged) { + try { + $executor->deleteRuntime($project->getId(), $function->getAttribute('deploymentId')); + } catch (\Throwable $th) { + // Don't throw if the deployment doesn't exist + if ($th->getCode() !== 404) { + throw $th; + } } } } @@ -253,8 +271,7 @@ class Update extends Base 'entrypoint' => $entrypoint, 'commands' => $commands, 'scopes' => $scopes, - 'deploymentRetention' => 0, - 'startCommand' => '', + 'deploymentRetention' => $deploymentRetention, 'installationId' => $installation->getId(), 'installationInternalId' => $installation->getSequence(), 'providerRepositoryId' => $providerRepositoryId, @@ -263,9 +280,8 @@ class Update extends Base 'providerBranch' => $providerBranch, 'providerRootDirectory' => $providerRootDirectory, 'providerSilentMode' => $providerSilentMode, - 'specification' => $specification, - 'buildSpecification' => $specification, - 'runtimeSpecification' => $specification, + 'buildSpecification' => $buildSpecification, + 'runtimeSpecification' => $runtimeSpecification, 'search' => implode(' ', [$functionId, $name, $runtime]), ]))); diff --git a/src/Appwrite/Platform/Modules/Functions/Workers/Builds.php b/src/Appwrite/Platform/Modules/Functions/Workers/Builds.php index 7f55d223f6..c080f5d3dd 100644 --- a/src/Appwrite/Platform/Modules/Functions/Workers/Builds.php +++ b/src/Appwrite/Platform/Modules/Functions/Workers/Builds.php @@ -255,7 +255,7 @@ class Builds extends Action $version = $this->getVersion($resource); $runtime = $this->getRuntime($resource, $version); - $spec = Config::getParam('specifications')[$resource->getAttribute('specification', APP_COMPUTE_SPECIFICATION_DEFAULT)]; + $spec = Config::getParam('specifications')[$resource->getAttribute('buildSpecification', APP_COMPUTE_SPECIFICATION_DEFAULT)]; if ($resource->getCollection() === 'functions' && \is_null($runtime)) { throw new \Exception('Runtime "' . $resource->getAttribute('runtime', '') . '" is not supported'); @@ -1229,7 +1229,7 @@ class Builds extends Action protected function sendUsage(Document $resource, Document $deployment, Document $project, StatsUsage $queue): void { - $spec = Config::getParam('specifications')[$resource->getAttribute('specification', APP_COMPUTE_SPECIFICATION_DEFAULT)]; + $spec = Config::getParam('specifications')[$resource->getAttribute('buildSpecification', APP_COMPUTE_SPECIFICATION_DEFAULT)]; switch ($deployment->getAttribute('status')) { case 'ready': diff --git a/src/Appwrite/Platform/Modules/Health/Http/Health/Storage/Get.php b/src/Appwrite/Platform/Modules/Health/Http/Health/Storage/Get.php index 52468cab5a..93c9483959 100644 --- a/src/Appwrite/Platform/Modules/Health/Http/Health/Storage/Get.php +++ b/src/Appwrite/Platform/Modules/Health/Http/Health/Storage/Get.php @@ -2,7 +2,6 @@ namespace Appwrite\Platform\Modules\Health\Http\Health\Storage; -use Appwrite\Extend\Exception; use Appwrite\SDK\AuthType; use Appwrite\SDK\ContentType; use Appwrite\SDK\Method; @@ -58,33 +57,21 @@ class Get extends Action $checkStart = \microtime(true); foreach ($devices as $device) { - $uniqueFileName = \uniqid('health', true); - $filePath = $device->getPath($uniqueFileName); + $path = $device->getPath(\uniqid('health', true)); - if (!$device->write($filePath, 'test', 'text/plain')) { - throw new Exception(Exception::GENERAL_SERVER_ERROR, 'Failed writing test file to ' . $device->getRoot()); - } - - $readError = null; try { - if ($device->read($filePath) !== 'test') { - $readError = new Exception(Exception::GENERAL_SERVER_ERROR, 'Failed reading test file from ' . $device->getRoot()); + if (!$device->write($path, 'test', 'text/plain')) { + throw new \Exception("Failed writing test file to {$device->getRoot()}"); + } + + $content = $device->read($path); + if ($content !== 'test') { + throw new \Exception("Failed reading test file from {$device->getRoot()}: content mismatch"); } - } catch (\Throwable $e) { - $readError = $e; } finally { - // Always attempt to clean up test file - if (!$device->delete($filePath)) { - if ($readError !== null) { - // If read already failed, wrap delete error but preserve original - \error_log('Failed deleting test file from ' . $device->getRoot() . ' during read error recovery'); - } else { - throw new Exception(Exception::GENERAL_SERVER_ERROR, 'Failed deleting test file from ' . $device->getRoot()); - } - } - // Re-throw read error if it occurred - if ($readError !== null) { - throw $readError; + try { + $device->delete($path); + } catch (\Throwable) { } } } diff --git a/src/Appwrite/Platform/Modules/Sites/Http/Sites/Create.php b/src/Appwrite/Platform/Modules/Sites/Http/Sites/Create.php index b6896ff505..d01d0d8ca7 100644 --- a/src/Appwrite/Platform/Modules/Sites/Http/Sites/Create.php +++ b/src/Appwrite/Platform/Modules/Sites/Http/Sites/Create.php @@ -68,6 +68,7 @@ class Create extends Base ->param('timeout', 30, new Range(1, (int) System::getEnv('_APP_SITES_TIMEOUT', 30)), 'Maximum request time in seconds.', true) ->param('installCommand', '', new Text(8192, 0), 'Install Command.', true) ->param('buildCommand', '', new Text(8192, 0), 'Build Command.', true) + ->param('startCommand', '', new Text(8192, 0), 'Custom start command. Leave empty to use default.', true) ->param('outputDirectory', '', new Text(8192, 0), 'Output Directory for site.', true) ->param('buildRuntime', '', new WhiteList(array_keys(Config::getParam('runtimes')), true), 'Runtime to use during build step.') ->param('adapter', '', new WhiteList(['static', 'ssr']), 'Framework adapter defining rendering strategy. Allowed values are: static, ssr', true) @@ -77,12 +78,19 @@ class Create extends Base ->param('providerBranch', '', new Text(128, 0), 'Production branch for the repo linked to the site.', true) ->param('providerSilentMode', false, new Boolean(), 'Is the VCS (Version Control System) connection in silent mode for the repo linked to the site? In silent mode, comments will not be made on commits and pull requests.', true) ->param('providerRootDirectory', '', new Text(128, 0), 'Path to site code in the linked repo.', true) - ->param('specification', fn (array $plan) => $this->getDefaultSpecification($plan), fn (array $plan) => new Specification( + ->param('buildSpecification', fn (array $plan) => $this->getDefaultSpecification($plan), fn (array $plan) => new Specification( $plan, Config::getParam('specifications', []), System::getEnv('_APP_COMPUTE_CPUS', 0), System::getEnv('_APP_COMPUTE_MEMORY', 0) - ), 'Framework specification for the site and builds.', true, ['plan']) + ), 'Build specification for the site deployments.', true, ['plan']) + ->param('runtimeSpecification', fn (array $plan) => $this->getDefaultSpecification($plan), fn (array $plan) => new Specification( + $plan, + Config::getParam('specifications', []), + System::getEnv('_APP_COMPUTE_CPUS', 0), + System::getEnv('_APP_COMPUTE_MEMORY', 0) + ), 'Runtime specification for the SSR executions.', true, ['plan']) + ->param('deploymentRetention', 0, new Range(0, APP_COMPUTE_DEPLOYMENT_MAX_RETENTION), 'Days to keep non-active deployments before deletion. Value 0 means all deployments will be kept.', true) ->inject('response') ->inject('dbForProject') ->inject('project') @@ -100,6 +108,7 @@ class Create extends Base int $timeout, string $installCommand, string $buildCommand, + string $startCommand, string $outputDirectory, string $buildRuntime, string $adapter, @@ -109,7 +118,9 @@ class Create extends Base string $providerBranch, bool $providerSilentMode, string $providerRootDirectory, - string $specification, + string $buildSpecification, + string $runtimeSpecification, + int $deploymentRetention, Response $response, Database $dbForProject, Document $project, @@ -144,13 +155,13 @@ class Create extends Base 'logging' => $logging, 'name' => $name, 'framework' => $framework, + 'deploymentRetention' => $deploymentRetention, 'deploymentInternalId' => '', 'deploymentId' => '', 'timeout' => $timeout, 'installCommand' => $installCommand, 'buildCommand' => $buildCommand, - 'deploymentRetention' => 0, - 'startCommand' => '', + 'startCommand' => $startCommand, 'outputDirectory' => $outputDirectory, 'search' => implode(' ', [$siteId, $name, $framework]), 'fallbackFile' => $fallbackFile, @@ -162,9 +173,8 @@ class Create extends Base 'providerBranch' => $providerBranch, 'providerRootDirectory' => $providerRootDirectory, 'providerSilentMode' => $providerSilentMode, - 'specification' => $specification, - 'buildSpecification' => $specification, - 'runtimeSpecification' => $specification, + 'buildSpecification' => $buildSpecification, + 'runtimeSpecification' => $runtimeSpecification, 'buildRuntime' => $buildRuntime, 'adapter' => $adapter, ]); diff --git a/src/Appwrite/Platform/Modules/Sites/Http/Sites/Update.php b/src/Appwrite/Platform/Modules/Sites/Http/Sites/Update.php index 895e7ae3ef..6510e505ae 100644 --- a/src/Appwrite/Platform/Modules/Sites/Http/Sites/Update.php +++ b/src/Appwrite/Platform/Modules/Sites/Http/Sites/Update.php @@ -71,6 +71,7 @@ class Update extends Base ->param('timeout', 30, new Range(1, (int) System::getEnv('_APP_SITES_TIMEOUT', 30)), 'Maximum request time in seconds.', true) ->param('installCommand', '', new Text(8192, 0), 'Install Command.', true) ->param('buildCommand', '', new Text(8192, 0), 'Build Command.', true) + ->param('startCommand', '', new Text(8192, 0), 'Custom start command. Leave empty to use default.', true) ->param('outputDirectory', '', new Text(8192, 0), 'Output Directory for site.', true) ->param('buildRuntime', '', new WhiteList(array_keys(Config::getParam('runtimes')), true), 'Runtime to use during build step.', true) ->param('adapter', '', new WhiteList(['static', 'ssr']), 'Framework adapter defining rendering strategy. Allowed values are: static, ssr', true) @@ -80,12 +81,19 @@ class Update extends Base ->param('providerBranch', '', new Text(128, 0), 'Production branch for the repo linked to the site.', true) ->param('providerSilentMode', false, new Boolean(), 'Is the VCS (Version Control System) connection in silent mode for the repo linked to the site? In silent mode, comments will not be made on commits and pull requests.', true) ->param('providerRootDirectory', '', new Text(128, 0), 'Path to site code in the linked repo.', true) - ->param('specification', fn (array $plan) => $this->getDefaultSpecification($plan), fn (array $plan) => new Specification( + ->param('buildSpecification', fn (array $plan) => $this->getDefaultSpecification($plan), fn (array $plan) => new Specification( $plan, Config::getParam('specifications', []), System::getEnv('_APP_COMPUTE_CPUS', 0), System::getEnv('_APP_COMPUTE_MEMORY', 0) - ), 'Framework specification for the site and builds.', true, ['plan']) + ), 'Build specification for the site deployments.', true, ['plan']) + ->param('runtimeSpecification', fn (array $plan) => $this->getDefaultSpecification($plan), fn (array $plan) => new Specification( + $plan, + Config::getParam('specifications', []), + System::getEnv('_APP_COMPUTE_CPUS', 0), + System::getEnv('_APP_COMPUTE_MEMORY', 0) + ), 'Runtime specification for the SSR executions.', true, ['plan']) + ->param('deploymentRetention', 0, new Range(0, APP_COMPUTE_DEPLOYMENT_MAX_RETENTION), 'Days to keep non-active deployments before deletion. Value 0 means all deployments will be kept.', true) ->inject('request') ->inject('response') ->inject('dbForProject') @@ -107,6 +115,7 @@ class Update extends Base int $timeout, string $installCommand, string $buildCommand, + string $startCommand, string $outputDirectory, string $buildRuntime, string $adapter, @@ -116,7 +125,9 @@ class Update extends Base string $providerBranch, bool $providerSilentMode, string $providerRootDirectory, - string $specification, + string $buildSpecification, + string $runtimeSpecification, + int $deploymentRetention, Request $request, Response $response, Database $dbForProject, @@ -216,6 +227,7 @@ class Update extends Base $site->getAttribute('name') !== $name || $site->getAttribute('buildCommand') !== $buildCommand || $site->getAttribute('installCommand') !== $installCommand || + $site->getAttribute('startCommand') !== $startCommand || $site->getAttribute('outputDirectory') !== $outputDirectory || $site->getAttribute('providerRootDirectory') !== $providerRootDirectory || $site->getAttribute('framework') !== $framework @@ -223,14 +235,22 @@ class Update extends Base $live = false; } - // Enforce Cold Start if spec limits change. - if ($site->getAttribute('specification') !== $specification && !empty($site->getAttribute('deploymentId'))) { - try { - $executor->deleteRuntime($project->getId(), $site->getAttribute('deploymentId')); - } catch (\Throwable $th) { - // Don't throw if the deployment doesn't exist - if ($th->getCode() !== 404) { - throw $th; + if (!empty($site->getAttribute('deploymentId'))) { + $specsChanged = false; + if ($site->getAttribute('runtimeSpecification', '') !== $runtimeSpecification) { + $specsChanged = true; + } elseif ($site->getAttribute('buildSpecification', '') !== $buildSpecification) { + $specsChanged = true; + } + + if ($specsChanged) { + try { + $executor->deleteRuntime($project->getId(), $site->getAttribute('deploymentId')); + } catch (\Throwable $th) { + // Don't throw if the deployment doesn't exist + if ($th->getCode() !== 404) { + throw $th; + } } } } @@ -242,10 +262,10 @@ class Update extends Base 'logging' => $logging, 'live' => $live, 'timeout' => $timeout, + 'deploymentRetention' => $deploymentRetention, 'installCommand' => $installCommand, 'buildCommand' => $buildCommand, - 'deploymentRetention' => 0, - 'startCommand' => '', + 'startCommand' => $startCommand, 'outputDirectory' => $outputDirectory, 'installationId' => $installation->getId(), 'installationInternalId' => $installation->getSequence(), @@ -255,9 +275,8 @@ class Update extends Base 'providerBranch' => $providerBranch, 'providerRootDirectory' => $providerRootDirectory, 'providerSilentMode' => $providerSilentMode, - 'specification' => $specification, - 'buildSpecification' => $specification, - 'runtimeSpecification' => $specification, + 'buildSpecification' => $buildSpecification, + 'runtimeSpecification' => $runtimeSpecification, 'search' => implode(' ', [$siteId, $name, $framework]), 'buildRuntime' => $buildRuntime, 'adapter' => $adapter, diff --git a/src/Appwrite/Platform/Services/Tasks.php b/src/Appwrite/Platform/Services/Tasks.php index 941530d7ed..023cade694 100644 --- a/src/Appwrite/Platform/Services/Tasks.php +++ b/src/Appwrite/Platform/Services/Tasks.php @@ -16,6 +16,7 @@ use Appwrite\Platform\Tasks\SDKs; use Appwrite\Platform\Tasks\Specs; use Appwrite\Platform\Tasks\SSL; use Appwrite\Platform\Tasks\StatsResources; +use Appwrite\Platform\Tasks\TimeTravel; use Appwrite\Platform\Tasks\Upgrade; use Appwrite\Platform\Tasks\Vars; use Appwrite\Platform\Tasks\Version; @@ -44,6 +45,7 @@ class Tasks extends Service ->addAction(Vars::getName(), new Vars()) ->addAction(Version::getName(), new Version()) ->addAction(StatsResources::getName(), new StatsResources()) + ->addAction(TimeTravel::getName(), new TimeTravel()) ; } } diff --git a/src/Appwrite/Platform/Tasks/Maintenance.php b/src/Appwrite/Platform/Tasks/Maintenance.php index 2dace58d1d..c821435786 100644 --- a/src/Appwrite/Platform/Tasks/Maintenance.php +++ b/src/Appwrite/Platform/Tasks/Maintenance.php @@ -13,6 +13,7 @@ use Utopia\Database\Document; use Utopia\Database\Query; use Utopia\Platform\Action; use Utopia\System\System; +use Utopia\Validator\WhiteList; class Maintenance extends Action { @@ -25,6 +26,7 @@ class Maintenance extends Action { $this ->desc('Schedules maintenance tasks and publishes them to our queues') + ->param('type', 'loop', new WhiteList(['loop', 'trigger']), 'How to run task. "loop" is meant for container entrypoint, and "trigger" for manual execution.') ->inject('dbForPlatform') ->inject('console') ->inject('queueForCertificates') @@ -32,7 +34,7 @@ class Maintenance extends Action ->callback($this->action(...)); } - public function action(Database $dbForPlatform, Document $console, Certificate $queueForCertificates, Delete $queueForDeletes): void + public function action(string $type, Database $dbForPlatform, Document $console, Certificate $queueForCertificates, Delete $queueForDeletes): void { Console::title('Maintenance V1'); Console::success(APP_NAME . ' maintenance process v1 has started'); @@ -57,9 +59,7 @@ class Maintenance extends Action $delay = $next->getTimestamp() - $now->getTimestamp(); } - Console::info('Setting loop start time to ' . $next->format("Y-m-d H:i:s.v") . '. Delaying for ' . $delay . ' seconds.'); - - Console::loop(function () use ($interval, $cacheRetention, $schedulesDeletionRetention, $usageStatsRetentionHourly, $dbForPlatform, $console, $queueForDeletes, $queueForCertificates) { + $action = function () use ($interval, $cacheRetention, $schedulesDeletionRetention, $usageStatsRetentionHourly, $dbForPlatform, $console, $queueForDeletes, $queueForCertificates) { $time = DatabaseDateTime::now(); Console::info("[{$time}] Notifying workers with maintenance tasks every {$interval} seconds"); @@ -96,7 +96,17 @@ class Maintenance extends Action $this->notifyDeleteCache($cacheRetention, $queueForDeletes); $this->notifyDeleteSchedules($schedulesDeletionRetention, $queueForDeletes); $this->notifyDeleteCSVExports($queueForDeletes); - }, $interval, $delay); + }; + + if ($type === 'loop') { + Console::info('Setting loop start time to ' . $next->format("Y-m-d H:i:s.v") . '. Delaying for ' . $delay . ' seconds.'); + + Console::loop(function () use ($action) { + $action(); + }, $interval, $delay); + } elseif ($type === 'trigger') { + $action(); + } } private function notifyDeleteConnections(Delete $queueForDeletes): void diff --git a/src/Appwrite/Platform/Tasks/TimeTravel.php b/src/Appwrite/Platform/Tasks/TimeTravel.php new file mode 100644 index 0000000000..323db56806 --- /dev/null +++ b/src/Appwrite/Platform/Tasks/TimeTravel.php @@ -0,0 +1,72 @@ +desc('Create a time-travel to change $createdAt') + ->param('projectId', '', new UID(), 'Project ID.') + ->param('resourceType', '', new WhiteList(['deployment']), 'Type of resource.') + ->param('resourceId', '', new UID(), 'ID of resource.') + ->param('createdAt', '', new DatetimeValidator(), 'New value for $createdAt') + ->inject('getProjectDB') + ->inject('dbForPlatform') + ->callback($this->action(...)); + } + + public function action(string $projectId, string $resourceType, string $resourceId, string $createdAt, callable $getProjectDB, Database $dbForPlatform): void + { + $isDevelopment = System::getEnv('_APP_ENV', 'development') === 'development'; + + if (!$isDevelopment) { + Console::error('This task is only available in development mode.'); + return; + } + + $project = $dbForPlatform->getDocument('projects', $projectId); + + if ($project->isEmpty()) { + Console::error('Project not found.'); + return; + } + + $collection = match ($resourceType) { + 'deployment' => 'deployments', + default => throw new \Exception('Resource type not implemented') + }; + + /** @var Database $dbForProject */ + $dbForProject = $getProjectDB($project); + + $resource = $dbForProject->getDocument($collection, $resourceId); + if ($resource->isEmpty()) { + Console::error('Resource not found.'); + return; + } + + $update = new Document([ + '$createdAt' => $createdAt, + ]); + + $dbForProject->withPreserveDates(fn () => $dbForProject->updateDocument($collection, $resourceId, $update)); + + Console::success('Time-travel successful. Updated $createdAt for ' . $resourceType . ' ' . $resourceId . ' to ' . $createdAt); + } +} diff --git a/src/Appwrite/Platform/Workers/Deletes.php b/src/Appwrite/Platform/Workers/Deletes.php index 7770e5bc90..500d42f037 100644 --- a/src/Appwrite/Platform/Workers/Deletes.php +++ b/src/Appwrite/Platform/Workers/Deletes.php @@ -5,6 +5,7 @@ namespace Appwrite\Platform\Workers; use Appwrite\Certificates\Adapter as CertificatesAdapter; use Appwrite\Deletes\Identities; use Appwrite\Deletes\Targets; +use Appwrite\Event\Delete as DeleteEvent; use Appwrite\Extend\Exception; use Executor\Executor; use Throwable; @@ -66,6 +67,7 @@ class Deletes extends Action ->inject('executionsRetentionCount') ->inject('auditRetention') ->inject('log') + ->inject('queueForDeletes') ->inject('getAudit') ->callback($this->action(...)); } @@ -92,6 +94,7 @@ class Deletes extends Action int $executionsRetentionCount, string $auditRetention, Log $log, + DeleteEvent $queueForDeletes, callable $getAudit, ): void { $payload = $message->getPayload() ?? []; @@ -212,6 +215,7 @@ class Deletes extends Action $this->deleteUsageStats($project, $getProjectDB, $getLogsDB, $hourlyUsageRetentionDatetime); $this->deleteExpiredSessions($project, $getProjectDB); $this->deleteExpiredTransactions($project, $getProjectDB); + $this->deleteOldDeployments($queueForDeletes, $project, $getProjectDB); break; default: throw new \Exception('No delete operation for type: ' . \strval($type)); @@ -373,6 +377,61 @@ class Deletes extends Action Targets::delete($getProjectDB($project), Query::equal('sessionInternalId', [$session->getSequence()])); } + private function deleteOldDeployments(DeleteEvent $queueForDeletes, Document $project, callable $getProjectDB): void + { + /** @var Database $dbForProject */ + $dbForProject = $getProjectDB($project); + + $removalCallback = function (Document $resource) use ($dbForProject, $queueForDeletes, $project) { + $retention = $resource->getAttribute('deploymentRetention', 0); + + // 0 means unlimited - never delete + if ($retention === 0) { + return; + } + + $activeDeploymentId = $resource->getAttribute('deploymentId', ''); + + $queries = [ + Query::createdBefore(DateTime::addSeconds(new \DateTime(), -1 * $retention * 24 * 60 * 60)), + Query::equal('resourceInternalId', [$resource->getSequence()]), + Query::equal('resourceType', [$resource->getCollection()]), + Query::orderDesc('$createdAt'), + ]; + + if (!empty($activeDeploymentId)) { + $queries[] = Query::notEqual('$id', $activeDeploymentId); + } + + $this->deleteByGroup( + 'deployments', + $queries, + $dbForProject, + function (Document $deployment) use ($queueForDeletes, $project) { + $queueForDeletes + ->setType(DELETE_TYPE_DOCUMENT) + ->setDocument($deployment) + ->setProject($project) + ->trigger(); + } + ); + }; + + $this->listByGroup( + 'functions', + [], + $dbForProject, + $removalCallback + ); + + $this->listByGroup( + 'sites', + [], + $dbForProject, + $removalCallback + ); + } + /** * @param Document $project * @param callable $getProjectDB @@ -609,7 +668,7 @@ class Deletes extends Action 'database' => $document->getAttribute('database') ]), ...$dbForProject->find('databases', [ - Query::equal('type', [DATABASE_TYPE_DOCUMENTSDB, DATABASE_TYPE_VECTORDB]), + Query::equal('type', [DATABASE_TYPE_DOCUMENTSDB, DATABASE_TYPE_VECTORSDB]), Query::limit(5000), ]), ]; diff --git a/src/Appwrite/Platform/Workers/Functions.php b/src/Appwrite/Platform/Workers/Functions.php index 18ab087966..29ccb0ef09 100644 --- a/src/Appwrite/Platform/Workers/Functions.php +++ b/src/Appwrite/Platform/Workers/Functions.php @@ -357,7 +357,7 @@ class Functions extends Action $user ??= new Document(); $functionId = $function->getId(); $deploymentId = $function->getAttribute('deploymentId', ''); - $spec = Config::getParam('specifications')[$function->getAttribute('specification', APP_COMPUTE_SPECIFICATION_DEFAULT)]; + $spec = Config::getParam('specifications')[$function->getAttribute('runtimeSpecification', APP_COMPUTE_SPECIFICATION_DEFAULT)]; $log->addTag('deploymentId', $deploymentId); @@ -511,6 +511,11 @@ class Functions extends Action try { $version = $function->getAttribute('version', 'v2'); $command = $runtime['startCommand']; + + if (!empty($deployment->getAttribute('startCommand', ''))) { + $command = 'cd /usr/local/server/src/function/ && ' . $deployment->getAttribute('startCommand', ''); + } + $source = $deployment->getAttribute('buildPath', ''); $extension = str_ends_with($source, '.tar') ? 'tar' : 'tar.gz'; $command = $version === 'v2' ? '' : "cp /tmp/code.$extension /mnt/code/code.$extension && nohup helpers/start.sh \"$command\""; diff --git a/src/Appwrite/Platform/Workers/Migrations.php b/src/Appwrite/Platform/Workers/Migrations.php index 1938891588..c5c21fbd07 100644 --- a/src/Appwrite/Platform/Workers/Migrations.php +++ b/src/Appwrite/Platform/Workers/Migrations.php @@ -323,8 +323,8 @@ class Migrations extends Action METRIC_DATABASES_OPERATIONS_WRITES, METRIC_DATABASES_OPERATIONS_READS_DOCUMENTSDB, METRIC_DATABASES_OPERATIONS_WRITES_DOCUMENTSDB, - METRIC_DATABASES_OPERATIONS_READS_VECTORDB, - METRIC_DATABASES_OPERATIONS_WRITES_VECTORDB, + METRIC_DATABASES_OPERATIONS_READS_VECTORSDB, + METRIC_DATABASES_OPERATIONS_WRITES_VECTORSDB, METRIC_NETWORK_REQUESTS, METRIC_NETWORK_INBOUND, METRIC_NETWORK_OUTBOUND, diff --git a/src/Appwrite/Platform/Workers/StatsResources.php b/src/Appwrite/Platform/Workers/StatsResources.php index 8481996efe..54545eefb0 100644 --- a/src/Appwrite/Platform/Workers/StatsResources.php +++ b/src/Appwrite/Platform/Workers/StatsResources.php @@ -112,7 +112,7 @@ class StatsResources extends Action $databases = $dbForProject->count('databases', [Query::equal('type', [DATABASE_TYPE_LEGACY, DATABASE_TYPE_TABLESDB])]); $documentsdb = $dbForProject->count('databases', [Query::equal('type', [DATABASE_TYPE_DOCUMENTSDB])]); - $vectordb = $dbForProject->count('databases', [Query::equal('type', [DATABASE_TYPE_VECTORDB])]); + $vectorsdb = $dbForProject->count('databases', [Query::equal('type', [DATABASE_TYPE_VECTORSDB])]); $buckets = $dbForProject->count('buckets'); $users = $dbForProject->count('users'); @@ -148,7 +148,7 @@ class StatsResources extends Action $metrics = [ METRIC_DATABASES => $databases, METRIC_DATABASES_DOCUMENTSDB => $documentsdb, - METRIC_DATABASES_VECTORDB => $vectordb, + METRIC_DATABASES_VECTORSDB => $vectorsdb, METRIC_BUCKETS => $buckets, METRIC_USERS => $users, METRIC_FUNCTIONS => $functions, @@ -273,7 +273,7 @@ class StatsResources extends Action $totalDocumentsDocumentsdb = 0; $totalDatabaseStorageDocumentsdb = 0; - // vectordb + // vectorsdb $totalCollectionsVectordb = 0; $totalDocumentsVectordb = 0; $totalDatabaseStorageVectordb = 0; @@ -299,7 +299,7 @@ class StatsResources extends Action $totalDocumentsDocumentsdb += $documents; $totalCollectionsDocumentsdb += $collections; break; - case DATABASE_TYPE_VECTORDB: + case DATABASE_TYPE_VECTORSDB: $totalDatabaseStorageVectordb += $storage; $totalDocumentsVectordb += $documents; $totalCollectionsVectordb += $collections; @@ -319,9 +319,9 @@ class StatsResources extends Action $this->createStatsDocuments($region, METRIC_DOCUMENTS_DOCUMENTSDB, $totalDocumentsDocumentsdb); $this->createStatsDocuments($region, METRIC_DATABASES_STORAGE_DOCUMENTSDB, $totalDatabaseStorageDocumentsdb); - $this->createStatsDocuments($region, METRIC_COLLECTIONS_VECTORDB, $totalCollectionsVectordb); - $this->createStatsDocuments($region, METRIC_DOCUMENTS_VECTORDB, $totalDocumentsVectordb); - $this->createStatsDocuments($region, METRIC_DATABASES_STORAGE_VECTORDB, $totalDatabaseStorageVectordb); + $this->createStatsDocuments($region, METRIC_COLLECTIONS_VECTORSDB, $totalCollectionsVectordb); + $this->createStatsDocuments($region, METRIC_DOCUMENTS_VECTORSDB, $totalDocumentsVectordb); + $this->createStatsDocuments($region, METRIC_DATABASES_STORAGE_VECTORSDB, $totalDatabaseStorageVectordb); } protected function countForCollections(Database $dbForProject, Database $dbForDatabases, Document $database, string $region): array { diff --git a/src/Appwrite/Platform/Workers/StatsUsage.php b/src/Appwrite/Platform/Workers/StatsUsage.php index 682ba1d006..305ba3f8fa 100644 --- a/src/Appwrite/Platform/Workers/StatsUsage.php +++ b/src/Appwrite/Platform/Workers/StatsUsage.php @@ -48,7 +48,7 @@ class StatsUsage extends Action protected array $skipBaseMetrics = [ METRIC_DATABASES => true, METRIC_DATABASES_DOCUMENTSDB => true, - METRIC_DATABASES_VECTORDB => true, + METRIC_DATABASES_VECTORSDB => true, METRIC_BUCKETS => true, METRIC_USERS => true, METRIC_FUNCTIONS => true, @@ -70,11 +70,11 @@ class StatsUsage extends Action METRIC_DOCUMENTS => true, METRIC_COLLECTIONS_DOCUMENTSDB => true, METRIC_DOCUMENTS_DOCUMENTSDB => true, - METRIC_COLLECTIONS_VECTORDB => true, - METRIC_DOCUMENTS_VECTORDB => true, + METRIC_COLLECTIONS_VECTORSDB => true, + METRIC_DOCUMENTS_VECTORSDB => true, METRIC_DATABASES_STORAGE => true, METRIC_DATABASES_STORAGE_DOCUMENTSDB => true, - METRIC_DATABASES_STORAGE_VECTORDB => true, + METRIC_DATABASES_STORAGE_VECTORSDB => true, ]; /** diff --git a/src/Appwrite/SDK/Specification/Format.php b/src/Appwrite/SDK/Specification/Format.php index 4302c61238..04ecafa8fc 100644 --- a/src/Appwrite/SDK/Specification/Format.php +++ b/src/Appwrite/SDK/Specification/Format.php @@ -367,7 +367,7 @@ abstract class Format } } break; - case 'vectorDB': + case 'vectorsDB': switch ($method) { case 'getUsage': case 'listUsage': @@ -380,7 +380,7 @@ abstract class Format case 'createIndex': switch ($param) { case 'type': - return 'VectorDBIndexType'; + return 'VectorsDBIndexType'; case 'orders': return 'OrderBy'; } @@ -669,7 +669,7 @@ abstract class Format break; case 'databases': case 'documentsDB': - case 'vectorDB': + case 'vectorsDB': switch ($method) { case 'getUsage': case 'listUsage': diff --git a/src/Appwrite/Utopia/Request/Filters/V21.php b/src/Appwrite/Utopia/Request/Filters/V21.php index 3ef0becf1d..4feb8e1926 100644 --- a/src/Appwrite/Utopia/Request/Filters/V21.php +++ b/src/Appwrite/Utopia/Request/Filters/V21.php @@ -6,7 +6,7 @@ use Appwrite\Utopia\Request\Filter; class V21 extends Filter { - // Convert 1.8.0 params to 1.8.1 + // Convert 1.8.0 params to 1.9.0 public function parse(array $content, string $model): array { switch ($model) { @@ -14,6 +14,12 @@ class V21 extends Filter case 'sites.createTemplateDeployment': $content = $this->convertVersionToTypeAndReference($content); break; + case 'functions.create': + case 'sites.create': + case 'functions.update': + case 'sites.update': + $content = $this->convertSpecs($content); + break; } return $content; } @@ -31,4 +37,15 @@ class V21 extends Filter } return $content; } + + protected function convertSpecs(array $content): array + { + if (!empty($content['specification'])) { + $content['buildSpecification'] = $content['specification']; + $content['runtimeSpecification'] = $content['specification']; + unset($content['specification']); + } + + return $content; + } } diff --git a/src/Appwrite/Utopia/Response.php b/src/Appwrite/Utopia/Response.php index dee33b27c5..c2fc520da3 100644 --- a/src/Appwrite/Utopia/Response.php +++ b/src/Appwrite/Utopia/Response.php @@ -34,8 +34,8 @@ class Response extends SwooleResponse public const MODEL_USAGE_DATABASE = 'usageDatabase'; public const MODEL_USAGE_DOCUMENTSDBS = 'usageDocumentsDBs'; public const MODEL_USAGE_DOCUMENTSDB = 'usageDocumentsDB'; - public const MODEL_USAGE_VECTORDBS = 'usageVectorDBs'; - public const MODEL_USAGE_VECTORDB = 'usageVectorDB'; + public const MODEL_USAGE_VECTORSDBS = 'usageVectorsDBs'; + public const MODEL_USAGE_VECTORSDB = 'usageVectorsDB'; public const MODEL_USAGE_TABLE = 'usageTable'; public const MODEL_USAGE_COLLECTION = 'usageCollection'; public const MODEL_USAGE_USERS = 'usageUsers'; @@ -52,8 +52,8 @@ class Response extends SwooleResponse public const MODEL_DATABASE_LIST = 'databaseList'; public const MODEL_COLLECTION = 'collection'; public const MODEL_COLLECTION_LIST = 'collectionList'; - public const MODEL_VECTORDB_COLLECTION = 'vectordbCollection'; - public const MODEL_VECTORDB_COLLECTION_LIST = 'vectordbCollectionList'; + public const MODEL_VECTORSDB_COLLECTION = 'vectorsdbCollection'; + public const MODEL_VECTORSDB_COLLECTION_LIST = 'vectorsdbCollectionList'; public const MODEL_EMBEDDING = 'embedding'; public const MODEL_EMBEDDING_LIST = 'embeddingList'; public const MODEL_TABLE = 'table'; diff --git a/src/Appwrite/Utopia/Response/Filters/V21.php b/src/Appwrite/Utopia/Response/Filters/V21.php new file mode 100644 index 0000000000..4a414a9418 --- /dev/null +++ b/src/Appwrite/Utopia/Response/Filters/V21.php @@ -0,0 +1,51 @@ + $this->parseSite($content), + Response::MODEL_SITE_LIST => $this->handleList( + $content, + "sites", + fn ($item) => $this->parseSite($item), + ), + Response::MODEL_FUNCTION => $this->parseFunction($content), + Response::MODEL_FUNCTION_LIST => $this->handleList( + $content, + "functions", + fn ($item) => $this->parseFunction($item), + ), + default => $parsedResponse, + }; + } + + protected function parseSite(array $content): array + { + $content = $this->parseSpecs($content); + return $content; + } + + protected function parseFunction(array $content): array + { + $content = $this->parseSpecs($content); + return $content; + } + + protected function parseSpecs(array $content): array + { + $content['specification'] = $content['buildSpecification'] ?? $content['specification'] ?? null; + unset($content['buildSpecification']); + unset($content['runtimeSpecification']); + return $content; + } +} diff --git a/src/Appwrite/Utopia/Response/Model/Func.php b/src/Appwrite/Utopia/Response/Model/Func.php index e33d7663fd..3aea364fe5 100644 --- a/src/Appwrite/Utopia/Response/Model/Func.php +++ b/src/Appwrite/Utopia/Response/Model/Func.php @@ -65,6 +65,12 @@ class Func extends Model 'default' => '', 'example' => 'python-3.8', ]) + ->addRule('deploymentRetention', [ + 'type' => self::TYPE_INTEGER, + 'description' => 'How many days to keep the non-active deployments before they will be automatically deleted.', + 'default' => 0, + 'example' => 7, + ]) ->addRule('deploymentId', [ 'type' => self::TYPE_STRING, 'description' => 'Function\'s active deployment ID.', @@ -176,9 +182,15 @@ class Func extends Model 'default' => false, 'example' => false, ]) - ->addRule('specification', [ + ->addRule('buildSpecification', [ 'type' => self::TYPE_STRING, - 'description' => 'Machine specification for builds and executions.', + 'description' => 'Machine specification for deployment builds.', + 'default' => APP_COMPUTE_SPECIFICATION_DEFAULT, + 'example' => APP_COMPUTE_SPECIFICATION_DEFAULT, + ]) + ->addRule('runtimeSpecification', [ + 'type' => self::TYPE_STRING, + 'description' => 'Machine specification for executions.', 'default' => APP_COMPUTE_SPECIFICATION_DEFAULT, 'example' => APP_COMPUTE_SPECIFICATION_DEFAULT, ]) diff --git a/src/Appwrite/Utopia/Response/Model/Site.php b/src/Appwrite/Utopia/Response/Model/Site.php index e6e205909b..941b6104df 100644 --- a/src/Appwrite/Utopia/Response/Model/Site.php +++ b/src/Appwrite/Utopia/Response/Model/Site.php @@ -58,6 +58,12 @@ class Site extends Model 'default' => '', 'example' => 'react', ]) + ->addRule('deploymentRetention', [ + 'type' => self::TYPE_INTEGER, + 'description' => 'How many days to keep the non-active deployments before they will be automatically deleted.', + 'default' => 0, + 'example' => 7, + ]) ->addRule('deploymentId', [ 'type' => self::TYPE_STRING, 'description' => 'Site\'s active deployment ID.', @@ -125,6 +131,12 @@ class Site extends Model 'default' => '', 'example' => 'npm run build', ]) + ->addRule('startCommand', [ + 'type' => self::TYPE_STRING, + 'description' => 'Custom command to use when starting site runtime.', + 'default' => '', + 'example' => 'node custom-server.mjs', + ]) ->addRule('outputDirectory', [ 'type' => self::TYPE_STRING, 'description' => 'The directory where the site build output is located.', @@ -161,9 +173,15 @@ class Site extends Model 'default' => false, 'example' => false, ]) - ->addRule('specification', [ + ->addRule('buildSpecification', [ 'type' => self::TYPE_STRING, - 'description' => 'Machine specification for builds and executions.', + 'description' => 'Machine specification for deployment builds.', + 'default' => APP_COMPUTE_SPECIFICATION_DEFAULT, + 'example' => APP_COMPUTE_SPECIFICATION_DEFAULT, + ]) + ->addRule('runtimeSpecification', [ + 'type' => self::TYPE_STRING, + 'description' => 'Machine specification for SSR executions.', 'default' => APP_COMPUTE_SPECIFICATION_DEFAULT, 'example' => APP_COMPUTE_SPECIFICATION_DEFAULT, ]) diff --git a/src/Appwrite/Utopia/Response/Model/UsageProject.php b/src/Appwrite/Utopia/Response/Model/UsageProject.php index 66628a7b13..e00c4bc1dc 100644 --- a/src/Appwrite/Utopia/Response/Model/UsageProject.php +++ b/src/Appwrite/Utopia/Response/Model/UsageProject.php @@ -267,81 +267,81 @@ class UsageProject extends Model 'default' => 0, 'example' => 0, ]) - // VectorDB aggregates - ->addRule('vectordbDatabasesTotal', [ + // VectorsDB aggregates + ->addRule('vectorsdbDatabasesTotal', [ 'type' => self::TYPE_INTEGER, - 'description' => 'Total aggregated number of VectorDB databases.', + 'description' => 'Total aggregated number of VectorsDB databases.', 'default' => 0, 'example' => 0, ]) - ->addRule('vectordbCollectionsTotal', [ + ->addRule('vectorsdbCollectionsTotal', [ 'type' => self::TYPE_INTEGER, - 'description' => 'Total aggregated number of VectorDB collections.', + 'description' => 'Total aggregated number of VectorsDB collections.', 'default' => 0, 'example' => 0, ]) - ->addRule('vectordbDocumentsTotal', [ + ->addRule('vectorsdbDocumentsTotal', [ 'type' => self::TYPE_INTEGER, - 'description' => 'Total aggregated number of VectorDB documents.', + 'description' => 'Total aggregated number of VectorsDB documents.', 'default' => 0, 'example' => 0, ]) - ->addRule('vectordbDatabasesStorageTotal', [ + ->addRule('vectorsdbDatabasesStorageTotal', [ 'type' => self::TYPE_INTEGER, - 'description' => 'Total aggregated VectorDB storage (bytes).', + 'description' => 'Total aggregated VectorsDB storage (bytes).', 'default' => 0, 'example' => 0, ]) - ->addRule('vectordbDatabasesReadsTotal', [ + ->addRule('vectorsdbDatabasesReadsTotal', [ 'type' => self::TYPE_INTEGER, - 'description' => 'Total aggregated number of VectorDB reads.', + 'description' => 'Total aggregated number of VectorsDB reads.', 'default' => 0, 'example' => 0, ]) - ->addRule('vectordbDatabasesWritesTotal', [ + ->addRule('vectorsdbDatabasesWritesTotal', [ 'type' => self::TYPE_INTEGER, - 'description' => 'Total aggregated number of VectorDB writes.', + 'description' => 'Total aggregated number of VectorsDB writes.', 'default' => 0, 'example' => 0, ]) - ->addRule('vectordbDatabases', [ + ->addRule('vectorsdbDatabases', [ 'type' => Response::MODEL_METRIC, - 'description' => 'Aggregated VectorDB databases per period.', + 'description' => 'Aggregated VectorsDB databases per period.', 'default' => [], 'example' => [], 'array' => true ]) - ->addRule('vectordbCollections', [ + ->addRule('vectorsdbCollections', [ 'type' => Response::MODEL_METRIC, - 'description' => 'Aggregated VectorDB collections per period.', + 'description' => 'Aggregated VectorsDB collections per period.', 'default' => [], 'example' => [], 'array' => true ]) - ->addRule('vectordbDocuments', [ + ->addRule('vectorsdbDocuments', [ 'type' => Response::MODEL_METRIC, - 'description' => 'Aggregated VectorDB documents per period.', + 'description' => 'Aggregated VectorsDB documents per period.', 'default' => [], 'example' => [], 'array' => true ]) - ->addRule('vectordbDatabasesStorage', [ + ->addRule('vectorsdbDatabasesStorage', [ 'type' => Response::MODEL_METRIC, - 'description' => 'Aggregated VectorDB storage per period.', + 'description' => 'Aggregated VectorsDB storage per period.', 'default' => [], 'example' => [], 'array' => true ]) - ->addRule('vectordbDatabasesReads', [ + ->addRule('vectorsdbDatabasesReads', [ 'type' => Response::MODEL_METRIC, - 'description' => 'Aggregated VectorDB reads per period.', + 'description' => 'Aggregated VectorsDB reads per period.', 'default' => [], 'example' => [], 'array' => true ]) - ->addRule('vectordbDatabasesWrites', [ + ->addRule('vectorsdbDatabasesWrites', [ 'type' => Response::MODEL_METRIC, - 'description' => 'Aggregated VectorDB writes per period.', + 'description' => 'Aggregated VectorsDB writes per period.', 'default' => [], 'example' => [], 'array' => true diff --git a/src/Appwrite/Utopia/Response/Model/UsageVectorDB.php b/src/Appwrite/Utopia/Response/Model/UsageVectorsDB.php similarity index 96% rename from src/Appwrite/Utopia/Response/Model/UsageVectorDB.php rename to src/Appwrite/Utopia/Response/Model/UsageVectorsDB.php index a90f593c7e..c652a3d62e 100644 --- a/src/Appwrite/Utopia/Response/Model/UsageVectorDB.php +++ b/src/Appwrite/Utopia/Response/Model/UsageVectorsDB.php @@ -5,7 +5,7 @@ namespace Appwrite\Utopia\Response\Model; use Appwrite\Utopia\Response; use Appwrite\Utopia\Response\Model; -class UsageVectorDB extends Model +class UsageVectorsDB extends Model { public function __construct() { @@ -86,11 +86,11 @@ class UsageVectorDB extends Model public function getName(): string { - return 'UsageVectorDB'; + return 'UsageVectorsDB'; } public function getType(): string { - return Response::MODEL_USAGE_VECTORDB; + return Response::MODEL_USAGE_VECTORSDB; } } diff --git a/src/Appwrite/Utopia/Response/Model/UsageVectorDBs.php b/src/Appwrite/Utopia/Response/Model/UsageVectorsDBs.php similarity index 96% rename from src/Appwrite/Utopia/Response/Model/UsageVectorDBs.php rename to src/Appwrite/Utopia/Response/Model/UsageVectorsDBs.php index da63120c5c..1f5fe7853d 100644 --- a/src/Appwrite/Utopia/Response/Model/UsageVectorDBs.php +++ b/src/Appwrite/Utopia/Response/Model/UsageVectorsDBs.php @@ -5,7 +5,7 @@ namespace Appwrite\Utopia\Response\Model; use Appwrite\Utopia\Response; use Appwrite\Utopia\Response\Model; -class UsageVectorDBs extends Model +class UsageVectorsDBs extends Model { public function __construct() { @@ -18,7 +18,7 @@ class UsageVectorDBs extends Model ]) ->addRule('databasesTotal', [ 'type' => self::TYPE_INTEGER, - 'description' => 'Total aggregated number of VectorDB databases.', + 'description' => 'Total aggregated number of VectorsDB databases.', 'default' => 0, 'example' => 0, ]) @@ -99,11 +99,11 @@ class UsageVectorDBs extends Model public function getName(): string { - return 'UsageVectorDBs'; + return 'UsageVectorsDBs'; } public function getType(): string { - return Response::MODEL_USAGE_VECTORDBS; + return Response::MODEL_USAGE_VECTORSDBS; } } diff --git a/src/Appwrite/Utopia/Response/Model/VectorDBCollection.php b/src/Appwrite/Utopia/Response/Model/VectorsDBCollection.php similarity index 86% rename from src/Appwrite/Utopia/Response/Model/VectorDBCollection.php rename to src/Appwrite/Utopia/Response/Model/VectorsDBCollection.php index ccf609132d..5053628e74 100644 --- a/src/Appwrite/Utopia/Response/Model/VectorDBCollection.php +++ b/src/Appwrite/Utopia/Response/Model/VectorsDBCollection.php @@ -4,7 +4,7 @@ namespace Appwrite\Utopia\Response\Model; use Appwrite\Utopia\Response; -class VectorDBCollection extends Collection +class VectorsDBCollection extends Collection { public function __construct() { @@ -31,11 +31,11 @@ class VectorDBCollection extends Collection public function getName(): string { - return 'VectorDB Collection'; + return 'VectorsDB Collection'; } public function getType(): string { - return Response::MODEL_VECTORDB_COLLECTION; + return Response::MODEL_VECTORSDB_COLLECTION; } } diff --git a/tests/e2e/General/UsageTest.php b/tests/e2e/General/UsageTest.php index 35afe23320..16346f95bd 100644 --- a/tests/e2e/General/UsageTest.php +++ b/tests/e2e/General/UsageTest.php @@ -1150,7 +1150,7 @@ class UsageTest extends Scope } #[Depends('testDocumentsDBStats')] - public function testPrepareVectorDBStats(array $data): array + public function testPrepareVectorsDBStats(array $data): array { $documentsTotal = 0; $collectionsTotal = 0; @@ -1159,11 +1159,11 @@ class UsageTest extends Scope $requestsTotal = $data['requestsTotal']; for ($i = 0; $i < self::CREATE; $i++) { - $name = uniqid() . ' vectordb'; + $name = uniqid() . ' vectorsdb'; $response = $this->client->call( Client::METHOD_POST, - '/vectordb', + '/vectorsdb', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'] @@ -1185,7 +1185,7 @@ class UsageTest extends Scope if ($i < (self::CREATE / 2)) { $response = $this->client->call( Client::METHOD_DELETE, - '/vectordb/' . $vectordbId, + '/vectorsdb/' . $vectordbId, array_merge([ 'x-appwrite-project' => $this->getProject()['$id'] ], $this->getHeaders()), @@ -1203,7 +1203,7 @@ class UsageTest extends Scope $response = $this->client->call( Client::METHOD_POST, - '/vectordb/' . $vectordbId . '/collections', + '/vectorsdb/' . $vectordbId . '/collections', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'] @@ -1233,7 +1233,7 @@ class UsageTest extends Scope if ($i < (self::CREATE / 2)) { $response = $this->client->call( Client::METHOD_DELETE, - '/vectordb/' . $vectordbId . '/collections/' . $collectionId, + '/vectorsdb/' . $vectordbId . '/collections/' . $collectionId, array_merge([ 'x-appwrite-project' => $this->getProject()['$id'] ], $this->getHeaders()), @@ -1249,7 +1249,7 @@ class UsageTest extends Scope for ($i = 0; $i < self::CREATE; $i++) { $response = $this->client->call( Client::METHOD_POST, - '/vectordb/' . $vectordbId . '/collections/' . $collectionId . '/documents', + '/vectorsdb/' . $vectordbId . '/collections/' . $collectionId . '/documents', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'] @@ -1276,7 +1276,7 @@ class UsageTest extends Scope if ($i < (self::CREATE / 2)) { $response = $this->client->call( Client::METHOD_DELETE, - '/vectordb/' . $vectordbId . '/collections/' . $collectionId . '/documents/' . $documentId, + '/vectorsdb/' . $vectordbId . '/collections/' . $collectionId . '/documents/' . $documentId, array_merge([ 'x-appwrite-project' => $this->getProject()['$id'] ], $this->getHeaders()), @@ -1300,9 +1300,9 @@ class UsageTest extends Scope ]); } - #[Depends('testPrepareVectorDBStats')] + #[Depends('testPrepareVectorsDBStats')] #[Retry(count: 1)] - public function testVectorDBStats(array $data): array + public function testVectorsDBStats(array $data): array { $vectordbId = $data['vectordbId']; $collectionId = $data['vectordbCollectionId']; @@ -1329,7 +1329,7 @@ class UsageTest extends Scope $this->assertCount(1, $response['body']['network']); $this->assertEquals($requestsTotal, $response['body']['requests'][array_key_last($response['body']['requests'])]['value']); $this->validateDates($response['body']['requests']); - // vectordbTotal should reflect only VectorDB instances, not relational databases. + // vectordbTotal should reflect only VectorsDB instances, not relational databases. $this->assertEquals($vectordbTotal, $response['body']['vectordbDatabasesTotal']); $this->assertEquals($documentsTotal, $response['body']['vectordbDocumentsTotal']); }); @@ -1346,7 +1346,7 @@ class UsageTest extends Scope $this->assertEventually(function () use ($vectordbId, $collectionsTotal, $documentsTotal) { $response = $this->client->call( Client::METHOD_GET, - '/vectordb/' . $vectordbId . '/usage?range=30d', + '/vectorsdb/' . $vectordbId . '/usage?range=30d', $this->getConsoleHeaders() ); @@ -1360,7 +1360,7 @@ class UsageTest extends Scope $this->assertEventually(function () use ($vectordbId, $collectionId, $documentsTotal) { $response = $this->client->call( Client::METHOD_GET, - '/vectordb/' . $vectordbId . '/collections/' . $collectionId . '/usage?range=30d', + '/vectorsdb/' . $vectordbId . '/collections/' . $collectionId . '/usage?range=30d', $this->getConsoleHeaders() ); @@ -1371,7 +1371,7 @@ class UsageTest extends Scope return $data; } - #[Depends('testVectorDBStats')] + #[Depends('testVectorsDBStats')] public function testPrepareFunctionsStats(array $data): array { $executionTime = 0; @@ -1401,7 +1401,8 @@ class UsageTest extends Scope ], 'schedule' => '0 0 1 1 *', 'timeout' => 10, - 'specification' => Specification::S_8VCPU_8GB + 'buildSpecification' => Specification::S_8VCPU_8GB, + 'runtimeSpecification' => Specification::S_4VCPU_4GB, ] ); @@ -1857,7 +1858,7 @@ class UsageTest extends Scope for ($i = 0; $i < 3; $i++) { $response = $this->client->call( Client::METHOD_POST, - '/vectordb/embeddings/text', + '/vectorsdb/embeddings/text', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], diff --git a/tests/e2e/Scopes/ApiVectorDB.php b/tests/e2e/Scopes/ApiVectorsDB.php similarity index 91% rename from tests/e2e/Scopes/ApiVectorDB.php rename to tests/e2e/Scopes/ApiVectorsDB.php index e9e9ac6205..09494d3c10 100644 --- a/tests/e2e/Scopes/ApiVectorDB.php +++ b/tests/e2e/Scopes/ApiVectorsDB.php @@ -3,19 +3,19 @@ namespace Tests\E2E\Scopes; /** - * API configuration trait for VectorDB database API. - * Uses: /vectordb, collections, documents, indexes + * API configuration trait for VectorsDB database API. + * Uses: /vectorsdb, collections, documents, indexes */ -trait ApiVectorDB +trait ApiVectorsDB { protected function getApiBasePath(): string { - return '/vectordb'; + return '/vectorsdb'; } protected function getDatabaseType(): string { - return 'vectordb'; + return 'vectorsdb'; } protected function getContainerResource(): string diff --git a/tests/e2e/Services/Databases/Permissions/VectorDBPermissionsGuestTest.php b/tests/e2e/Services/Databases/Permissions/VectorsDBPermissionsGuestTest.php similarity index 85% rename from tests/e2e/Services/Databases/Permissions/VectorDBPermissionsGuestTest.php rename to tests/e2e/Services/Databases/Permissions/VectorsDBPermissionsGuestTest.php index 8ceac1c55d..52ddcc8586 100644 --- a/tests/e2e/Services/Databases/Permissions/VectorDBPermissionsGuestTest.php +++ b/tests/e2e/Services/Databases/Permissions/VectorsDBPermissionsGuestTest.php @@ -1,19 +1,19 @@ client->call(Client::METHOD_POST, '/vectordb', array_merge([ + $database = $this->client->call(Client::METHOD_POST, '/vectorsdb', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -46,7 +46,7 @@ class VectorDBPermissionsGuestTest extends Scope $this->assertEquals('VectorGuestDB', $database['body']['name']); $databaseId = $database['body']['$id']; - $publicMovies = $this->client->call(Client::METHOD_POST, '/vectordb/' . $databaseId . '/collections', $this->getServerHeader(), [ + $publicMovies = $this->client->call(Client::METHOD_POST, '/vectorsdb/' . $databaseId . '/collections', $this->getServerHeader(), [ 'collectionId' => ID::unique(), 'name' => 'Movies', 'dimension' => 3, @@ -57,7 +57,7 @@ class VectorDBPermissionsGuestTest extends Scope Permission::delete(Role::any()), ], ]); - $privateMovies = $this->client->call(Client::METHOD_POST, '/vectordb/' . $databaseId . '/collections', $this->getServerHeader(), [ + $privateMovies = $this->client->call(Client::METHOD_POST, '/vectorsdb/' . $databaseId . '/collections', $this->getServerHeader(), [ 'collectionId' => ID::unique(), 'name' => 'Movies', 'dimension' => 3, @@ -95,7 +95,7 @@ class VectorDBPermissionsGuestTest extends Scope $privateCollectionId = $data['privateCollectionId']; $databaseId = $data['databaseId']; - $publicResponse = $this->client->call(Client::METHOD_POST, '/vectordb/' . $databaseId . '/collections/' . $publicCollectionId . '/documents', $this->getServerHeader(), [ + $publicResponse = $this->client->call(Client::METHOD_POST, '/vectorsdb/' . $databaseId . '/collections/' . $publicCollectionId . '/documents', $this->getServerHeader(), [ 'documentId' => ID::unique(), 'data' => [ 'embeddings' => [1.0, 0.0, 0.0], @@ -103,7 +103,7 @@ class VectorDBPermissionsGuestTest extends Scope ], 'permissions' => $permissions, ]); - $privateResponse = $this->client->call(Client::METHOD_POST, '/vectordb/' . $databaseId . '/collections/' . $privateCollectionId . '/documents', $this->getServerHeader(), [ + $privateResponse = $this->client->call(Client::METHOD_POST, '/vectorsdb/' . $databaseId . '/collections/' . $privateCollectionId . '/documents', $this->getServerHeader(), [ 'documentId' => ID::unique(), 'data' => [ 'embeddings' => [0.0, 1.0, 0.0], @@ -118,11 +118,11 @@ class VectorDBPermissionsGuestTest extends Scope $roles = $this->getAuthorization()->getRoles(); $this->getAuthorization()->cleanRoles(); - $publicDocuments = $this->client->call(Client::METHOD_GET, '/vectordb/' . $databaseId . '/collections/' . $publicCollectionId . '/documents', [ + $publicDocuments = $this->client->call(Client::METHOD_GET, '/vectorsdb/' . $databaseId . '/collections/' . $publicCollectionId . '/documents', [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ]); - $privateDocuments = $this->client->call(Client::METHOD_GET, '/vectordb/' . $databaseId . '/collections/' . $privateCollectionId . '/documents', [ + $privateDocuments = $this->client->call(Client::METHOD_GET, '/vectorsdb/' . $databaseId . '/collections/' . $privateCollectionId . '/documents', [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ]); @@ -152,7 +152,7 @@ class VectorDBPermissionsGuestTest extends Scope $roles = $this->getAuthorization()->getRoles(); $this->getAuthorization()->cleanRoles(); - $publicResponse = $this->client->call(Client::METHOD_POST, '/vectordb/' . $databaseId . '/collections/' . $publicCollectionId . '/documents', [ + $publicResponse = $this->client->call(Client::METHOD_POST, '/vectorsdb/' . $databaseId . '/collections/' . $publicCollectionId . '/documents', [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], [ @@ -166,7 +166,7 @@ class VectorDBPermissionsGuestTest extends Scope $publicDocumentId = $publicResponse['body']['$id']; $this->assertEquals(201, $publicResponse['headers']['status-code']); - $privateResponse = $this->client->call(Client::METHOD_POST, '/vectordb/' . $databaseId . '/collections/' . $privateCollectionId . '/documents', [ + $privateResponse = $this->client->call(Client::METHOD_POST, '/vectorsdb/' . $databaseId . '/collections/' . $privateCollectionId . '/documents', [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], [ @@ -180,7 +180,7 @@ class VectorDBPermissionsGuestTest extends Scope $this->assertEquals(401, $privateResponse['headers']['status-code']); // Create a document in private collection with API key so we can test that update and delete are also not allowed - $privateResponse = $this->client->call(Client::METHOD_POST, '/vectordb/' . $databaseId . '/collections/' . $privateCollectionId . '/documents', $this->getServerHeader(), [ + $privateResponse = $this->client->call(Client::METHOD_POST, '/vectorsdb/' . $databaseId . '/collections/' . $privateCollectionId . '/documents', $this->getServerHeader(), [ 'documentId' => ID::unique(), 'data' => [ 'embeddings' => [0.0, 0.0, 1.0], @@ -191,7 +191,7 @@ class VectorDBPermissionsGuestTest extends Scope $this->assertEquals(201, $privateResponse['headers']['status-code']); $privateDocumentId = $privateResponse['body']['$id']; - $publicDocument = $this->client->call(Client::METHOD_PUT, '/vectordb/' . $databaseId . '/collections/' . $publicCollectionId . '/documents/' . $publicDocumentId, [ + $publicDocument = $this->client->call(Client::METHOD_PUT, '/vectorsdb/' . $databaseId . '/collections/' . $publicCollectionId . '/documents/' . $publicDocumentId, [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], [ @@ -204,7 +204,7 @@ class VectorDBPermissionsGuestTest extends Scope $this->assertEquals(200, $publicDocument['headers']['status-code']); $this->assertEquals('Thor: Ragnarok', $publicDocument['body']['metadata']['title']); - $privateDocument = $this->client->call(Client::METHOD_PUT, '/vectordb/' . $databaseId . '/collections/' . $privateCollectionId . '/documents/' . $privateDocumentId, [ + $privateDocument = $this->client->call(Client::METHOD_PUT, '/vectorsdb/' . $databaseId . '/collections/' . $privateCollectionId . '/documents/' . $privateDocumentId, [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], [ @@ -216,14 +216,14 @@ class VectorDBPermissionsGuestTest extends Scope $this->assertEquals(401, $privateDocument['headers']['status-code']); - $publicDocument = $this->client->call(Client::METHOD_DELETE, '/vectordb/' . $databaseId . '/collections/' . $publicCollectionId . '/documents/' . $publicDocumentId, [ + $publicDocument = $this->client->call(Client::METHOD_DELETE, '/vectorsdb/' . $databaseId . '/collections/' . $publicCollectionId . '/documents/' . $publicDocumentId, [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ]); $this->assertEquals(204, $publicDocument['headers']['status-code']); - $privateDocument = $this->client->call(Client::METHOD_DELETE, '/vectordb/' . $databaseId . '/collections/' . $privateCollectionId . '/documents/' . $privateDocumentId, [ + $privateDocument = $this->client->call(Client::METHOD_DELETE, '/vectorsdb/' . $databaseId . '/collections/' . $privateCollectionId . '/documents/' . $privateDocumentId, [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ]); @@ -237,7 +237,7 @@ class VectorDBPermissionsGuestTest extends Scope public function testWriteDocumentWithPermissions() { - $database = $this->client->call(Client::METHOD_POST, '/vectordb', array_merge([ + $database = $this->client->call(Client::METHOD_POST, '/vectorsdb', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -249,7 +249,7 @@ class VectorDBPermissionsGuestTest extends Scope $this->assertEquals('VectorGuestPermsWrite', $database['body']['name']); $databaseId = $database['body']['$id']; - $movies = $this->client->call(Client::METHOD_POST, '/vectordb/' . $databaseId . '/collections', $this->getServerHeader(), [ + $movies = $this->client->call(Client::METHOD_POST, '/vectorsdb/' . $databaseId . '/collections', $this->getServerHeader(), [ 'collectionId' => ID::unique(), 'name' => 'Movies', 'dimension' => 3, @@ -261,7 +261,7 @@ class VectorDBPermissionsGuestTest extends Scope $moviesId = $movies['body']['$id']; - $document = $this->client->call(Client::METHOD_POST, '/vectordb/' . $databaseId . '/collections/' . $moviesId . '/documents', [ + $document = $this->client->call(Client::METHOD_POST, '/vectorsdb/' . $databaseId . '/collections/' . $moviesId . '/documents', [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], [ diff --git a/tests/e2e/Services/Databases/Permissions/VectorDBPermissionsMemberTest.php b/tests/e2e/Services/Databases/Permissions/VectorsDBPermissionsMemberTest.php similarity index 87% rename from tests/e2e/Services/Databases/Permissions/VectorDBPermissionsMemberTest.php rename to tests/e2e/Services/Databases/Permissions/VectorsDBPermissionsMemberTest.php index 9b8ac234b2..3043a42dd5 100644 --- a/tests/e2e/Services/Databases/Permissions/VectorDBPermissionsMemberTest.php +++ b/tests/e2e/Services/Databases/Permissions/VectorsDBPermissionsMemberTest.php @@ -1,6 +1,6 @@ createUsers(); - $db = $this->client->call(Client::METHOD_POST, '/vectordb', $this->getServerHeader(), [ + $db = $this->client->call(Client::METHOD_POST, '/vectorsdb', $this->getServerHeader(), [ 'databaseId' => ID::unique(), 'name' => 'Test Database', ]); @@ -67,7 +67,7 @@ class VectorDBPermissionsMemberTest extends Scope $databaseId = $db['body']['$id']; - $public = $this->client->call(Client::METHOD_POST, '/vectordb/' . $databaseId . '/collections', $this->getServerHeader(), [ + $public = $this->client->call(Client::METHOD_POST, '/vectorsdb/' . $databaseId . '/collections', $this->getServerHeader(), [ 'collectionId' => ID::unique(), 'name' => 'Movies', 'dimension' => 3, @@ -82,7 +82,7 @@ class VectorDBPermissionsMemberTest extends Scope $this->assertEquals(201, $public['headers']['status-code']); $this->collections = ['public' => $public['body']['$id']]; - $private = $this->client->call(Client::METHOD_POST, '/vectordb/' . $databaseId . '/collections', $this->getServerHeader(), [ + $private = $this->client->call(Client::METHOD_POST, '/vectorsdb/' . $databaseId . '/collections', $this->getServerHeader(), [ 'collectionId' => ID::unique(), 'name' => 'Private Movies', 'dimension' => 3, @@ -97,7 +97,7 @@ class VectorDBPermissionsMemberTest extends Scope $this->assertEquals(201, $private['headers']['status-code']); $this->collections['private'] = $private['body']['$id']; - $doconly = $this->client->call(Client::METHOD_POST, '/vectordb/' . $databaseId . '/collections', $this->getServerHeader(), [ + $doconly = $this->client->call(Client::METHOD_POST, '/vectorsdb/' . $databaseId . '/collections', $this->getServerHeader(), [ 'collectionId' => ID::unique(), 'name' => 'Document Only Movies', 'dimension' => 3, @@ -125,7 +125,7 @@ class VectorDBPermissionsMemberTest extends Scope $collections = $data['collections']; $databaseId = $data['databaseId']; - $response = $this->client->call(Client::METHOD_POST, '/vectordb/' . $databaseId . '/collections/' . $collections['public'] . '/documents', $this->getServerHeader(), [ + $response = $this->client->call(Client::METHOD_POST, '/vectorsdb/' . $databaseId . '/collections/' . $collections['public'] . '/documents', $this->getServerHeader(), [ 'documentId' => ID::unique(), 'data' => [ 'embeddings' => [1.0, 0.0, 0.0], @@ -135,7 +135,7 @@ class VectorDBPermissionsMemberTest extends Scope ]); $this->assertEquals(201, $response['headers']['status-code']); - $response = $this->client->call(Client::METHOD_POST, '/vectordb/' . $databaseId . '/collections/' . $collections['private'] . '/documents', $this->getServerHeader(), [ + $response = $this->client->call(Client::METHOD_POST, '/vectorsdb/' . $databaseId . '/collections/' . $collections['private'] . '/documents', $this->getServerHeader(), [ 'documentId' => ID::unique(), 'data' => [ 'embeddings' => [0.0, 1.0, 0.0], @@ -145,7 +145,7 @@ class VectorDBPermissionsMemberTest extends Scope ]); $this->assertEquals(201, $response['headers']['status-code']); - $response = $this->client->call(Client::METHOD_POST, '/vectordb/' . $databaseId . '/collections/' . $collections['doconly'] . '/documents', $this->getServerHeader(), [ + $response = $this->client->call(Client::METHOD_POST, '/vectorsdb/' . $databaseId . '/collections/' . $collections['doconly'] . '/documents', $this->getServerHeader(), [ 'documentId' => ID::unique(), 'data' => [ 'embeddings' => [0.0, 0.0, 1.0], @@ -158,7 +158,7 @@ class VectorDBPermissionsMemberTest extends Scope /** * Check "any" permission collection */ - $documents = $this->client->call(Client::METHOD_GET, '/vectordb/' . $databaseId . '/collections/' . $collections['public'] . '/documents', [ + $documents = $this->client->call(Client::METHOD_GET, '/vectorsdb/' . $databaseId . '/collections/' . $collections['public'] . '/documents', [ 'origin' => 'http://localhost', 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], @@ -171,7 +171,7 @@ class VectorDBPermissionsMemberTest extends Scope /** * Check "users" permission collection */ - $documents = $this->client->call(Client::METHOD_GET, '/vectordb/' . $databaseId . '/collections/' . $collections['private'] . '/documents', [ + $documents = $this->client->call(Client::METHOD_GET, '/vectorsdb/' . $databaseId . '/collections/' . $collections['private'] . '/documents', [ 'origin' => 'http://localhost', 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], @@ -184,7 +184,7 @@ class VectorDBPermissionsMemberTest extends Scope /** * Check "user:user1" document only permission collection */ - $documents = $this->client->call(Client::METHOD_GET, '/vectordb/' . $databaseId . '/collections/' . $collections['doconly'] . '/documents', [ + $documents = $this->client->call(Client::METHOD_GET, '/vectorsdb/' . $databaseId . '/collections/' . $collections['doconly'] . '/documents', [ 'origin' => 'http://localhost', 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], diff --git a/tests/e2e/Services/Databases/Permissions/VectorDBPermissionsTeamTest.php b/tests/e2e/Services/Databases/Permissions/VectorsDBPermissionsTeamTest.php similarity index 88% rename from tests/e2e/Services/Databases/Permissions/VectorDBPermissionsTeamTest.php rename to tests/e2e/Services/Databases/Permissions/VectorsDBPermissionsTeamTest.php index 409d0d2a76..11709ed729 100644 --- a/tests/e2e/Services/Databases/Permissions/VectorDBPermissionsTeamTest.php +++ b/tests/e2e/Services/Databases/Permissions/VectorsDBPermissionsTeamTest.php @@ -1,6 +1,6 @@ client->call(Client::METHOD_POST, '/vectordb', $this->getServerHeader(), [ + $db = $this->client->call(Client::METHOD_POST, '/vectorsdb', $this->getServerHeader(), [ 'databaseId' => $this->databaseId, 'name' => 'Test Database', ]); $this->assertEquals(201, $db['headers']['status-code']); - $collection1 = $this->client->call(Client::METHOD_POST, '/vectordb/' . $this->databaseId . '/collections', $this->getServerHeader(), [ + $collection1 = $this->client->call(Client::METHOD_POST, '/vectorsdb/' . $this->databaseId . '/collections', $this->getServerHeader(), [ 'collectionId' => ID::custom('collection1'), 'name' => 'Collection 1', 'dimension' => 3, @@ -61,7 +61,7 @@ class VectorDBPermissionsTeamTest extends Scope $this->collections['collection1'] = $collection1['body']['$id']; - $collection2 = $this->client->call(Client::METHOD_POST, '/vectordb/' . $this->databaseId . '/collections', $this->getServerHeader(), [ + $collection2 = $this->client->call(Client::METHOD_POST, '/vectorsdb/' . $this->databaseId . '/collections', $this->getServerHeader(), [ 'collectionId' => ID::custom('collection2'), 'name' => 'Collection 2', 'dimension' => 3, @@ -131,7 +131,7 @@ class VectorDBPermissionsTeamTest extends Scope $this->createCollections($this->teams); - $response = $this->client->call(Client::METHOD_POST, '/vectordb/' . $this->databaseId . '/collections/' . $this->collections['collection1'] . '/documents', $this->getServerHeader(), [ + $response = $this->client->call(Client::METHOD_POST, '/vectorsdb/' . $this->databaseId . '/collections/' . $this->collections['collection1'] . '/documents', $this->getServerHeader(), [ 'documentId' => ID::unique(), 'data' => [ 'embeddings' => [1.0, 0.0, 0.0], @@ -140,7 +140,7 @@ class VectorDBPermissionsTeamTest extends Scope ]); $this->assertEquals(201, $response['headers']['status-code']); - $response = $this->client->call(Client::METHOD_POST, '/vectordb/' . $this->databaseId . '/collections/' . $this->collections['collection2'] . '/documents', $this->getServerHeader(), [ + $response = $this->client->call(Client::METHOD_POST, '/vectorsdb/' . $this->databaseId . '/collections/' . $this->collections['collection2'] . '/documents', $this->getServerHeader(), [ 'documentId' => ID::unique(), 'data' => [ 'embeddings' => [0.0, 1.0, 0.0], @@ -159,7 +159,7 @@ class VectorDBPermissionsTeamTest extends Scope #[DataProvider('readDocumentsProvider')] public function testReadDocuments($user, $collection, $success, $users) { - $documents = $this->client->call(Client::METHOD_GET, '/vectordb/' . $this->databaseId . '/collections/' . $collection . '/documents', [ + $documents = $this->client->call(Client::METHOD_GET, '/vectorsdb/' . $this->databaseId . '/collections/' . $collection . '/documents', [ 'origin' => 'http://localhost', 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], @@ -177,7 +177,7 @@ class VectorDBPermissionsTeamTest extends Scope #[DataProvider('writeDocumentsProvider')] public function testWriteDocuments($user, $collection, $success, $users) { - $documents = $this->client->call(Client::METHOD_POST, '/vectordb/' . $this->databaseId . '/collections/' . $collection . '/documents', [ + $documents = $this->client->call(Client::METHOD_POST, '/vectorsdb/' . $this->databaseId . '/collections/' . $collection . '/documents', [ 'origin' => 'http://localhost', 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], diff --git a/tests/e2e/Services/Databases/Transactions/VectorDBACIDTest.php b/tests/e2e/Services/Databases/Transactions/VectorsDBACIDTest.php similarity index 89% rename from tests/e2e/Services/Databases/Transactions/VectorDBACIDTest.php rename to tests/e2e/Services/Databases/Transactions/VectorsDBACIDTest.php index 2af598d0ce..914c8d0c5b 100644 --- a/tests/e2e/Services/Databases/Transactions/VectorDBACIDTest.php +++ b/tests/e2e/Services/Databases/Transactions/VectorsDBACIDTest.php @@ -10,7 +10,7 @@ use Utopia\Database\Helpers\ID; use Utopia\Database\Helpers\Permission; use Utopia\Database\Helpers\Role; -class VectorDBACIDTest extends Scope +class VectorsDBACIDTest extends Scope { use ProjectCustom; use SideClient; @@ -28,7 +28,7 @@ class VectorDBACIDTest extends Scope public function testAtomicity(): void { // Create database - $database = $this->client->call(Client::METHOD_POST, '/vectordb', array_merge([ + $database = $this->client->call(Client::METHOD_POST, '/vectorsdb', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -41,7 +41,7 @@ class VectorDBACIDTest extends Scope $databaseId = $database['body']['$id']; // Create collection for the test - $collection = $this->client->call(Client::METHOD_POST, '/vectordb/' . $databaseId . '/collections', array_merge([ + $collection = $this->client->call(Client::METHOD_POST, '/vectorsdb/' . $databaseId . '/collections', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -61,7 +61,7 @@ class VectorDBACIDTest extends Scope // Create a document outside the transaction $existingDocumentId = 'existing_doc'; - $doc1 = $this->client->call(Client::METHOD_POST, "/vectordb/{$databaseId}/collections/{$collectionId}/documents", array_merge([ + $doc1 = $this->client->call(Client::METHOD_POST, "/vectorsdb/{$databaseId}/collections/{$collectionId}/documents", array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders()), [ @@ -75,7 +75,7 @@ class VectorDBACIDTest extends Scope $this->assertEquals(201, $doc1['headers']['status-code']); // Create transaction - $transaction = $this->client->call(Client::METHOD_POST, '/vectordb/transactions', array_merge([ + $transaction = $this->client->call(Client::METHOD_POST, '/vectorsdb/transactions', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -86,7 +86,7 @@ class VectorDBACIDTest extends Scope $transactionId = $transaction['body']['$id']; // Add operations - second create reuses an existing documentId and should cause the commit to fail - $response = $this->client->call(Client::METHOD_POST, "/vectordb/{$databaseId}/collections/{$collectionId}/documents", array_merge([ + $response = $this->client->call(Client::METHOD_POST, "/vectorsdb/{$databaseId}/collections/{$collectionId}/documents", array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -114,7 +114,7 @@ class VectorDBACIDTest extends Scope $this->assertEquals(200, $response['headers']['status-code'], 'Adding documents via normal route should succeed. Response: ' . json_encode($response['body'])); // Attempt to commit - should fail due to duplicate document ID - $response = $this->client->call(Client::METHOD_PATCH, "/vectordb/transactions/{$transactionId}", array_merge([ + $response = $this->client->call(Client::METHOD_PATCH, "/vectorsdb/transactions/{$transactionId}", array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -125,7 +125,7 @@ class VectorDBACIDTest extends Scope $this->assertEquals(409, $response['headers']['status-code']); // Verify NO new documents were created (atomicity) - $documents = $this->client->call(Client::METHOD_GET, "/vectordb/{$databaseId}/collections/{$collectionId}/documents", array_merge([ + $documents = $this->client->call(Client::METHOD_GET, "/vectorsdb/{$databaseId}/collections/{$collectionId}/documents", array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders())); @@ -140,7 +140,7 @@ class VectorDBACIDTest extends Scope public function testConsistency(): void { // Create database - $database = $this->client->call(Client::METHOD_POST, '/vectordb', array_merge([ + $database = $this->client->call(Client::METHOD_POST, '/vectorsdb', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -153,7 +153,7 @@ class VectorDBACIDTest extends Scope $databaseId = $database['body']['$id']; // Create collection - $collection = $this->client->call(Client::METHOD_POST, '/vectordb/' . $databaseId . '/collections', array_merge([ + $collection = $this->client->call(Client::METHOD_POST, '/vectorsdb/' . $databaseId . '/collections', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -172,7 +172,7 @@ class VectorDBACIDTest extends Scope $collectionId = $collection['body']['$id']; // Create transaction - $transaction = $this->client->call(Client::METHOD_POST, '/vectordb/transactions', array_merge([ + $transaction = $this->client->call(Client::METHOD_POST, '/vectorsdb/transactions', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -181,7 +181,7 @@ class VectorDBACIDTest extends Scope $transactionId = $transaction['body']['$id']; // Stage operations with valid and invalid data (embedding length mismatch) - $response = $this->client->call(Client::METHOD_POST, "/vectordb/transactions/{$transactionId}/operations", array_merge([ + $response = $this->client->call(Client::METHOD_POST, "/vectorsdb/transactions/{$transactionId}/operations", array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -223,7 +223,7 @@ class VectorDBACIDTest extends Scope $this->assertEquals(201, $response['headers']['status-code']); // Attempt to commit - should fail due to invalid embeddings - $response = $this->client->call(Client::METHOD_PATCH, "/vectordb/transactions/{$transactionId}", array_merge([ + $response = $this->client->call(Client::METHOD_PATCH, "/vectorsdb/transactions/{$transactionId}", array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -234,7 +234,7 @@ class VectorDBACIDTest extends Scope $this->assertContains($response['headers']['status-code'], [400, 409, 500], 'Transaction commit should fail due to validation. Response: ' . json_encode($response['body'])); // Verify no documents were created - $documents = $this->client->call(Client::METHOD_GET, "/vectordb/{$databaseId}/collections/{$collectionId}/documents", array_merge([ + $documents = $this->client->call(Client::METHOD_GET, "/vectorsdb/{$databaseId}/collections/{$collectionId}/documents", array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders())); @@ -248,7 +248,7 @@ class VectorDBACIDTest extends Scope public function testIsolation(): void { // Create database - $database = $this->client->call(Client::METHOD_POST, '/vectordb', array_merge([ + $database = $this->client->call(Client::METHOD_POST, '/vectorsdb', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -261,7 +261,7 @@ class VectorDBACIDTest extends Scope $databaseId = $database['body']['$id']; // Create collection - $collection = $this->client->call(Client::METHOD_POST, '/vectordb/' . $databaseId . '/collections', array_merge([ + $collection = $this->client->call(Client::METHOD_POST, '/vectorsdb/' . $databaseId . '/collections', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -280,7 +280,7 @@ class VectorDBACIDTest extends Scope $collectionId = $collection['body']['$id']; // Create initial document with status metadata - $doc = $this->client->call(Client::METHOD_POST, "/vectordb/{$databaseId}/collections/{$collectionId}/documents", array_merge([ + $doc = $this->client->call(Client::METHOD_POST, "/vectorsdb/{$databaseId}/collections/{$collectionId}/documents", array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders()), [ @@ -294,7 +294,7 @@ class VectorDBACIDTest extends Scope $this->assertEquals(201, $doc['headers']['status-code']); // Create first transaction - $transaction1 = $this->client->call(Client::METHOD_POST, '/vectordb/transactions', array_merge([ + $transaction1 = $this->client->call(Client::METHOD_POST, '/vectorsdb/transactions', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -305,7 +305,7 @@ class VectorDBACIDTest extends Scope $transactionId1 = $transaction1['body']['$id']; // Transaction 1: update status to approved - $this->client->call(Client::METHOD_POST, "/vectordb/transactions/{$transactionId1}/operations", array_merge([ + $this->client->call(Client::METHOD_POST, "/vectorsdb/transactions/{$transactionId1}/operations", array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -324,7 +324,7 @@ class VectorDBACIDTest extends Scope ]); // Commit first transaction - $response1 = $this->client->call(Client::METHOD_PATCH, "/vectordb/transactions/{$transactionId1}", array_merge([ + $response1 = $this->client->call(Client::METHOD_PATCH, "/vectorsdb/transactions/{$transactionId1}", array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -334,14 +334,14 @@ class VectorDBACIDTest extends Scope $this->assertEquals(200, $response1['headers']['status-code']); // Document should reflect the first transaction's update - $document = $this->client->call(Client::METHOD_GET, "/vectordb/{$databaseId}/collections/{$collectionId}/documents/shared_doc", array_merge([ + $document = $this->client->call(Client::METHOD_GET, "/vectorsdb/{$databaseId}/collections/{$collectionId}/documents/shared_doc", array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders())); $this->assertEquals('approved', $document['body']['metadata']['status']); // Create second transaction after first commit - $transaction2 = $this->client->call(Client::METHOD_POST, '/vectordb/transactions', array_merge([ + $transaction2 = $this->client->call(Client::METHOD_POST, '/vectorsdb/transactions', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -352,7 +352,7 @@ class VectorDBACIDTest extends Scope $transactionId2 = $transaction2['body']['$id']; // Transaction 2: update status to declined - $this->client->call(Client::METHOD_POST, "/vectordb/transactions/{$transactionId2}/operations", array_merge([ + $this->client->call(Client::METHOD_POST, "/vectorsdb/transactions/{$transactionId2}/operations", array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -371,7 +371,7 @@ class VectorDBACIDTest extends Scope ]); // Commit second transaction and ensure isolation guarantees - $response2 = $this->client->call(Client::METHOD_PATCH, "/vectordb/transactions/{$transactionId2}", array_merge([ + $response2 = $this->client->call(Client::METHOD_PATCH, "/vectorsdb/transactions/{$transactionId2}", array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -382,7 +382,7 @@ class VectorDBACIDTest extends Scope $this->assertEquals(200, $response2['headers']['status-code']); // Final document should reflect the second transaction's update - $document = $this->client->call(Client::METHOD_GET, "/vectordb/{$databaseId}/collections/{$collectionId}/documents/shared_doc", array_merge([ + $document = $this->client->call(Client::METHOD_GET, "/vectorsdb/{$databaseId}/collections/{$collectionId}/documents/shared_doc", array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders())); @@ -396,7 +396,7 @@ class VectorDBACIDTest extends Scope public function testDurability(): void { // Create database - $database = $this->client->call(Client::METHOD_POST, '/vectordb', array_merge([ + $database = $this->client->call(Client::METHOD_POST, '/vectorsdb', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -409,7 +409,7 @@ class VectorDBACIDTest extends Scope $databaseId = $database['body']['$id']; // Create collection - $collection = $this->client->call(Client::METHOD_POST, '/vectordb/' . $databaseId . '/collections', array_merge([ + $collection = $this->client->call(Client::METHOD_POST, '/vectorsdb/' . $databaseId . '/collections', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -430,7 +430,7 @@ class VectorDBACIDTest extends Scope $collectionId = $collection['body']['$id']; // Create transaction with multiple operations - $transaction = $this->client->call(Client::METHOD_POST, '/vectordb/transactions', array_merge([ + $transaction = $this->client->call(Client::METHOD_POST, '/vectorsdb/transactions', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -441,7 +441,7 @@ class VectorDBACIDTest extends Scope $transactionId = $transaction['body']['$id']; // Create two documents via normal route inside transaction - $this->client->call(Client::METHOD_POST, "/vectordb/{$databaseId}/collections/{$collectionId}/documents", array_merge([ + $this->client->call(Client::METHOD_POST, "/vectorsdb/{$databaseId}/collections/{$collectionId}/documents", array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -462,7 +462,7 @@ class VectorDBACIDTest extends Scope ]); // Update first document inside the same transaction - $this->client->call(Client::METHOD_PATCH, "/vectordb/{$databaseId}/collections/{$collectionId}/documents/durable_doc_1", array_merge([ + $this->client->call(Client::METHOD_PATCH, "/vectorsdb/{$databaseId}/collections/{$collectionId}/documents/durable_doc_1", array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -474,7 +474,7 @@ class VectorDBACIDTest extends Scope ]); // Commit transaction - $response = $this->client->call(Client::METHOD_PATCH, "/vectordb/transactions/{$transactionId}", array_merge([ + $response = $this->client->call(Client::METHOD_PATCH, "/vectorsdb/transactions/{$transactionId}", array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -486,14 +486,14 @@ class VectorDBACIDTest extends Scope $this->assertEquals('committed', $response['body']['status']); // Verify documents exist and have correct data - $document1 = $this->client->call(Client::METHOD_GET, "/vectordb/{$databaseId}/collections/{$collectionId}/documents/durable_doc_1", array_merge([ + $document1 = $this->client->call(Client::METHOD_GET, "/vectorsdb/{$databaseId}/collections/{$collectionId}/documents/durable_doc_1", array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders())); $this->assertEquals(200, $document1['headers']['status-code']); $this->assertEquals('Updated important data 1', $document1['body']['metadata']['data']); - $document2 = $this->client->call(Client::METHOD_GET, "/vectordb/{$databaseId}/collections/{$collectionId}/documents/durable_doc_2", array_merge([ + $document2 = $this->client->call(Client::METHOD_GET, "/vectorsdb/{$databaseId}/collections/{$collectionId}/documents/durable_doc_2", array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders())); @@ -501,7 +501,7 @@ class VectorDBACIDTest extends Scope $this->assertEquals('Important data 2', $document2['body']['metadata']['data']); // Further update outside transaction to ensure persistence - $update = $this->client->call(Client::METHOD_PATCH, "/vectordb/{$databaseId}/collections/{$collectionId}/documents/durable_doc_1", array_merge([ + $update = $this->client->call(Client::METHOD_PATCH, "/vectorsdb/{$databaseId}/collections/{$collectionId}/documents/durable_doc_1", array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders()), [ @@ -512,14 +512,14 @@ class VectorDBACIDTest extends Scope $this->assertEquals(200, $update['headers']['status-code']); // Verify the update persisted - $document1 = $this->client->call(Client::METHOD_GET, "/vectordb/{$databaseId}/collections/{$collectionId}/documents/durable_doc_1", array_merge([ + $document1 = $this->client->call(Client::METHOD_GET, "/vectorsdb/{$databaseId}/collections/{$collectionId}/documents/durable_doc_1", array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders())); $this->assertEquals('Modified outside transaction', $document1['body']['metadata']['data']); // List all documents to verify total count - $documents = $this->client->call(Client::METHOD_GET, "/vectordb/{$databaseId}/collections/{$collectionId}/documents", array_merge([ + $documents = $this->client->call(Client::METHOD_GET, "/vectorsdb/{$databaseId}/collections/{$collectionId}/documents", array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders())); diff --git a/tests/e2e/Services/Databases/Transactions/VectorDBTransactionsConsoleClientTest.php b/tests/e2e/Services/Databases/Transactions/VectorsDBTransactionsConsoleClientTest.php similarity index 63% rename from tests/e2e/Services/Databases/Transactions/VectorDBTransactionsConsoleClientTest.php rename to tests/e2e/Services/Databases/Transactions/VectorsDBTransactionsConsoleClientTest.php index 7cb28b2f74..f6f217ab69 100644 --- a/tests/e2e/Services/Databases/Transactions/VectorDBTransactionsConsoleClientTest.php +++ b/tests/e2e/Services/Databases/Transactions/VectorsDBTransactionsConsoleClientTest.php @@ -5,9 +5,9 @@ namespace Tests\E2E\Services\Databases\Transactions; use Tests\E2E\Scopes\ProjectCustom; use Tests\E2E\Scopes\Scope; use Tests\E2E\Scopes\SideConsole; -use Tests\E2E\Services\Databases\VectorDB\Transactions\TransactionsBase; +use Tests\E2E\Services\Databases\VectorsDB\Transactions\TransactionsBase; -class VectorDBTransactionsConsoleClientTest extends Scope +class VectorsDBTransactionsConsoleClientTest extends Scope { use TransactionsBase; use ProjectCustom; diff --git a/tests/e2e/Services/Databases/Transactions/VectorDBTransactionsCustomClientTest.php b/tests/e2e/Services/Databases/Transactions/VectorsDBTransactionsCustomClientTest.php similarity index 63% rename from tests/e2e/Services/Databases/Transactions/VectorDBTransactionsCustomClientTest.php rename to tests/e2e/Services/Databases/Transactions/VectorsDBTransactionsCustomClientTest.php index 238cf9aea0..6dcfdf9f3e 100644 --- a/tests/e2e/Services/Databases/Transactions/VectorDBTransactionsCustomClientTest.php +++ b/tests/e2e/Services/Databases/Transactions/VectorsDBTransactionsCustomClientTest.php @@ -5,9 +5,9 @@ namespace Tests\E2E\Services\Databases\Transactions; use Tests\E2E\Scopes\ProjectCustom; use Tests\E2E\Scopes\Scope; use Tests\E2E\Scopes\SideClient; -use Tests\E2E\Services\Databases\VectorDB\Transactions\TransactionsBase; +use Tests\E2E\Services\Databases\VectorsDB\Transactions\TransactionsBase; -class VectorDBTransactionsCustomClientTest extends Scope +class VectorsDBTransactionsCustomClientTest extends Scope { use TransactionsBase; use ProjectCustom; diff --git a/tests/e2e/Services/Databases/Transactions/VectorDBTransactionsCustomServerTest.php b/tests/e2e/Services/Databases/Transactions/VectorsDBTransactionsCustomServerTest.php similarity index 63% rename from tests/e2e/Services/Databases/Transactions/VectorDBTransactionsCustomServerTest.php rename to tests/e2e/Services/Databases/Transactions/VectorsDBTransactionsCustomServerTest.php index 5cc23ef3d5..44f1ba36e1 100644 --- a/tests/e2e/Services/Databases/Transactions/VectorDBTransactionsCustomServerTest.php +++ b/tests/e2e/Services/Databases/Transactions/VectorsDBTransactionsCustomServerTest.php @@ -5,9 +5,9 @@ namespace Tests\E2E\Services\Databases\Transactions; use Tests\E2E\Scopes\ProjectCustom; use Tests\E2E\Scopes\Scope; use Tests\E2E\Scopes\SideServer; -use Tests\E2E\Services\Databases\VectorDB\Transactions\TransactionsBase; +use Tests\E2E\Services\Databases\VectorsDB\Transactions\TransactionsBase; -class VectorDBTransactionsCustomServerTest extends Scope +class VectorsDBTransactionsCustomServerTest extends Scope { use TransactionsBase; use ProjectCustom; diff --git a/tests/e2e/Services/Databases/VectorDB/DatabasesBase.php b/tests/e2e/Services/Databases/VectorsDB/DatabasesBase.php similarity index 90% rename from tests/e2e/Services/Databases/VectorDB/DatabasesBase.php rename to tests/e2e/Services/Databases/VectorsDB/DatabasesBase.php index 2276fc32bb..1bdc77085b 100644 --- a/tests/e2e/Services/Databases/VectorDB/DatabasesBase.php +++ b/tests/e2e/Services/Databases/VectorsDB/DatabasesBase.php @@ -1,6 +1,6 @@ client->call(Client::METHOD_POST, '/vectordb', [ + $database = $this->client->call(Client::METHOD_POST, '/vectorsdb', [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -29,7 +29,7 @@ trait DatabasesBase $this->assertNotEmpty($database['body']['$id']); $this->assertEquals(201, $database['headers']['status-code']); $this->assertEquals('Test Database', $database['body']['name']); - $this->assertEquals('vectordb', $database['body']['type']); + $this->assertEquals('vectorsdb', $database['body']['type']); return ['databaseId' => $database['body']['$id']]; } @@ -44,7 +44,7 @@ trait DatabasesBase $vector = array_fill(0, 1536, 0.1); $vector[0] = 1.0; - $res = $this->client->call(Client::METHOD_POST, "/vectordb/{$databaseId}/collections/{$collectionId}/documents", [ + $res = $this->client->call(Client::METHOD_POST, "/vectorsdb/{$databaseId}/collections/{$collectionId}/documents", [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -74,7 +74,7 @@ trait DatabasesBase // Edge: invalid dimensions (vector too short) → expect 4xx $badVec = [1.0, 0.0]; - $bad = $this->client->call(Client::METHOD_POST, "/vectordb/{$databaseId}/collections/{$collectionId}/documents", [ + $bad = $this->client->call(Client::METHOD_POST, "/vectorsdb/{$databaseId}/collections/{$collectionId}/documents", [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -90,7 +90,7 @@ trait DatabasesBase // Edge: invalid type values (strings) → expect 4xx $strVec = ['1.0', '0.0', '0.0']; - $bad2 = $this->client->call(Client::METHOD_POST, "/vectordb/{$databaseId}/collections/{$collectionId}/documents", [ + $bad2 = $this->client->call(Client::METHOD_POST, "/vectorsdb/{$databaseId}/collections/{$collectionId}/documents", [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -105,7 +105,7 @@ trait DatabasesBase $this->assertLessThan(500, $bad2['headers']['status-code']); // Create another valid doc to verify list totals later - $res2 = $this->client->call(Client::METHOD_POST, "/vectordb/{$databaseId}/collections/{$collectionId}/documents", [ + $res2 = $this->client->call(Client::METHOD_POST, "/vectorsdb/{$databaseId}/collections/{$collectionId}/documents", [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -137,7 +137,7 @@ trait DatabasesBase $collectionId = $data['collectionId']; $documentId = $data['documentId']; - $res = $this->client->call(Client::METHOD_GET, "/vectordb/{$databaseId}/collections/{$collectionId}/documents/{$documentId}", [ + $res = $this->client->call(Client::METHOD_GET, "/vectorsdb/{$databaseId}/collections/{$collectionId}/documents/{$documentId}", [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -147,7 +147,7 @@ trait DatabasesBase $this->assertEquals($documentId, $res['body']['$id']); // Edge: missing document should return 404 - $missing = $this->client->call(Client::METHOD_GET, "/vectordb/{$databaseId}/collections/{$collectionId}/documents/" . ID::unique(), [ + $missing = $this->client->call(Client::METHOD_GET, "/vectorsdb/{$databaseId}/collections/{$collectionId}/documents/" . ID::unique(), [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -163,7 +163,7 @@ trait DatabasesBase $databaseId = $data['databaseId']; $collectionId = $data['collectionId']; - $list = $this->client->call(Client::METHOD_GET, "/vectordb/{$databaseId}/collections/{$collectionId}/documents", [ + $list = $this->client->call(Client::METHOD_GET, "/vectorsdb/{$databaseId}/collections/{$collectionId}/documents", [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -176,7 +176,7 @@ trait DatabasesBase $this->assertGreaterThanOrEqual(1, $list['body']['total']); // Pagination: limit 1, then offset 1 - $page1 = $this->client->call(Client::METHOD_GET, "/vectordb/{$databaseId}/collections/{$collectionId}/documents", [ + $page1 = $this->client->call(Client::METHOD_GET, "/vectorsdb/{$databaseId}/collections/{$collectionId}/documents", [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -189,7 +189,7 @@ trait DatabasesBase $this->assertEquals(200, $page1['headers']['status-code']); $this->assertEquals(1, \count($page1['body']['documents'] ?? [])); - $page2 = $this->client->call(Client::METHOD_GET, "/vectordb/{$databaseId}/collections/{$collectionId}/documents", [ + $page2 = $this->client->call(Client::METHOD_GET, "/vectorsdb/{$databaseId}/collections/{$collectionId}/documents", [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -216,7 +216,7 @@ trait DatabasesBase $vector = array_fill(0, 1536, 0.0); // $vector[1] = 1.0; - $upd = $this->client->call(Client::METHOD_PUT, "/vectordb/{$databaseId}/collections/{$collectionId}/documents/{$documentId}", [ + $upd = $this->client->call(Client::METHOD_PUT, "/vectorsdb/{$databaseId}/collections/{$collectionId}/documents/{$documentId}", [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -230,7 +230,7 @@ trait DatabasesBase $this->assertEquals(200, $upd['headers']['status-code']); // Verify update took effect - $get = $this->client->call(Client::METHOD_GET, "/vectordb/{$databaseId}/collections/{$collectionId}/documents/{$documentId}", [ + $get = $this->client->call(Client::METHOD_GET, "/vectorsdb/{$databaseId}/collections/{$collectionId}/documents/{$documentId}", [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -254,7 +254,7 @@ trait DatabasesBase $vector = array_fill(0, 1536, 0.0); $vector[2] = 1.0; - $upd = $this->client->call(Client::METHOD_PUT, "/vectordb/{$databaseId}/collections/{$collectionId}/documents/{$documentId}", [ + $upd = $this->client->call(Client::METHOD_PUT, "/vectorsdb/{$databaseId}/collections/{$collectionId}/documents/{$documentId}", [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -270,7 +270,7 @@ trait DatabasesBase // Re-update to check idempotence and metadata replacement $vector2 = array_fill(0, 1536, 0.0); $vector2[3] = 1.0; - $upd2 = $this->client->call(Client::METHOD_PUT, "/vectordb/{$databaseId}/collections/{$collectionId}/documents/{$documentId}", [ + $upd2 = $this->client->call(Client::METHOD_PUT, "/vectorsdb/{$databaseId}/collections/{$collectionId}/documents/{$documentId}", [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -283,7 +283,7 @@ trait DatabasesBase $this->assertEquals(200, $upd2['headers']['status-code']); // Verify updatedAt changed again - $get2 = $this->client->call(Client::METHOD_GET, "/vectordb/{$databaseId}/collections/{$collectionId}/documents/{$documentId}", [ + $get2 = $this->client->call(Client::METHOD_GET, "/vectorsdb/{$databaseId}/collections/{$collectionId}/documents/{$documentId}", [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -302,7 +302,7 @@ trait DatabasesBase // Create two more documents with distinct embeddings $mk = function (array $vec, string $name) use ($databaseId, $collectionId) { - $this->client->call(Client::METHOD_POST, "/vectordb/{$databaseId}/collections/{$collectionId}/documents", [ + $this->client->call(Client::METHOD_POST, "/vectorsdb/{$databaseId}/collections/{$collectionId}/documents", [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -325,7 +325,7 @@ trait DatabasesBase $mk($vB, 'B'); // Dot product - $dot = $this->client->call(Client::METHOD_GET, "/vectordb/{$databaseId}/collections/{$collectionId}/documents", [ + $dot = $this->client->call(Client::METHOD_GET, "/vectorsdb/{$databaseId}/collections/{$collectionId}/documents", [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -339,7 +339,7 @@ trait DatabasesBase $this->assertGreaterThanOrEqual(1, $dot['body']['total']); // Cosine - $cos = $this->client->call(Client::METHOD_GET, "/vectordb/{$databaseId}/collections/{$collectionId}/documents", [ + $cos = $this->client->call(Client::METHOD_GET, "/vectorsdb/{$databaseId}/collections/{$collectionId}/documents", [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -353,7 +353,7 @@ trait DatabasesBase $this->assertGreaterThanOrEqual(1, $cos['body']['total']); // Euclidean - $eu = $this->client->call(Client::METHOD_GET, "/vectordb/{$databaseId}/collections/{$collectionId}/documents", [ + $eu = $this->client->call(Client::METHOD_GET, "/vectorsdb/{$databaseId}/collections/{$collectionId}/documents", [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -367,7 +367,7 @@ trait DatabasesBase $this->assertGreaterThanOrEqual(1, $eu['body']['total']); // Combined vector + metadata filters - $combo = $this->client->call(Client::METHOD_GET, "/vectordb/{$databaseId}/collections/{$collectionId}/documents", [ + $combo = $this->client->call(Client::METHOD_GET, "/vectorsdb/{$databaseId}/collections/{$collectionId}/documents", [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -382,7 +382,7 @@ trait DatabasesBase $this->assertGreaterThanOrEqual(1, $combo['body']['total']); // Ordering with $id ascending combined with vector - $ordered = $this->client->call(Client::METHOD_GET, "/vectordb/{$databaseId}/collections/{$collectionId}/documents", [ + $ordered = $this->client->call(Client::METHOD_GET, "/vectorsdb/{$databaseId}/collections/{$collectionId}/documents", [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -405,7 +405,7 @@ trait DatabasesBase $collectionId = $data['collectionId']; $documentId = $data['documentId']; - $del = $this->client->call(Client::METHOD_DELETE, "/vectordb/{$databaseId}/collections/{$collectionId}/documents/{$documentId}", [ + $del = $this->client->call(Client::METHOD_DELETE, "/vectorsdb/{$databaseId}/collections/{$collectionId}/documents/{$documentId}", [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -413,7 +413,7 @@ trait DatabasesBase $this->assertEquals(204, $del['headers']['status-code']); // GET after delete should be 404 - $getMissing = $this->client->call(Client::METHOD_GET, "/vectordb/{$databaseId}/collections/{$collectionId}/documents/{$documentId}", [ + $getMissing = $this->client->call(Client::METHOD_GET, "/vectorsdb/{$databaseId}/collections/{$collectionId}/documents/{$documentId}", [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -421,7 +421,7 @@ trait DatabasesBase $this->assertEquals(404, $getMissing['headers']['status-code']); // List should still work and reflect at least one less document compared to earlier pages (best-effort) - $list = $this->client->call(Client::METHOD_GET, "/vectordb/{$databaseId}/collections/{$collectionId}/documents", [ + $list = $this->client->call(Client::METHOD_GET, "/vectorsdb/{$databaseId}/collections/{$collectionId}/documents", [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -441,7 +441,7 @@ trait DatabasesBase $docId = ID::unique(); $vector = array_fill(0, 1536, 0.0); $vector[0] = 1.0; - $create = $this->client->call(Client::METHOD_POST, "/vectordb/{$databaseId}/collections/{$collectionId}/documents", [ + $create = $this->client->call(Client::METHOD_POST, "/vectorsdb/{$databaseId}/collections/{$collectionId}/documents", [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -457,14 +457,14 @@ trait DatabasesBase ]); $this->assertEquals(201, $create['headers']['status-code']); - $guest = $this->client->call(Client::METHOD_GET, "/vectordb/{$databaseId}/collections/{$collectionId}/documents/{$docId}", [ + $guest = $this->client->call(Client::METHOD_GET, "/vectorsdb/{$databaseId}/collections/{$collectionId}/documents/{$docId}", [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'] ]); $this->assertEquals(404, $guest['headers']['status-code']); // GET with key should succeed regardless of document user-level permission - $withKey = $this->client->call(Client::METHOD_GET, "/vectordb/{$databaseId}/collections/{$collectionId}/documents/{$docId}", [ + $withKey = $this->client->call(Client::METHOD_GET, "/vectorsdb/{$databaseId}/collections/{$collectionId}/documents/{$docId}", [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -479,7 +479,7 @@ trait DatabasesBase /** * Test for SUCCESS */ - $movies = $this->client->call(Client::METHOD_POST, '/vectordb/' . $databaseId . '/collections', array_merge([ + $movies = $this->client->call(Client::METHOD_POST, '/vectorsdb/' . $databaseId . '/collections', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -496,7 +496,7 @@ trait DatabasesBase $this->assertEquals(201, $movies['headers']['status-code']); $this->assertEquals($movies['body']['name'], 'Movies'); - $actors = $this->client->call(Client::METHOD_POST, '/vectordb/' . $databaseId . '/collections', array_merge([ + $actors = $this->client->call(Client::METHOD_POST, '/vectorsdb/' . $databaseId . '/collections', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -522,19 +522,19 @@ trait DatabasesBase public function testCreateDatabaseSample(): array { - $database = $this->client->call(Client::METHOD_POST, '/vectordb', [ + $database = $this->client->call(Client::METHOD_POST, '/vectorsdb', [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] ], [ 'databaseId' => ID::unique(), - 'name' => 'Sample VectorDB' + 'name' => 'Sample VectorsDB' ]); $this->assertNotEmpty($database['body']['$id']); $this->assertEquals(201, $database['headers']['status-code']); - $this->assertEquals('Sample VectorDB', $database['body']['name']); - $this->assertEquals('vectordb', $database['body']['type']); + $this->assertEquals('Sample VectorsDB', $database['body']['name']); + $this->assertEquals('vectorsdb', $database['body']['type']); return ['databaseId' => $database['body']['$id']]; } @@ -544,7 +544,7 @@ trait DatabasesBase { $databaseId = $data['databaseId']; - $collection = $this->client->call(Client::METHOD_POST, '/vectordb/' . $databaseId . '/collections', array_merge([ + $collection = $this->client->call(Client::METHOD_POST, '/vectorsdb/' . $databaseId . '/collections', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -578,7 +578,7 @@ trait DatabasesBase * Helper to create a database */ $createDatabase = function (string $name) use ($projectId, $apiKey) { - $db = $this->client->call(Client::METHOD_POST, '/vectordb', [ + $db = $this->client->call(Client::METHOD_POST, '/vectorsdb', [ 'content-type' => 'application/json', 'x-appwrite-project' => $projectId, 'x-appwrite-key' => $apiKey @@ -588,7 +588,7 @@ trait DatabasesBase ]); $this->assertEquals(201, $db['headers']['status-code']); - $this->assertEquals('vectordb', $db['body']['type']); + $this->assertEquals('vectorsdb', $db['body']['type']); $this->assertEquals($name, $db['body']['name']); $this->assertNotEmpty($db['body']['$id']); @@ -599,7 +599,7 @@ trait DatabasesBase * Helper to create a collection */ $createCollection = function (string $databaseId, string $name, int $dimensions = 1536) use ($projectId, $apiKey, $userId) { - $res = $this->client->call(Client::METHOD_POST, '/vectordb/' . $databaseId . '/collections', [ + $res = $this->client->call(Client::METHOD_POST, '/vectorsdb/' . $databaseId . '/collections', [ 'content-type' => 'application/json', 'x-appwrite-project' => $projectId, 'x-appwrite-key' => $apiKey @@ -665,7 +665,7 @@ trait DatabasesBase public function testInvalidCollectionDimensions(): void { // dimensions = 0 -> expect 4xx - $bad0 = $this->client->call(Client::METHOD_POST, '/vectordb', [ + $bad0 = $this->client->call(Client::METHOD_POST, '/vectorsdb', [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -675,7 +675,7 @@ trait DatabasesBase ]); $this->assertEquals(201, $bad0['headers']['status-code']); $dbId = $bad0['body']['$id']; - $col = $this->client->call(Client::METHOD_POST, '/vectordb/' . $dbId . '/collections', [ + $col = $this->client->call(Client::METHOD_POST, '/vectorsdb/' . $dbId . '/collections', [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -690,7 +690,7 @@ trait DatabasesBase $this->assertLessThan(500, $col['headers']['status-code']); // dimensions too large -> expect 4xx - $col2 = $this->client->call(Client::METHOD_POST, '/vectordb/' . $dbId . '/collections', [ + $col2 = $this->client->call(Client::METHOD_POST, '/vectorsdb/' . $dbId . '/collections', [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -707,7 +707,7 @@ trait DatabasesBase public function testSingleDimensionVectorCollection(): void { - $db = $this->client->call(Client::METHOD_POST, '/vectordb', [ + $db = $this->client->call(Client::METHOD_POST, '/vectorsdb', [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -718,7 +718,7 @@ trait DatabasesBase $this->assertEquals(201, $db['headers']['status-code']); $databaseId = $db['body']['$id']; - $col = $this->client->call(Client::METHOD_POST, '/vectordb/' . $databaseId . '/collections', [ + $col = $this->client->call(Client::METHOD_POST, '/vectorsdb/' . $databaseId . '/collections', [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -734,7 +734,7 @@ trait DatabasesBase // Create two docs with 1D embeddings $id1 = ID::unique(); - $this->client->call(Client::METHOD_PUT, "/vectordb/{$databaseId}/collections/{$collectionId}/documents/{$id1}", [ + $this->client->call(Client::METHOD_PUT, "/vectorsdb/{$databaseId}/collections/{$collectionId}/documents/{$id1}", [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -742,7 +742,7 @@ trait DatabasesBase 'data' => ['embeddings' => [1.0]] ]); $id2 = ID::unique(); - $this->client->call(Client::METHOD_PUT, "/vectordb/{$databaseId}/collections/{$collectionId}/documents/{$id2}", [ + $this->client->call(Client::METHOD_PUT, "/vectorsdb/{$databaseId}/collections/{$collectionId}/documents/{$id2}", [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -751,7 +751,7 @@ trait DatabasesBase ]); // Query with vectorCosine - $res = $this->client->call(Client::METHOD_GET, "/vectordb/{$databaseId}/collections/{$collectionId}/documents", [ + $res = $this->client->call(Client::METHOD_GET, "/vectorsdb/{$databaseId}/collections/{$collectionId}/documents", [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -764,7 +764,7 @@ trait DatabasesBase public function testVectorInvalidValues(): void { - $db = $this->client->call(Client::METHOD_POST, '/vectordb', [ + $db = $this->client->call(Client::METHOD_POST, '/vectorsdb', [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -775,7 +775,7 @@ trait DatabasesBase $this->assertEquals(201, $db['headers']['status-code']); $databaseId = $db['body']['$id']; - $col = $this->client->call(Client::METHOD_POST, '/vectordb/' . $databaseId . '/collections', [ + $col = $this->client->call(Client::METHOD_POST, '/vectorsdb/' . $databaseId . '/collections', [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -807,7 +807,7 @@ trait DatabasesBase ]; foreach ($badPayloads as $payload) { - $resp = $this->client->call(Client::METHOD_PUT, "/vectordb/{$databaseId}/collections/{$collectionId}/documents/" . ID::unique(), [ + $resp = $this->client->call(Client::METHOD_PUT, "/vectorsdb/{$databaseId}/collections/{$collectionId}/documents/" . ID::unique(), [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -821,7 +821,7 @@ trait DatabasesBase public function testVectorAllZerosAndQuery(): void { - $db = $this->client->call(Client::METHOD_POST, '/vectordb', [ + $db = $this->client->call(Client::METHOD_POST, '/vectorsdb', [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -832,7 +832,7 @@ trait DatabasesBase $this->assertEquals(201, $db['headers']['status-code']); $databaseId = $db['body']['$id']; - $col = $this->client->call(Client::METHOD_POST, '/vectordb/' . $databaseId . '/collections', [ + $col = $this->client->call(Client::METHOD_POST, '/vectorsdb/' . $databaseId . '/collections', [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -846,19 +846,19 @@ trait DatabasesBase $this->assertEquals(201, $col['headers']['status-code']); $collectionId = $col['body']['$id']; - $this->client->call(Client::METHOD_PUT, "/vectordb/{$databaseId}/collections/{$collectionId}/documents/" . ID::unique(), [ + $this->client->call(Client::METHOD_PUT, "/vectorsdb/{$databaseId}/collections/{$collectionId}/documents/" . ID::unique(), [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] ], [ 'data' => ['embeddings' => [0.0, 0.0, 0.0]] ]); - $this->client->call(Client::METHOD_PUT, "/vectordb/{$databaseId}/collections/{$collectionId}/documents/" . ID::unique(), [ + $this->client->call(Client::METHOD_PUT, "/vectorsdb/{$databaseId}/collections/{$collectionId}/documents/" . ID::unique(), [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] ], [ 'data' => ['embeddings' => [1.0, 0.0, 0.0]] ]); - $results = $this->client->call(Client::METHOD_GET, "/vectordb/{$databaseId}/collections/{$collectionId}/documents", [ + $results = $this->client->call(Client::METHOD_GET, "/vectorsdb/{$databaseId}/collections/{$collectionId}/documents", [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -870,14 +870,14 @@ trait DatabasesBase public function testVectorMultipleQueriesRejection(): void { // Create a simple DB and collection - $db = $this->client->call(Client::METHOD_POST, '/vectordb', [ + $db = $this->client->call(Client::METHOD_POST, '/vectorsdb', [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] ], [ 'databaseId' => ID::unique(), 'name' => 'MultiQueryDB' ]); $this->assertEquals(201, $db['headers']['status-code']); $databaseId = $db['body']['$id']; - $col = $this->client->call(Client::METHOD_POST, '/vectordb/' . $databaseId . '/collections', [ + $col = $this->client->call(Client::METHOD_POST, '/vectorsdb/' . $databaseId . '/collections', [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -886,7 +886,7 @@ trait DatabasesBase $collectionId = $col['body']['$id']; // Two vector queries simultaneously should fail - $fail = $this->client->call(Client::METHOD_GET, "/vectordb/{$databaseId}/collections/{$collectionId}/documents", [ + $fail = $this->client->call(Client::METHOD_GET, "/vectorsdb/{$databaseId}/collections/{$collectionId}/documents", [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -902,14 +902,14 @@ trait DatabasesBase public function testVectorQueryOnNonVectorAttribute(): void { - $db = $this->client->call(Client::METHOD_POST, '/vectordb', [ + $db = $this->client->call(Client::METHOD_POST, '/vectorsdb', [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] ], [ 'databaseId' => ID::unique(), 'name' => 'NonVec' ]); $this->assertEquals(201, $db['headers']['status-code']); $databaseId = $db['body']['$id']; - $col = $this->client->call(Client::METHOD_POST, '/vectordb/' . $databaseId . '/collections', [ + $col = $this->client->call(Client::METHOD_POST, '/vectorsdb/' . $databaseId . '/collections', [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -918,7 +918,7 @@ trait DatabasesBase $collectionId = $col['body']['$id']; // Query on non-vector attribute 'metadata' should fail - $fail = $this->client->call(Client::METHOD_GET, "/vectordb/{$databaseId}/collections/{$collectionId}/documents", [ + $fail = $this->client->call(Client::METHOD_GET, "/vectorsdb/{$databaseId}/collections/{$collectionId}/documents", [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -929,14 +929,14 @@ trait DatabasesBase public function testVectorEmptyQueryCollection(): void { - $db = $this->client->call(Client::METHOD_POST, '/vectordb', [ + $db = $this->client->call(Client::METHOD_POST, '/vectorsdb', [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] ], [ 'databaseId' => ID::unique(), 'name' => 'EmptyQ' ]); $this->assertEquals(201, $db['headers']['status-code']); $databaseId = $db['body']['$id']; - $col = $this->client->call(Client::METHOD_POST, '/vectordb/' . $databaseId . '/collections', [ + $col = $this->client->call(Client::METHOD_POST, '/vectorsdb/' . $databaseId . '/collections', [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -944,7 +944,7 @@ trait DatabasesBase $this->assertEquals(201, $col['headers']['status-code']); $collectionId = $col['body']['$id']; - $res = $this->client->call(Client::METHOD_GET, "/vectordb/{$databaseId}/collections/{$collectionId}/documents", [ + $res = $this->client->call(Client::METHOD_GET, "/vectorsdb/{$databaseId}/collections/{$collectionId}/documents", [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -960,7 +960,7 @@ trait DatabasesBase $collectionId = $data['moviesId']; // HNSW Euclidean - $idxEuclidean = $this->client->call(Client::METHOD_POST, "/vectordb/{$databaseId}/collections/{$collectionId}/indexes", [ + $idxEuclidean = $this->client->call(Client::METHOD_POST, "/vectorsdb/{$databaseId}/collections/{$collectionId}/indexes", [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -972,7 +972,7 @@ trait DatabasesBase $this->assertEquals(202, $idxEuclidean['headers']['status-code']); // HNSW Dot (Inner Product) - $idxDot = $this->client->call(Client::METHOD_POST, "/vectordb/{$databaseId}/collections/{$collectionId}/indexes", [ + $idxDot = $this->client->call(Client::METHOD_POST, "/vectorsdb/{$databaseId}/collections/{$collectionId}/indexes", [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -984,7 +984,7 @@ trait DatabasesBase $this->assertEquals(202, $idxDot['headers']['status-code']); // HNSW Cosine - $idxCosine = $this->client->call(Client::METHOD_POST, "/vectordb/{$databaseId}/collections/{$collectionId}/indexes", [ + $idxCosine = $this->client->call(Client::METHOD_POST, "/vectorsdb/{$databaseId}/collections/{$collectionId}/indexes", [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -1008,7 +1008,7 @@ trait DatabasesBase $databaseId = $data['databaseId']; $collectionId = $data['collectionId']; - $list = $this->client->call(Client::METHOD_GET, "/vectordb/{$databaseId}/collections/{$collectionId}/indexes", [ + $list = $this->client->call(Client::METHOD_GET, "/vectorsdb/{$databaseId}/collections/{$collectionId}/indexes", [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -1034,7 +1034,7 @@ trait DatabasesBase ]; foreach ($keysToTypes as $key => $type) { - $res = $this->client->call(Client::METHOD_GET, "/vectordb/{$databaseId}/collections/{$collectionId}/indexes/{$key}", [ + $res = $this->client->call(Client::METHOD_GET, "/vectorsdb/{$databaseId}/collections/{$collectionId}/indexes/{$key}", [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] diff --git a/tests/e2e/Services/Databases/VectorDB/DatabasesConsoleClientTest.php b/tests/e2e/Services/Databases/VectorsDB/DatabasesConsoleClientTest.php similarity index 89% rename from tests/e2e/Services/Databases/VectorDB/DatabasesConsoleClientTest.php rename to tests/e2e/Services/Databases/VectorsDB/DatabasesConsoleClientTest.php index c585a7930b..abe4d4968b 100644 --- a/tests/e2e/Services/Databases/VectorDB/DatabasesConsoleClientTest.php +++ b/tests/e2e/Services/Databases/VectorsDB/DatabasesConsoleClientTest.php @@ -1,6 +1,6 @@ client->call(Client::METHOD_POST, '/vectordb', array_merge([ + $database = $this->client->call(Client::METHOD_POST, '/vectorsdb', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders()), [ @@ -35,7 +35,7 @@ class DatabasesConsoleClientTest extends Scope /** * Test for SUCCESS */ - $movies = $this->client->call(Client::METHOD_POST, '/vectordb/' . $databaseId . '/collections', array_merge([ + $movies = $this->client->call(Client::METHOD_POST, '/vectorsdb/' . $databaseId . '/collections', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders()), [ @@ -57,7 +57,7 @@ class DatabasesConsoleClientTest extends Scope /** * Test when database is disabled but can still create collections */ - $database = $this->client->call(Client::METHOD_PUT, '/vectordb/' . $databaseId, array_merge([ + $database = $this->client->call(Client::METHOD_PUT, '/vectorsdb/' . $databaseId, array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders()), [ @@ -67,7 +67,7 @@ class DatabasesConsoleClientTest extends Scope $this->assertFalse($database['body']['enabled']); - $tvShows = $this->client->call(Client::METHOD_POST, '/vectordb/' . $databaseId . '/collections', array_merge([ + $tvShows = $this->client->call(Client::METHOD_POST, '/vectorsdb/' . $databaseId . '/collections', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders()), [ @@ -86,7 +86,7 @@ class DatabasesConsoleClientTest extends Scope /** * Test when collection is disabled but can still modify collections */ - $database = $this->client->call(Client::METHOD_PUT, '/vectordb/' . $databaseId . '/collections/' . $movies['body']['$id'], array_merge([ + $database = $this->client->call(Client::METHOD_PUT, '/vectorsdb/' . $databaseId . '/collections/' . $movies['body']['$id'], array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders()), [ @@ -108,7 +108,7 @@ class DatabasesConsoleClientTest extends Scope */ $databaseId = $data['databaseId']; - $collections = $this->client->call(Client::METHOD_GET, '/vectordb/' . $databaseId . '/collections', array_merge([ + $collections = $this->client->call(Client::METHOD_GET, '/vectorsdb/' . $databaseId . '/collections', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'] ], $this->getHeaders())); @@ -126,7 +126,7 @@ class DatabasesConsoleClientTest extends Scope /** * Test when database and collection are disabled but can still call get collection */ - $collection = $this->client->call(Client::METHOD_GET, '/vectordb/' . $databaseId . '/collections/' . $moviesCollectionId, array_merge([ + $collection = $this->client->call(Client::METHOD_GET, '/vectorsdb/' . $databaseId . '/collections/' . $moviesCollectionId, array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders())); @@ -146,7 +146,7 @@ class DatabasesConsoleClientTest extends Scope /** * Test When database and collection are disabled but can still call update collection */ - $collection = $this->client->call(Client::METHOD_PUT, '/vectordb/' . $databaseId . '/collections/' . $moviesCollectionId, array_merge([ + $collection = $this->client->call(Client::METHOD_PUT, '/vectorsdb/' . $databaseId . '/collections/' . $moviesCollectionId, array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders()), [ @@ -169,7 +169,7 @@ class DatabasesConsoleClientTest extends Scope /** * Test when database and collection are disabled but can still call delete collection */ - $response = $this->client->call(Client::METHOD_DELETE, '/vectordb/' . $databaseId . '/collections/' . $tvShowsId, array_merge([ + $response = $this->client->call(Client::METHOD_DELETE, '/vectorsdb/' . $databaseId . '/collections/' . $tvShowsId, array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders())); @@ -186,7 +186,7 @@ class DatabasesConsoleClientTest extends Scope * Test for FAILURE */ - $response = $this->client->call(Client::METHOD_GET, '/vectordb/' . $databaseId . '/usage', array_merge([ + $response = $this->client->call(Client::METHOD_GET, '/vectorsdb/' . $databaseId . '/usage', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'] ], $this->getHeaders()), [ @@ -199,7 +199,7 @@ class DatabasesConsoleClientTest extends Scope * Test for SUCCESS */ - $response = $this->client->call(Client::METHOD_GET, '/vectordb/' . $databaseId . '/usage', array_merge([ + $response = $this->client->call(Client::METHOD_GET, '/vectorsdb/' . $databaseId . '/usage', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'] ], $this->getHeaders()), [ @@ -224,7 +224,7 @@ class DatabasesConsoleClientTest extends Scope * Test for FAILURE */ - $response = $this->client->call(Client::METHOD_GET, '/vectordb/' . $databaseId . '/collections/' . $data['moviesId'] . '/usage', array_merge([ + $response = $this->client->call(Client::METHOD_GET, '/vectorsdb/' . $databaseId . '/collections/' . $data['moviesId'] . '/usage', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'] ], $this->getHeaders()), [ @@ -233,7 +233,7 @@ class DatabasesConsoleClientTest extends Scope $this->assertEquals(400, $response['headers']['status-code']); - $response = $this->client->call(Client::METHOD_GET, '/vectordb/' . $databaseId . '/collections/randomCollectionId/usage', array_merge([ + $response = $this->client->call(Client::METHOD_GET, '/vectorsdb/' . $databaseId . '/collections/randomCollectionId/usage', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'] ], $this->getHeaders()), [ @@ -245,7 +245,7 @@ class DatabasesConsoleClientTest extends Scope /** * Test for SUCCESS */ - $response = $this->client->call(Client::METHOD_GET, '/vectordb/' . $databaseId . '/collections/' . $data['moviesId'] . '/usage', array_merge([ + $response = $this->client->call(Client::METHOD_GET, '/vectorsdb/' . $databaseId . '/collections/' . $data['moviesId'] . '/usage', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'] ], $this->getHeaders()), [ @@ -265,7 +265,7 @@ class DatabasesConsoleClientTest extends Scope /** * Test for SUCCESS */ - $logs = $this->client->call(Client::METHOD_GET, '/vectordb/' . $databaseId . '/collections/' . $data['moviesId'] . '/logs', array_merge([ + $logs = $this->client->call(Client::METHOD_GET, '/vectorsdb/' . $databaseId . '/collections/' . $data['moviesId'] . '/logs', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders())); @@ -274,7 +274,7 @@ class DatabasesConsoleClientTest extends Scope $this->assertIsArray($logs['body']['logs']); $this->assertIsNumeric($logs['body']['total']); - $logs = $this->client->call(Client::METHOD_GET, '/vectordb/' . $databaseId . '/collections/' . $data['moviesId'] . '/logs', array_merge([ + $logs = $this->client->call(Client::METHOD_GET, '/vectorsdb/' . $databaseId . '/collections/' . $data['moviesId'] . '/logs', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders()), [ @@ -286,7 +286,7 @@ class DatabasesConsoleClientTest extends Scope $this->assertLessThanOrEqual(1, count($logs['body']['logs'])); $this->assertIsNumeric($logs['body']['total']); - $logs = $this->client->call(Client::METHOD_GET, '/vectordb/' . $databaseId . '/collections/' . $data['moviesId'] . '/logs', array_merge([ + $logs = $this->client->call(Client::METHOD_GET, '/vectorsdb/' . $databaseId . '/collections/' . $data['moviesId'] . '/logs', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders()), [ @@ -297,7 +297,7 @@ class DatabasesConsoleClientTest extends Scope $this->assertIsArray($logs['body']['logs']); $this->assertIsNumeric($logs['body']['total']); - $logs = $this->client->call(Client::METHOD_GET, '/vectordb/' . $databaseId . '/collections/' . $data['moviesId'] . '/logs', array_merge([ + $logs = $this->client->call(Client::METHOD_GET, '/vectorsdb/' . $databaseId . '/collections/' . $data['moviesId'] . '/logs', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders()), [ diff --git a/tests/e2e/Services/Databases/VectorDB/DatabasesCustomClientTest.php b/tests/e2e/Services/Databases/VectorsDB/DatabasesCustomClientTest.php similarity index 89% rename from tests/e2e/Services/Databases/VectorDB/DatabasesCustomClientTest.php rename to tests/e2e/Services/Databases/VectorsDB/DatabasesCustomClientTest.php index cc99806848..b27cb420b4 100644 --- a/tests/e2e/Services/Databases/VectorDB/DatabasesCustomClientTest.php +++ b/tests/e2e/Services/Databases/VectorsDB/DatabasesCustomClientTest.php @@ -1,6 +1,6 @@ client->call(Client::METHOD_POST, '/vectordb', [ + $database = $this->client->call(Client::METHOD_POST, '/vectorsdb', [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -35,7 +35,7 @@ class DatabasesCustomClientTest extends Scope $databaseId = $database['body']['$id']; // Collection aliases write to create, update, delete - $movies = $this->client->call(Client::METHOD_POST, '/vectordb/' . $databaseId . '/collections', array_merge([ + $movies = $this->client->call(Client::METHOD_POST, '/vectorsdb/' . $databaseId . '/collections', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -55,10 +55,10 @@ class DatabasesCustomClientTest extends Scope $this->assertContains(Permission::update(Role::user($this->getUser()['$id'])), $movies['body']['$permissions']); $this->assertContains(Permission::delete(Role::user($this->getUser()['$id'])), $movies['body']['$permissions']); - // VectorDB uses fixed schema (embeddings, metadata). No attribute creation needed. + // VectorsDB uses fixed schema (embeddings, metadata). No attribute creation needed. // Document aliases write to update, delete - $document1 = $this->client->call(Client::METHOD_POST, '/vectordb/' . $databaseId . '/collections/' . $moviesId . '/documents', array_merge([ + $document1 = $this->client->call(Client::METHOD_POST, '/vectorsdb/' . $databaseId . '/collections/' . $moviesId . '/documents', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders()), [ @@ -81,7 +81,7 @@ class DatabasesCustomClientTest extends Scope */ // Document does not allow create permission - $document2 = $this->client->call(Client::METHOD_POST, '/vectordb/' . $databaseId . '/collections/' . $moviesId . '/documents', array_merge([ + $document2 = $this->client->call(Client::METHOD_POST, '/vectorsdb/' . $databaseId . '/collections/' . $moviesId . '/documents', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders()), [ @@ -109,7 +109,7 @@ class DatabasesCustomClientTest extends Scope $userId = $response['body']['$id']; - $database = $this->client->call(Client::METHOD_POST, '/vectordb', array_merge([ + $database = $this->client->call(Client::METHOD_POST, '/vectorsdb', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -122,7 +122,7 @@ class DatabasesCustomClientTest extends Scope $databaseId = $database['body']['$id']; // Create collection - $response = $this->client->call(Client::METHOD_POST, '/vectordb/' . $databaseId . '/collections', array_merge([ + $response = $this->client->call(Client::METHOD_POST, '/vectorsdb/' . $databaseId . '/collections', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -136,7 +136,7 @@ class DatabasesCustomClientTest extends Scope $this->assertEquals(201, $response['headers']['status-code']); // Creating document by server, give read permission to our user + some other user - $response = $this->client->call(Client::METHOD_POST, '/vectordb/' . $databaseId . '/collections/permissionCheck/documents', array_merge([ + $response = $this->client->call(Client::METHOD_POST, '/vectorsdb/' . $databaseId . '/collections/permissionCheck/documents', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -158,7 +158,7 @@ class DatabasesCustomClientTest extends Scope // Update document // This is the point of this test. We should be allowed to do this action, and it should not fail on permission check - $response = $this->client->call(Client::METHOD_PATCH, '/vectordb/' . $databaseId . '/collections/permissionCheck/documents/permissionCheckDocument', array_merge([ + $response = $this->client->call(Client::METHOD_PATCH, '/vectorsdb/' . $databaseId . '/collections/permissionCheck/documents/permissionCheckDocument', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'] ], $this->getHeaders()), [ @@ -171,7 +171,7 @@ class DatabasesCustomClientTest extends Scope $this->assertEquals(200, $response['headers']['status-code']); // Get name of the document, should be the new one - $response = $this->client->call(Client::METHOD_GET, '/vectordb/' . $databaseId . '/collections/permissionCheck/documents/permissionCheckDocument', array_merge([ + $response = $this->client->call(Client::METHOD_GET, '/vectorsdb/' . $databaseId . '/collections/permissionCheck/documents/permissionCheckDocument', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders())); @@ -180,7 +180,7 @@ class DatabasesCustomClientTest extends Scope // Cleanup to prevent collision with other tests // Delete collection - $response = $this->client->call(Client::METHOD_DELETE, '/vectordb/' . $databaseId . '/collections/permissionCheck', array_merge([ + $response = $this->client->call(Client::METHOD_DELETE, '/vectorsdb/' . $databaseId . '/collections/permissionCheck', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -193,7 +193,7 @@ class DatabasesCustomClientTest extends Scope sleep(2); // Make sure collection has been deleted - $response = $this->client->call(Client::METHOD_GET, '/vectordb/' . $databaseId . '/collections/permissionCheck', array_merge([ + $response = $this->client->call(Client::METHOD_GET, '/vectorsdb/' . $databaseId . '/collections/permissionCheck', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] diff --git a/tests/e2e/Services/Databases/VectorDB/DatabasesCustomServerTest.php b/tests/e2e/Services/Databases/VectorsDB/DatabasesCustomServerTest.php similarity index 90% rename from tests/e2e/Services/Databases/VectorDB/DatabasesCustomServerTest.php rename to tests/e2e/Services/Databases/VectorsDB/DatabasesCustomServerTest.php index 45e641419f..9564b76079 100644 --- a/tests/e2e/Services/Databases/VectorDB/DatabasesCustomServerTest.php +++ b/tests/e2e/Services/Databases/VectorsDB/DatabasesCustomServerTest.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace Tests\E2E\Services\Databases\VectorDB; +namespace Tests\E2E\Services\Databases\VectorsDB; use PHPUnit\Framework\Attributes\Depends; use Tests\E2E\Client; @@ -22,7 +22,7 @@ class DatabasesCustomServerTest extends Scope public function testListDatabases(): array { - $db1 = $this->client->call(Client::METHOD_POST, '/vectordb', [ + $db1 = $this->client->call(Client::METHOD_POST, '/vectorsdb', [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -32,14 +32,14 @@ class DatabasesCustomServerTest extends Scope ]); $this->assertEquals(201, $db1['headers']['status-code']); $this->assertEquals('Test 1', $db1['body']['name']); - $this->assertEquals('vectordb', $db1['body']['type']); + $this->assertEquals('vectorsdb', $db1['body']['type']); // Validate database response model fields on create $this->assertArrayHasKey('$id', $db1['body']); $this->assertArrayHasKey('$createdAt', $db1['body']); $this->assertArrayHasKey('$updatedAt', $db1['body']); $this->assertArrayHasKey('enabled', $db1['body']); - $db2 = $this->client->call(Client::METHOD_POST, '/vectordb', [ + $db2 = $this->client->call(Client::METHOD_POST, '/vectorsdb', [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -49,9 +49,9 @@ class DatabasesCustomServerTest extends Scope ]); $this->assertEquals(201, $db2['headers']['status-code']); $this->assertEquals('Test 2', $db2['body']['name']); - $this->assertEquals('vectordb', $db2['body']['type']); + $this->assertEquals('vectorsdb', $db2['body']['type']); - $list = $this->client->call(Client::METHOD_GET, '/vectordb', [ + $list = $this->client->call(Client::METHOD_GET, '/vectorsdb', [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -71,7 +71,7 @@ class DatabasesCustomServerTest extends Scope public function testGetDatabase(array $data): array { $databaseId = $data['databaseId']; - $res = $this->client->call(Client::METHOD_GET, '/vectordb/' . $databaseId, [ + $res = $this->client->call(Client::METHOD_GET, '/vectorsdb/' . $databaseId, [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -79,7 +79,7 @@ class DatabasesCustomServerTest extends Scope $this->assertEquals(200, $res['headers']['status-code']); $this->assertEquals($databaseId, $res['body']['$id']); $this->assertEquals('Test 1', $res['body']['name']); - $this->assertEquals('vectordb', $res['body']['type']); + $this->assertEquals('vectorsdb', $res['body']['type']); return ['databaseId' => $databaseId]; } @@ -87,7 +87,7 @@ class DatabasesCustomServerTest extends Scope public function testUpdateDatabase(array $data): array { $databaseId = $data['databaseId']; - $res = $this->client->call(Client::METHOD_PUT, '/vectordb/' . $databaseId, [ + $res = $this->client->call(Client::METHOD_PUT, '/vectorsdb/' . $databaseId, [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -96,7 +96,7 @@ class DatabasesCustomServerTest extends Scope ]); $this->assertEquals(200, $res['headers']['status-code']); $this->assertEquals('Test 1 Updated', $res['body']['name']); - $this->assertEquals('vectordb', $res['body']['type']); + $this->assertEquals('vectorsdb', $res['body']['type']); return ['databaseId' => $databaseId]; } @@ -104,7 +104,7 @@ class DatabasesCustomServerTest extends Scope public function testDeleteDatabase(array $data): void { $databaseId = $data['databaseId']; - $del = $this->client->call(Client::METHOD_DELETE, '/vectordb/' . $databaseId, [ + $del = $this->client->call(Client::METHOD_DELETE, '/vectorsdb/' . $databaseId, [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -112,7 +112,7 @@ class DatabasesCustomServerTest extends Scope $this->assertEquals(204, $del['headers']['status-code']); $this->assertEquals("", $del['body']); - $get = $this->client->call(Client::METHOD_GET, '/vectordb/' . $databaseId, [ + $get = $this->client->call(Client::METHOD_GET, '/vectorsdb/' . $databaseId, [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -123,7 +123,7 @@ class DatabasesCustomServerTest extends Scope public function testCollectionsCRUD(): array { // Create database for collections tests - $database = $this->client->call(Client::METHOD_POST, '/vectordb', [ + $database = $this->client->call(Client::METHOD_POST, '/vectorsdb', [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -135,7 +135,7 @@ class DatabasesCustomServerTest extends Scope $databaseId = $database['body']['$id']; // Create two collections - $col1 = $this->client->call(Client::METHOD_POST, '/vectordb/' . $databaseId . '/collections', [ + $col1 = $this->client->call(Client::METHOD_POST, '/vectorsdb/' . $databaseId . '/collections', [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -160,7 +160,7 @@ class DatabasesCustomServerTest extends Scope $this->assertArrayHasKey('documentSecurity', $col1['body']); $this->assertArrayHasKey('dimension', $col1['body']); - $col2 = $this->client->call(Client::METHOD_POST, '/vectordb/' . $databaseId . '/collections', [ + $col2 = $this->client->call(Client::METHOD_POST, '/vectorsdb/' . $databaseId . '/collections', [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -182,7 +182,7 @@ class DatabasesCustomServerTest extends Scope $this->assertArrayHasKey('$updatedAt', $col2['body']); // List collections - $list = $this->client->call(Client::METHOD_GET, '/vectordb/' . $databaseId . '/collections', [ + $list = $this->client->call(Client::METHOD_GET, '/vectorsdb/' . $databaseId . '/collections', [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -196,7 +196,7 @@ class DatabasesCustomServerTest extends Scope $this->assertArrayHasKey('dimension', $list['body']['collections'][0]); // Get collection - $get = $this->client->call(Client::METHOD_GET, '/vectordb/' . $databaseId . '/collections/' . $col1['body']['$id'], [ + $get = $this->client->call(Client::METHOD_GET, '/vectorsdb/' . $databaseId . '/collections/' . $col1['body']['$id'], [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -207,7 +207,7 @@ class DatabasesCustomServerTest extends Scope $this->assertEquals(3, $get['body']['dimension']); // Update collection (name only) - $upd = $this->client->call(Client::METHOD_PUT, '/vectordb/' . $databaseId . '/collections/' . $col1['body']['$id'], [ + $upd = $this->client->call(Client::METHOD_PUT, '/vectorsdb/' . $databaseId . '/collections/' . $col1['body']['$id'], [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -219,7 +219,7 @@ class DatabasesCustomServerTest extends Scope $this->assertArrayHasKey('$updatedAt', $upd['body']); // Delete collection - $del = $this->client->call(Client::METHOD_DELETE, '/vectordb/' . $databaseId . '/collections/' . $col2['body']['$id'], [ + $del = $this->client->call(Client::METHOD_DELETE, '/vectorsdb/' . $databaseId . '/collections/' . $col2['body']['$id'], [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -240,7 +240,7 @@ class DatabasesCustomServerTest extends Scope $collectionId = $data['collectionId']; // Update collection name and dimensions - $upd = $this->client->call(Client::METHOD_PUT, '/vectordb/' . $databaseId . '/collections/' . $collectionId, [ + $upd = $this->client->call(Client::METHOD_PUT, '/vectorsdb/' . $databaseId . '/collections/' . $collectionId, [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -253,7 +253,7 @@ class DatabasesCustomServerTest extends Scope $this->assertEquals(4, $upd['body']['dimension']); // Read back to confirm - $get = $this->client->call(Client::METHOD_GET, '/vectordb/' . $databaseId . '/collections/' . $collectionId, [ + $get = $this->client->call(Client::METHOD_GET, '/vectorsdb/' . $databaseId . '/collections/' . $collectionId, [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -272,7 +272,7 @@ class DatabasesCustomServerTest extends Scope $collectionId = $data['collectionId']; // Disable collection - $disable = $this->client->call(Client::METHOD_PUT, '/vectordb/' . $databaseId . '/collections/' . $collectionId, [ + $disable = $this->client->call(Client::METHOD_PUT, '/vectorsdb/' . $databaseId . '/collections/' . $collectionId, [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -284,7 +284,7 @@ class DatabasesCustomServerTest extends Scope $this->assertFalse($disable['body']['enabled']); // Re-enable collection - $enable = $this->client->call(Client::METHOD_PUT, '/vectordb/' . $databaseId . '/collections/' . $collectionId, [ + $enable = $this->client->call(Client::METHOD_PUT, '/vectorsdb/' . $databaseId . '/collections/' . $collectionId, [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -301,7 +301,7 @@ class DatabasesCustomServerTest extends Scope public function testUpdateDatabaseNameAndEnabled(): void { // Create isolated database for this test to avoid ordering conflicts - $create = $this->client->call(Client::METHOD_POST, '/vectordb', [ + $create = $this->client->call(Client::METHOD_POST, '/vectorsdb', [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -313,7 +313,7 @@ class DatabasesCustomServerTest extends Scope $databaseId = $create['body']['$id']; // Update name - $rename = $this->client->call(Client::METHOD_PUT, '/vectordb/' . $databaseId, [ + $rename = $this->client->call(Client::METHOD_PUT, '/vectorsdb/' . $databaseId, [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -324,7 +324,7 @@ class DatabasesCustomServerTest extends Scope $this->assertEquals('Test DB Renamed', $rename['body']['name']); // Toggle enabled off then on - $disable = $this->client->call(Client::METHOD_PUT, '/vectordb/' . $databaseId, [ + $disable = $this->client->call(Client::METHOD_PUT, '/vectorsdb/' . $databaseId, [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -335,7 +335,7 @@ class DatabasesCustomServerTest extends Scope $this->assertEquals(200, $disable['headers']['status-code']); $this->assertFalse($disable['body']['enabled']); - $enable = $this->client->call(Client::METHOD_PUT, '/vectordb/' . $databaseId, [ + $enable = $this->client->call(Client::METHOD_PUT, '/vectorsdb/' . $databaseId, [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -347,7 +347,7 @@ class DatabasesCustomServerTest extends Scope $this->assertTrue($enable['body']['enabled']); // Cleanup - $del = $this->client->call(Client::METHOD_DELETE, '/vectordb/' . $databaseId, [ + $del = $this->client->call(Client::METHOD_DELETE, '/vectorsdb/' . $databaseId, [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -362,7 +362,7 @@ class DatabasesCustomServerTest extends Scope $collectionId = $data['collectionId']; // Create a new index variant - $create = $this->client->call(Client::METHOD_POST, "/vectordb/{$databaseId}/collections/{$collectionId}/indexes", [ + $create = $this->client->call(Client::METHOD_POST, "/vectorsdb/{$databaseId}/collections/{$collectionId}/indexes", [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -374,7 +374,7 @@ class DatabasesCustomServerTest extends Scope $this->assertEquals(202, $create['headers']['status-code']); // Ensure it exists - $get = $this->client->call(Client::METHOD_GET, "/vectordb/{$databaseId}/collections/{$collectionId}/indexes/embedding_euclidean_v2", [ + $get = $this->client->call(Client::METHOD_GET, "/vectorsdb/{$databaseId}/collections/{$collectionId}/indexes/embedding_euclidean_v2", [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -383,7 +383,7 @@ class DatabasesCustomServerTest extends Scope $this->assertEquals('embedding_euclidean_v2', $get['body']['key']); // Delete it - $del = $this->client->call(Client::METHOD_DELETE, "/vectordb/{$databaseId}/collections/{$collectionId}/indexes/embedding_euclidean_v2", [ + $del = $this->client->call(Client::METHOD_DELETE, "/vectorsdb/{$databaseId}/collections/{$collectionId}/indexes/embedding_euclidean_v2", [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -398,7 +398,7 @@ class DatabasesCustomServerTest extends Scope $collectionId = $data['collectionId']; // Create indexes - $eu = $this->client->call(Client::METHOD_POST, "/vectordb/{$databaseId}/collections/{$collectionId}/indexes", [ + $eu = $this->client->call(Client::METHOD_POST, "/vectorsdb/{$databaseId}/collections/{$collectionId}/indexes", [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -409,7 +409,7 @@ class DatabasesCustomServerTest extends Scope ]); $this->assertEquals(202, $eu['headers']['status-code']); - $dot = $this->client->call(Client::METHOD_POST, "/vectordb/{$databaseId}/collections/{$collectionId}/indexes", [ + $dot = $this->client->call(Client::METHOD_POST, "/vectorsdb/{$databaseId}/collections/{$collectionId}/indexes", [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -420,7 +420,7 @@ class DatabasesCustomServerTest extends Scope ]); $this->assertEquals(202, $dot['headers']['status-code']); - $cos = $this->client->call(Client::METHOD_POST, "/vectordb/{$databaseId}/collections/{$collectionId}/indexes", [ + $cos = $this->client->call(Client::METHOD_POST, "/vectorsdb/{$databaseId}/collections/{$collectionId}/indexes", [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -432,7 +432,7 @@ class DatabasesCustomServerTest extends Scope $this->assertEquals(202, $cos['headers']['status-code']); // List indexes - $list = $this->client->call(Client::METHOD_GET, "/vectordb/{$databaseId}/collections/{$collectionId}/indexes", [ + $list = $this->client->call(Client::METHOD_GET, "/vectorsdb/{$databaseId}/collections/{$collectionId}/indexes", [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -445,7 +445,7 @@ class DatabasesCustomServerTest extends Scope $this->assertContains('embedding_cosine', $keys); // Get index by key - $get = $this->client->call(Client::METHOD_GET, "/vectordb/{$databaseId}/collections/{$collectionId}/indexes/embedding_euclidean", [ + $get = $this->client->call(Client::METHOD_GET, "/vectorsdb/{$databaseId}/collections/{$collectionId}/indexes/embedding_euclidean", [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -455,7 +455,7 @@ class DatabasesCustomServerTest extends Scope $this->assertEquals(Database::INDEX_HNSW_EUCLIDEAN, $get['body']['type']); // Delete index - $del = $this->client->call(Client::METHOD_DELETE, "/vectordb/{$databaseId}/collections/{$collectionId}/indexes/embedding_dot", [ + $del = $this->client->call(Client::METHOD_DELETE, "/vectorsdb/{$databaseId}/collections/{$collectionId}/indexes/embedding_dot", [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -463,7 +463,7 @@ class DatabasesCustomServerTest extends Scope $this->assertEquals(204, $del['headers']['status-code']); sleep(4); // Ensure it's gone - $getMissing = $this->client->call(Client::METHOD_GET, "/vectordb/{$databaseId}/collections/{$collectionId}/indexes/embedding_dot", [ + $getMissing = $this->client->call(Client::METHOD_GET, "/vectorsdb/{$databaseId}/collections/{$collectionId}/indexes/embedding_dot", [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -474,7 +474,7 @@ class DatabasesCustomServerTest extends Scope public function testBulkCreate(): array { // Setup: create isolated database and collection - $db = $this->client->call(Client::METHOD_POST, '/vectordb', [ + $db = $this->client->call(Client::METHOD_POST, '/vectorsdb', [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -485,7 +485,7 @@ class DatabasesCustomServerTest extends Scope $this->assertEquals(201, $db['headers']['status-code']); $databaseId = $db['body']['$id']; - $col = $this->client->call(Client::METHOD_POST, "/vectordb/{$databaseId}/collections", [ + $col = $this->client->call(Client::METHOD_POST, "/vectorsdb/{$databaseId}/collections", [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -512,7 +512,7 @@ class DatabasesCustomServerTest extends Scope ], ]; - $res = $this->client->call(Client::METHOD_POST, "/vectordb/{$databaseId}/collections/{$collectionId}/documents", [ + $res = $this->client->call(Client::METHOD_POST, "/vectorsdb/{$databaseId}/collections/{$collectionId}/documents", [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -532,7 +532,7 @@ class DatabasesCustomServerTest extends Scope // Fetch and validate persisted data via GET foreach ($ids as $i => $id) { - $get = $this->client->call(Client::METHOD_GET, "/vectordb/{$databaseId}/collections/{$collectionId}/documents/{$id}", [ + $get = $this->client->call(Client::METHOD_GET, "/vectorsdb/{$databaseId}/collections/{$collectionId}/documents/{$id}", [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -550,7 +550,7 @@ class DatabasesCustomServerTest extends Scope public function testCreateTextEmbeddingsSuccessAndErrors(): void { // Setup new database and collection - $db = $this->client->call(Client::METHOD_POST, '/vectordb', [ + $db = $this->client->call(Client::METHOD_POST, '/vectorsdb', [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -561,7 +561,7 @@ class DatabasesCustomServerTest extends Scope $this->assertEquals(201, $db['headers']['status-code']); $databaseId = $db['body']['$id']; - $col = $this->client->call(Client::METHOD_POST, "/vectordb/{$databaseId}/collections", [ + $col = $this->client->call(Client::METHOD_POST, "/vectorsdb/{$databaseId}/collections", [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -577,7 +577,7 @@ class DatabasesCustomServerTest extends Scope // Success: two embeddings $this->assertEventually(function () { - $ok = $this->client->call(Client::METHOD_POST, "/vectordb/embeddings/text", [ + $ok = $this->client->call(Client::METHOD_POST, "/vectorsdb/embeddings/text", [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -603,7 +603,7 @@ class DatabasesCustomServerTest extends Scope }, 3000, 100); // Error: missing texts payload - $missingTexts = $this->client->call(Client::METHOD_POST, "/vectordb/embeddings/text", [ + $missingTexts = $this->client->call(Client::METHOD_POST, "/vectorsdb/embeddings/text", [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -611,7 +611,7 @@ class DatabasesCustomServerTest extends Scope $this->assertEquals(400, $missingTexts['headers']['status-code']); // Error: invalid texts item type (must be strings) - $invalidItem = $this->client->call(Client::METHOD_POST, "/vectordb/embeddings/text", [ + $invalidItem = $this->client->call(Client::METHOD_POST, "/vectorsdb/embeddings/text", [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -625,7 +625,7 @@ class DatabasesCustomServerTest extends Scope $this->assertEquals(400, $invalidItem['headers']['status-code']); // Error: unknown embedding model - $unknownModel = $this->client->call(Client::METHOD_POST, "/vectordb/embeddings/text", [ + $unknownModel = $this->client->call(Client::METHOD_POST, "/vectorsdb/embeddings/text", [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -639,7 +639,7 @@ class DatabasesCustomServerTest extends Scope public function testBulkUpsert(): void { // Setup fresh db/collection - $db = $this->client->call(Client::METHOD_POST, '/vectordb', [ + $db = $this->client->call(Client::METHOD_POST, '/vectorsdb', [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -647,7 +647,7 @@ class DatabasesCustomServerTest extends Scope $this->assertEquals(201, $db['headers']['status-code']); $databaseId = $db['body']['$id']; - $col = $this->client->call(Client::METHOD_POST, "/vectordb/{$databaseId}/collections", [ + $col = $this->client->call(Client::METHOD_POST, "/vectorsdb/{$databaseId}/collections", [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -674,7 +674,7 @@ class DatabasesCustomServerTest extends Scope ], ]; - $res = $this->client->call(Client::METHOD_PUT, "/vectordb/{$databaseId}/collections/{$collectionId}/documents", [ + $res = $this->client->call(Client::METHOD_PUT, "/vectorsdb/{$databaseId}/collections/{$collectionId}/documents", [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -691,7 +691,7 @@ class DatabasesCustomServerTest extends Scope // Fetch and validate updated content $ids = array_map(fn ($d) => $d['$id'], $res['body']['documents']); foreach ($ids as $id) { - $get = $this->client->call(Client::METHOD_GET, "/vectordb/{$databaseId}/collections/{$collectionId}/documents/{$id}", [ + $get = $this->client->call(Client::METHOD_GET, "/vectorsdb/{$databaseId}/collections/{$collectionId}/documents/{$id}", [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -705,7 +705,7 @@ class DatabasesCustomServerTest extends Scope [ 'embeddings' => [0.6, 0.4, 0.0], 'metadata' => ['updatedAgain' => true] ], [ 'embeddings' => [0.3, 0.7, 0.0], 'metadata' => ['updatedAgain' => true] ], ]; - $res2 = $this->client->call(Client::METHOD_PUT, "/vectordb/{$databaseId}/collections/{$collectionId}/documents", [ + $res2 = $this->client->call(Client::METHOD_PUT, "/vectorsdb/{$databaseId}/collections/{$collectionId}/documents", [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -719,7 +719,7 @@ class DatabasesCustomServerTest extends Scope // Fetch again and assert second update persisted $ids2 = array_map(fn ($d) => $d['$id'], $res2['body']['documents']); foreach ($ids2 as $id) { - $get2 = $this->client->call(Client::METHOD_GET, "/vectordb/{$databaseId}/collections/{$collectionId}/documents/{$id}", [ + $get2 = $this->client->call(Client::METHOD_GET, "/vectorsdb/{$databaseId}/collections/{$collectionId}/documents/{$id}", [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -732,7 +732,7 @@ class DatabasesCustomServerTest extends Scope public function testBulkUpdate(): void { // Setup: create db/collection and two docs - $db = $this->client->call(Client::METHOD_POST, '/vectordb', [ + $db = $this->client->call(Client::METHOD_POST, '/vectorsdb', [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -740,7 +740,7 @@ class DatabasesCustomServerTest extends Scope $this->assertEquals(201, $db['headers']['status-code']); $databaseId = $db['body']['$id']; - $col = $this->client->call(Client::METHOD_POST, "/vectordb/{$databaseId}/collections", [ + $col = $this->client->call(Client::METHOD_POST, "/vectorsdb/{$databaseId}/collections", [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -754,7 +754,7 @@ class DatabasesCustomServerTest extends Scope $this->assertEquals(201, $col['headers']['status-code']); $collectionId = $col['body']['$id']; - $seed = $this->client->call(Client::METHOD_PUT, "/vectordb/{$databaseId}/collections/{$collectionId}/documents", [ + $seed = $this->client->call(Client::METHOD_PUT, "/vectorsdb/{$databaseId}/collections/{$collectionId}/documents", [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -767,7 +767,7 @@ class DatabasesCustomServerTest extends Scope $this->assertEquals(200, $seed['headers']['status-code']); $ids = array_map(fn ($d) => $d['$id'], $seed['body']['documents']); - $res = $this->client->call(Client::METHOD_PATCH, "/vectordb/{$databaseId}/collections/{$collectionId}/documents", [ + $res = $this->client->call(Client::METHOD_PATCH, "/vectorsdb/{$databaseId}/collections/{$collectionId}/documents", [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -787,7 +787,7 @@ class DatabasesCustomServerTest extends Scope // Fetch by IDs and assert update persisted foreach ($ids as $id) { - $get = $this->client->call(Client::METHOD_GET, "/vectordb/{$databaseId}/collections/{$collectionId}/documents/{$id}", [ + $get = $this->client->call(Client::METHOD_GET, "/vectorsdb/{$databaseId}/collections/{$collectionId}/documents/{$id}", [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -800,7 +800,7 @@ class DatabasesCustomServerTest extends Scope public function testBulkDelete(): void { // Setup: create db/collection and two docs - $db = $this->client->call(Client::METHOD_POST, '/vectordb', [ + $db = $this->client->call(Client::METHOD_POST, '/vectorsdb', [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -808,7 +808,7 @@ class DatabasesCustomServerTest extends Scope $this->assertEquals(201, $db['headers']['status-code']); $databaseId = $db['body']['$id']; - $col = $this->client->call(Client::METHOD_POST, "/vectordb/{$databaseId}/collections", [ + $col = $this->client->call(Client::METHOD_POST, "/vectorsdb/{$databaseId}/collections", [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -822,7 +822,7 @@ class DatabasesCustomServerTest extends Scope $this->assertEquals(201, $col['headers']['status-code']); $collectionId = $col['body']['$id']; - $seed = $this->client->call(Client::METHOD_PUT, "/vectordb/{$databaseId}/collections/{$collectionId}/documents", [ + $seed = $this->client->call(Client::METHOD_PUT, "/vectorsdb/{$databaseId}/collections/{$collectionId}/documents", [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -835,7 +835,7 @@ class DatabasesCustomServerTest extends Scope $this->assertEquals(200, $seed['headers']['status-code']); $ids = array_map(fn ($d) => $d['$id'], $seed['body']['documents']); - $res = $this->client->call(Client::METHOD_DELETE, "/vectordb/{$databaseId}/collections/{$collectionId}/documents", [ + $res = $this->client->call(Client::METHOD_DELETE, "/vectorsdb/{$databaseId}/collections/{$collectionId}/documents", [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -850,7 +850,7 @@ class DatabasesCustomServerTest extends Scope // Ensure they are deleted foreach ($ids as $id) { - $get = $this->client->call(Client::METHOD_GET, "/vectordb/{$databaseId}/collections/{$collectionId}/documents/{$id}", [ + $get = $this->client->call(Client::METHOD_GET, "/vectorsdb/{$databaseId}/collections/{$collectionId}/documents/{$id}", [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -862,7 +862,7 @@ class DatabasesCustomServerTest extends Scope public function testCustomTimestamps(): void { // Setup: create database and collection - $db = $this->client->call(Client::METHOD_POST, '/vectordb', [ + $db = $this->client->call(Client::METHOD_POST, '/vectorsdb', [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -873,7 +873,7 @@ class DatabasesCustomServerTest extends Scope $this->assertEquals(201, $db['headers']['status-code']); $databaseId = $db['body']['$id']; - $col = $this->client->call(Client::METHOD_POST, "/vectordb/{$databaseId}/collections", [ + $col = $this->client->call(Client::METHOD_POST, "/vectorsdb/{$databaseId}/collections", [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -894,7 +894,7 @@ class DatabasesCustomServerTest extends Scope $vector[0] = 1.0; $documentId = ID::unique(); - $doc = $this->client->call(Client::METHOD_POST, "/vectordb/{$databaseId}/collections/{$collectionId}/documents", [ + $doc = $this->client->call(Client::METHOD_POST, "/vectorsdb/{$databaseId}/collections/{$collectionId}/documents", [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -917,7 +917,7 @@ class DatabasesCustomServerTest extends Scope $this->assertEquals($customUpdatedAt, $doc['body']['$updatedAt'], 'UpdatedAt should match custom timestamp'); // Fetch document and verify timestamps persist - $fetched = $this->client->call(Client::METHOD_GET, "/vectordb/{$databaseId}/collections/{$collectionId}/documents/{$documentId}", [ + $fetched = $this->client->call(Client::METHOD_GET, "/vectorsdb/{$databaseId}/collections/{$collectionId}/documents/{$documentId}", [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -932,7 +932,7 @@ class DatabasesCustomServerTest extends Scope $vector2 = array_fill(0, 1536, 0.0); $vector2[1] = 1.0; - $updated = $this->client->call(Client::METHOD_PUT, "/vectordb/{$databaseId}/collections/{$collectionId}/documents/{$documentId}", [ + $updated = $this->client->call(Client::METHOD_PUT, "/vectorsdb/{$databaseId}/collections/{$collectionId}/documents/{$documentId}", [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -950,7 +950,7 @@ class DatabasesCustomServerTest extends Scope $this->assertEquals($newCustomUpdatedAt, $updated['body']['$updatedAt'], 'UpdatedAt should be updated to new custom timestamp'); // Final verification - $final = $this->client->call(Client::METHOD_GET, "/vectordb/{$databaseId}/collections/{$collectionId}/documents/{$documentId}", [ + $final = $this->client->call(Client::METHOD_GET, "/vectorsdb/{$databaseId}/collections/{$collectionId}/documents/{$documentId}", [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] diff --git a/tests/e2e/Services/Databases/VectorDB/Permissions/DatabasesPermissionsGuestTest.php b/tests/e2e/Services/Databases/VectorsDB/Permissions/DatabasesPermissionsGuestTest.php similarity index 86% rename from tests/e2e/Services/Databases/VectorDB/Permissions/DatabasesPermissionsGuestTest.php rename to tests/e2e/Services/Databases/VectorsDB/Permissions/DatabasesPermissionsGuestTest.php index 4759413e77..9335b7f55b 100644 --- a/tests/e2e/Services/Databases/VectorDB/Permissions/DatabasesPermissionsGuestTest.php +++ b/tests/e2e/Services/Databases/VectorsDB/Permissions/DatabasesPermissionsGuestTest.php @@ -1,6 +1,6 @@ client->call(Client::METHOD_POST, '/vectordb', array_merge([ + $database = $this->client->call(Client::METHOD_POST, '/vectorsdb', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -45,7 +45,7 @@ class DatabasesPermissionsGuestTest extends Scope $this->assertEquals('VectorGuestDB', $database['body']['name']); $databaseId = $database['body']['$id']; - $publicMovies = $this->client->call(Client::METHOD_POST, '/vectordb/' . $databaseId . '/collections', $this->getServerHeader(), [ + $publicMovies = $this->client->call(Client::METHOD_POST, '/vectorsdb/' . $databaseId . '/collections', $this->getServerHeader(), [ 'collectionId' => ID::unique(), 'name' => 'Movies', 'dimension' => 3, @@ -56,7 +56,7 @@ class DatabasesPermissionsGuestTest extends Scope Permission::delete(Role::any()), ], ]); - $privateMovies = $this->client->call(Client::METHOD_POST, '/vectordb/' . $databaseId . '/collections', $this->getServerHeader(), [ + $privateMovies = $this->client->call(Client::METHOD_POST, '/vectorsdb/' . $databaseId . '/collections', $this->getServerHeader(), [ 'collectionId' => ID::unique(), 'name' => 'Movies', 'dimension' => 3, @@ -94,7 +94,7 @@ class DatabasesPermissionsGuestTest extends Scope $privateCollectionId = $data['privateCollectionId']; $databaseId = $data['databaseId']; - $publicResponse = $this->client->call(Client::METHOD_POST, '/vectordb/' . $databaseId . '/collections/' . $publicCollectionId . '/documents', $this->getServerHeader(), [ + $publicResponse = $this->client->call(Client::METHOD_POST, '/vectorsdb/' . $databaseId . '/collections/' . $publicCollectionId . '/documents', $this->getServerHeader(), [ 'documentId' => ID::unique(), 'data' => [ 'embeddings' => [1.0, 0.0, 0.0], @@ -102,7 +102,7 @@ class DatabasesPermissionsGuestTest extends Scope ], 'permissions' => $permissions, ]); - $privateResponse = $this->client->call(Client::METHOD_POST, '/vectordb/' . $databaseId . '/collections/' . $privateCollectionId . '/documents', $this->getServerHeader(), [ + $privateResponse = $this->client->call(Client::METHOD_POST, '/vectorsdb/' . $databaseId . '/collections/' . $privateCollectionId . '/documents', $this->getServerHeader(), [ 'documentId' => ID::unique(), 'data' => [ 'embeddings' => [0.0, 1.0, 0.0], @@ -117,11 +117,11 @@ class DatabasesPermissionsGuestTest extends Scope $roles = $this->getAuthorization()->getRoles(); $this->getAuthorization()->cleanRoles(); - $publicDocuments = $this->client->call(Client::METHOD_GET, '/vectordb/' . $databaseId . '/collections/' . $publicCollectionId . '/documents', [ + $publicDocuments = $this->client->call(Client::METHOD_GET, '/vectorsdb/' . $databaseId . '/collections/' . $publicCollectionId . '/documents', [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ]); - $privateDocuments = $this->client->call(Client::METHOD_GET, '/vectordb/' . $databaseId . '/collections/' . $privateCollectionId . '/documents', [ + $privateDocuments = $this->client->call(Client::METHOD_GET, '/vectorsdb/' . $databaseId . '/collections/' . $privateCollectionId . '/documents', [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ]); @@ -151,7 +151,7 @@ class DatabasesPermissionsGuestTest extends Scope $roles = $this->getAuthorization()->getRoles(); $this->getAuthorization()->cleanRoles(); - $publicResponse = $this->client->call(Client::METHOD_POST, '/vectordb/' . $databaseId . '/collections/' . $publicCollectionId . '/documents', [ + $publicResponse = $this->client->call(Client::METHOD_POST, '/vectorsdb/' . $databaseId . '/collections/' . $publicCollectionId . '/documents', [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], [ @@ -165,7 +165,7 @@ class DatabasesPermissionsGuestTest extends Scope $publicDocumentId = $publicResponse['body']['$id']; $this->assertEquals(201, $publicResponse['headers']['status-code']); - $privateResponse = $this->client->call(Client::METHOD_POST, '/vectordb/' . $databaseId . '/collections/' . $privateCollectionId . '/documents', [ + $privateResponse = $this->client->call(Client::METHOD_POST, '/vectorsdb/' . $databaseId . '/collections/' . $privateCollectionId . '/documents', [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], [ @@ -179,7 +179,7 @@ class DatabasesPermissionsGuestTest extends Scope $this->assertEquals(401, $privateResponse['headers']['status-code']); // Create a document in private collection with API key so we can test that update and delete are also not allowed - $privateResponse = $this->client->call(Client::METHOD_POST, '/vectordb/' . $databaseId . '/collections/' . $privateCollectionId . '/documents', $this->getServerHeader(), [ + $privateResponse = $this->client->call(Client::METHOD_POST, '/vectorsdb/' . $databaseId . '/collections/' . $privateCollectionId . '/documents', $this->getServerHeader(), [ 'documentId' => ID::unique(), 'data' => [ 'embeddings' => [0.0, 0.0, 1.0], @@ -190,7 +190,7 @@ class DatabasesPermissionsGuestTest extends Scope $this->assertEquals(201, $privateResponse['headers']['status-code']); $privateDocumentId = $privateResponse['body']['$id']; - $publicDocument = $this->client->call(Client::METHOD_PUT, '/vectordb/' . $databaseId . '/collections/' . $publicCollectionId . '/documents/' . $publicDocumentId, [ + $publicDocument = $this->client->call(Client::METHOD_PUT, '/vectorsdb/' . $databaseId . '/collections/' . $publicCollectionId . '/documents/' . $publicDocumentId, [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], [ @@ -203,7 +203,7 @@ class DatabasesPermissionsGuestTest extends Scope $this->assertEquals(200, $publicDocument['headers']['status-code']); $this->assertEquals('Thor: Ragnarok', $publicDocument['body']['metadata']['title']); - $privateDocument = $this->client->call(Client::METHOD_PUT, '/vectordb/' . $databaseId . '/collections/' . $privateCollectionId . '/documents/' . $privateDocumentId, [ + $privateDocument = $this->client->call(Client::METHOD_PUT, '/vectorsdb/' . $databaseId . '/collections/' . $privateCollectionId . '/documents/' . $privateDocumentId, [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], [ @@ -215,14 +215,14 @@ class DatabasesPermissionsGuestTest extends Scope $this->assertEquals(401, $privateDocument['headers']['status-code']); - $publicDocument = $this->client->call(Client::METHOD_DELETE, '/vectordb/' . $databaseId . '/collections/' . $publicCollectionId . '/documents/' . $publicDocumentId, [ + $publicDocument = $this->client->call(Client::METHOD_DELETE, '/vectorsdb/' . $databaseId . '/collections/' . $publicCollectionId . '/documents/' . $publicDocumentId, [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ]); $this->assertEquals(204, $publicDocument['headers']['status-code']); - $privateDocument = $this->client->call(Client::METHOD_DELETE, '/vectordb/' . $databaseId . '/collections/' . $privateCollectionId . '/documents/' . $privateDocumentId, [ + $privateDocument = $this->client->call(Client::METHOD_DELETE, '/vectorsdb/' . $databaseId . '/collections/' . $privateCollectionId . '/documents/' . $privateDocumentId, [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ]); @@ -236,7 +236,7 @@ class DatabasesPermissionsGuestTest extends Scope public function testWriteDocumentWithPermissions() { - $database = $this->client->call(Client::METHOD_POST, '/vectordb', array_merge([ + $database = $this->client->call(Client::METHOD_POST, '/vectorsdb', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -248,7 +248,7 @@ class DatabasesPermissionsGuestTest extends Scope $this->assertEquals('VectorGuestPermsWrite', $database['body']['name']); $databaseId = $database['body']['$id']; - $movies = $this->client->call(Client::METHOD_POST, '/vectordb/' . $databaseId . '/collections', $this->getServerHeader(), [ + $movies = $this->client->call(Client::METHOD_POST, '/vectorsdb/' . $databaseId . '/collections', $this->getServerHeader(), [ 'collectionId' => ID::unique(), 'name' => 'Movies', 'dimension' => 3, @@ -260,7 +260,7 @@ class DatabasesPermissionsGuestTest extends Scope $moviesId = $movies['body']['$id']; - $document = $this->client->call(Client::METHOD_POST, '/vectordb/' . $databaseId . '/collections/' . $moviesId . '/documents', [ + $document = $this->client->call(Client::METHOD_POST, '/vectorsdb/' . $databaseId . '/collections/' . $moviesId . '/documents', [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], [ diff --git a/tests/e2e/Services/Databases/VectorDB/Permissions/DatabasesPermissionsMemberTest.php b/tests/e2e/Services/Databases/VectorsDB/Permissions/DatabasesPermissionsMemberTest.php similarity index 88% rename from tests/e2e/Services/Databases/VectorDB/Permissions/DatabasesPermissionsMemberTest.php rename to tests/e2e/Services/Databases/VectorsDB/Permissions/DatabasesPermissionsMemberTest.php index 723eeb29f5..cbc2add857 100644 --- a/tests/e2e/Services/Databases/VectorDB/Permissions/DatabasesPermissionsMemberTest.php +++ b/tests/e2e/Services/Databases/VectorsDB/Permissions/DatabasesPermissionsMemberTest.php @@ -1,6 +1,6 @@ createUsers(); - $db = $this->client->call(Client::METHOD_POST, '/vectordb', $this->getServerHeader(), [ + $db = $this->client->call(Client::METHOD_POST, '/vectorsdb', $this->getServerHeader(), [ 'databaseId' => ID::unique(), 'name' => 'Test Database', ]); @@ -66,7 +66,7 @@ class DatabasesPermissionsMemberTest extends Scope $databaseId = $db['body']['$id']; - $public = $this->client->call(Client::METHOD_POST, '/vectordb/' . $databaseId . '/collections', $this->getServerHeader(), [ + $public = $this->client->call(Client::METHOD_POST, '/vectorsdb/' . $databaseId . '/collections', $this->getServerHeader(), [ 'collectionId' => ID::unique(), 'name' => 'Movies', 'dimension' => 3, @@ -81,7 +81,7 @@ class DatabasesPermissionsMemberTest extends Scope $this->assertEquals(201, $public['headers']['status-code']); $this->collections = ['public' => $public['body']['$id']]; - $private = $this->client->call(Client::METHOD_POST, '/vectordb/' . $databaseId . '/collections', $this->getServerHeader(), [ + $private = $this->client->call(Client::METHOD_POST, '/vectorsdb/' . $databaseId . '/collections', $this->getServerHeader(), [ 'collectionId' => ID::unique(), 'name' => 'Private Movies', 'dimension' => 3, @@ -96,7 +96,7 @@ class DatabasesPermissionsMemberTest extends Scope $this->assertEquals(201, $private['headers']['status-code']); $this->collections['private'] = $private['body']['$id']; - $doconly = $this->client->call(Client::METHOD_POST, '/vectordb/' . $databaseId . '/collections', $this->getServerHeader(), [ + $doconly = $this->client->call(Client::METHOD_POST, '/vectorsdb/' . $databaseId . '/collections', $this->getServerHeader(), [ 'collectionId' => ID::unique(), 'name' => 'Document Only Movies', 'dimension' => 3, @@ -124,7 +124,7 @@ class DatabasesPermissionsMemberTest extends Scope $collections = $data['collections']; $databaseId = $data['databaseId']; - $response = $this->client->call(Client::METHOD_POST, '/vectordb/' . $databaseId . '/collections/' . $collections['public'] . '/documents', $this->getServerHeader(), [ + $response = $this->client->call(Client::METHOD_POST, '/vectorsdb/' . $databaseId . '/collections/' . $collections['public'] . '/documents', $this->getServerHeader(), [ 'documentId' => ID::unique(), 'data' => [ 'embeddings' => [1.0, 0.0, 0.0], @@ -134,7 +134,7 @@ class DatabasesPermissionsMemberTest extends Scope ]); $this->assertEquals(201, $response['headers']['status-code']); - $response = $this->client->call(Client::METHOD_POST, '/vectordb/' . $databaseId . '/collections/' . $collections['private'] . '/documents', $this->getServerHeader(), [ + $response = $this->client->call(Client::METHOD_POST, '/vectorsdb/' . $databaseId . '/collections/' . $collections['private'] . '/documents', $this->getServerHeader(), [ 'documentId' => ID::unique(), 'data' => [ 'embeddings' => [0.0, 1.0, 0.0], @@ -144,7 +144,7 @@ class DatabasesPermissionsMemberTest extends Scope ]); $this->assertEquals(201, $response['headers']['status-code']); - $response = $this->client->call(Client::METHOD_POST, '/vectordb/' . $databaseId . '/collections/' . $collections['doconly'] . '/documents', $this->getServerHeader(), [ + $response = $this->client->call(Client::METHOD_POST, '/vectorsdb/' . $databaseId . '/collections/' . $collections['doconly'] . '/documents', $this->getServerHeader(), [ 'documentId' => ID::unique(), 'data' => [ 'embeddings' => [0.0, 0.0, 1.0], @@ -157,7 +157,7 @@ class DatabasesPermissionsMemberTest extends Scope /** * Check "any" permission collection */ - $documents = $this->client->call(Client::METHOD_GET, '/vectordb/' . $databaseId . '/collections/' . $collections['public'] . '/documents', [ + $documents = $this->client->call(Client::METHOD_GET, '/vectorsdb/' . $databaseId . '/collections/' . $collections['public'] . '/documents', [ 'origin' => 'http://localhost', 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], @@ -170,7 +170,7 @@ class DatabasesPermissionsMemberTest extends Scope /** * Check "users" permission collection */ - $documents = $this->client->call(Client::METHOD_GET, '/vectordb/' . $databaseId . '/collections/' . $collections['private'] . '/documents', [ + $documents = $this->client->call(Client::METHOD_GET, '/vectorsdb/' . $databaseId . '/collections/' . $collections['private'] . '/documents', [ 'origin' => 'http://localhost', 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], @@ -183,7 +183,7 @@ class DatabasesPermissionsMemberTest extends Scope /** * Check "user:user1" document only permission collection */ - $documents = $this->client->call(Client::METHOD_GET, '/vectordb/' . $databaseId . '/collections/' . $collections['doconly'] . '/documents', [ + $documents = $this->client->call(Client::METHOD_GET, '/vectorsdb/' . $databaseId . '/collections/' . $collections['doconly'] . '/documents', [ 'origin' => 'http://localhost', 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], diff --git a/tests/e2e/Services/Databases/VectorDB/Permissions/DatabasesPermissionsScope.php b/tests/e2e/Services/Databases/VectorsDB/Permissions/DatabasesPermissionsScope.php similarity index 97% rename from tests/e2e/Services/Databases/VectorDB/Permissions/DatabasesPermissionsScope.php rename to tests/e2e/Services/Databases/VectorsDB/Permissions/DatabasesPermissionsScope.php index 7d1bfb41d6..be1800b654 100644 --- a/tests/e2e/Services/Databases/VectorDB/Permissions/DatabasesPermissionsScope.php +++ b/tests/e2e/Services/Databases/VectorsDB/Permissions/DatabasesPermissionsScope.php @@ -1,6 +1,6 @@ client->call(Client::METHOD_POST, '/vectordb', $this->getServerHeader(), [ + $db = $this->client->call(Client::METHOD_POST, '/vectorsdb', $this->getServerHeader(), [ 'databaseId' => $this->databaseId, 'name' => 'Test Database', ]); $this->assertEquals(201, $db['headers']['status-code']); - $collection1 = $this->client->call(Client::METHOD_POST, '/vectordb/' . $this->databaseId . '/collections', $this->getServerHeader(), [ + $collection1 = $this->client->call(Client::METHOD_POST, '/vectorsdb/' . $this->databaseId . '/collections', $this->getServerHeader(), [ 'collectionId' => ID::custom('collection1'), 'name' => 'Collection 1', 'dimension' => 3, @@ -60,7 +60,7 @@ class DatabasesPermissionsTeamTest extends Scope $this->collections['collection1'] = $collection1['body']['$id']; - $collection2 = $this->client->call(Client::METHOD_POST, '/vectordb/' . $this->databaseId . '/collections', $this->getServerHeader(), [ + $collection2 = $this->client->call(Client::METHOD_POST, '/vectorsdb/' . $this->databaseId . '/collections', $this->getServerHeader(), [ 'collectionId' => ID::custom('collection2'), 'name' => 'Collection 2', 'dimension' => 3, @@ -130,7 +130,7 @@ class DatabasesPermissionsTeamTest extends Scope $this->createCollections($this->teams); - $response = $this->client->call(Client::METHOD_POST, '/vectordb/' . $this->databaseId . '/collections/' . $this->collections['collection1'] . '/documents', $this->getServerHeader(), [ + $response = $this->client->call(Client::METHOD_POST, '/vectorsdb/' . $this->databaseId . '/collections/' . $this->collections['collection1'] . '/documents', $this->getServerHeader(), [ 'documentId' => ID::unique(), 'data' => [ 'embeddings' => [1.0, 0.0, 0.0], @@ -139,7 +139,7 @@ class DatabasesPermissionsTeamTest extends Scope ]); $this->assertEquals(201, $response['headers']['status-code']); - $response = $this->client->call(Client::METHOD_POST, '/vectordb/' . $this->databaseId . '/collections/' . $this->collections['collection2'] . '/documents', $this->getServerHeader(), [ + $response = $this->client->call(Client::METHOD_POST, '/vectorsdb/' . $this->databaseId . '/collections/' . $this->collections['collection2'] . '/documents', $this->getServerHeader(), [ 'documentId' => ID::unique(), 'data' => [ 'embeddings' => [0.0, 1.0, 0.0], @@ -158,7 +158,7 @@ class DatabasesPermissionsTeamTest extends Scope #[DataProvider('readDocumentsProvider')] public function testReadDocuments($user, $collection, $success, $users) { - $documents = $this->client->call(Client::METHOD_GET, '/vectordb/' . $this->databaseId . '/collections/' . $collection . '/documents', [ + $documents = $this->client->call(Client::METHOD_GET, '/vectorsdb/' . $this->databaseId . '/collections/' . $collection . '/documents', [ 'origin' => 'http://localhost', 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], @@ -176,7 +176,7 @@ class DatabasesPermissionsTeamTest extends Scope #[DataProvider('writeDocumentsProvider')] public function testWriteDocuments($user, $collection, $success, $users) { - $documents = $this->client->call(Client::METHOD_POST, '/vectordb/' . $this->databaseId . '/collections/' . $collection . '/documents', [ + $documents = $this->client->call(Client::METHOD_POST, '/vectorsdb/' . $this->databaseId . '/collections/' . $collection . '/documents', [ 'origin' => 'http://localhost', 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], diff --git a/tests/e2e/Services/Databases/VectorDB/Transactions/ACIDTest.php b/tests/e2e/Services/Databases/VectorsDB/Transactions/ACIDTest.php similarity index 89% rename from tests/e2e/Services/Databases/VectorDB/Transactions/ACIDTest.php rename to tests/e2e/Services/Databases/VectorsDB/Transactions/ACIDTest.php index 6e0e2dbd28..aa8d87eb8e 100644 --- a/tests/e2e/Services/Databases/VectorDB/Transactions/ACIDTest.php +++ b/tests/e2e/Services/Databases/VectorsDB/Transactions/ACIDTest.php @@ -1,6 +1,6 @@ client->call(Client::METHOD_POST, '/vectordb', array_merge([ + $database = $this->client->call(Client::METHOD_POST, '/vectorsdb', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -41,7 +41,7 @@ class ACIDTest extends Scope $databaseId = $database['body']['$id']; // Create collection for the test - $collection = $this->client->call(Client::METHOD_POST, '/vectordb/' . $databaseId . '/collections', array_merge([ + $collection = $this->client->call(Client::METHOD_POST, '/vectorsdb/' . $databaseId . '/collections', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -61,7 +61,7 @@ class ACIDTest extends Scope // Create a document outside the transaction $existingDocumentId = 'existing_doc'; - $doc1 = $this->client->call(Client::METHOD_POST, "/vectordb/{$databaseId}/collections/{$collectionId}/documents", array_merge([ + $doc1 = $this->client->call(Client::METHOD_POST, "/vectorsdb/{$databaseId}/collections/{$collectionId}/documents", array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders()), [ @@ -75,7 +75,7 @@ class ACIDTest extends Scope $this->assertEquals(201, $doc1['headers']['status-code']); // Create transaction - $transaction = $this->client->call(Client::METHOD_POST, '/vectordb/transactions', array_merge([ + $transaction = $this->client->call(Client::METHOD_POST, '/vectorsdb/transactions', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -86,7 +86,7 @@ class ACIDTest extends Scope $transactionId = $transaction['body']['$id']; // Add operations - second create reuses an existing documentId and should cause the commit to fail - $response = $this->client->call(Client::METHOD_POST, "/vectordb/{$databaseId}/collections/{$collectionId}/documents", array_merge([ + $response = $this->client->call(Client::METHOD_POST, "/vectorsdb/{$databaseId}/collections/{$collectionId}/documents", array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -114,7 +114,7 @@ class ACIDTest extends Scope $this->assertEquals(200, $response['headers']['status-code'], 'Adding documents via normal route should succeed. Response: ' . json_encode($response['body'])); // Attempt to commit - should fail due to duplicate document ID - $response = $this->client->call(Client::METHOD_PATCH, "/vectordb/transactions/{$transactionId}", array_merge([ + $response = $this->client->call(Client::METHOD_PATCH, "/vectorsdb/transactions/{$transactionId}", array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -125,7 +125,7 @@ class ACIDTest extends Scope $this->assertEquals(409, $response['headers']['status-code']); // Verify NO new documents were created (atomicity) - $documents = $this->client->call(Client::METHOD_GET, "/vectordb/{$databaseId}/collections/{$collectionId}/documents", array_merge([ + $documents = $this->client->call(Client::METHOD_GET, "/vectorsdb/{$databaseId}/collections/{$collectionId}/documents", array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders())); @@ -140,7 +140,7 @@ class ACIDTest extends Scope public function testConsistency(): void { // Create database - $database = $this->client->call(Client::METHOD_POST, '/vectordb', array_merge([ + $database = $this->client->call(Client::METHOD_POST, '/vectorsdb', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -153,7 +153,7 @@ class ACIDTest extends Scope $databaseId = $database['body']['$id']; // Create collection - $collection = $this->client->call(Client::METHOD_POST, '/vectordb/' . $databaseId . '/collections', array_merge([ + $collection = $this->client->call(Client::METHOD_POST, '/vectorsdb/' . $databaseId . '/collections', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -172,7 +172,7 @@ class ACIDTest extends Scope $collectionId = $collection['body']['$id']; // Create transaction - $transaction = $this->client->call(Client::METHOD_POST, '/vectordb/transactions', array_merge([ + $transaction = $this->client->call(Client::METHOD_POST, '/vectorsdb/transactions', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -181,7 +181,7 @@ class ACIDTest extends Scope $transactionId = $transaction['body']['$id']; // Stage operations with valid and invalid data (embedding length mismatch) - $response = $this->client->call(Client::METHOD_POST, "/vectordb/transactions/{$transactionId}/operations", array_merge([ + $response = $this->client->call(Client::METHOD_POST, "/vectorsdb/transactions/{$transactionId}/operations", array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -223,7 +223,7 @@ class ACIDTest extends Scope $this->assertEquals(201, $response['headers']['status-code']); // Attempt to commit - should fail due to invalid embeddings - $response = $this->client->call(Client::METHOD_PATCH, "/vectordb/transactions/{$transactionId}", array_merge([ + $response = $this->client->call(Client::METHOD_PATCH, "/vectorsdb/transactions/{$transactionId}", array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -234,7 +234,7 @@ class ACIDTest extends Scope $this->assertContains($response['headers']['status-code'], [400, 409, 500], 'Transaction commit should fail due to validation. Response: ' . json_encode($response['body'])); // Verify no documents were created - $documents = $this->client->call(Client::METHOD_GET, "/vectordb/{$databaseId}/collections/{$collectionId}/documents", array_merge([ + $documents = $this->client->call(Client::METHOD_GET, "/vectorsdb/{$databaseId}/collections/{$collectionId}/documents", array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders())); @@ -248,7 +248,7 @@ class ACIDTest extends Scope public function testIsolation(): void { // Create database - $database = $this->client->call(Client::METHOD_POST, '/vectordb', array_merge([ + $database = $this->client->call(Client::METHOD_POST, '/vectorsdb', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -261,7 +261,7 @@ class ACIDTest extends Scope $databaseId = $database['body']['$id']; // Create collection - $collection = $this->client->call(Client::METHOD_POST, '/vectordb/' . $databaseId . '/collections', array_merge([ + $collection = $this->client->call(Client::METHOD_POST, '/vectorsdb/' . $databaseId . '/collections', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -280,7 +280,7 @@ class ACIDTest extends Scope $collectionId = $collection['body']['$id']; // Create initial document with status metadata - $doc = $this->client->call(Client::METHOD_POST, "/vectordb/{$databaseId}/collections/{$collectionId}/documents", array_merge([ + $doc = $this->client->call(Client::METHOD_POST, "/vectorsdb/{$databaseId}/collections/{$collectionId}/documents", array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders()), [ @@ -294,7 +294,7 @@ class ACIDTest extends Scope $this->assertEquals(201, $doc['headers']['status-code']); // Create first transaction - $transaction1 = $this->client->call(Client::METHOD_POST, '/vectordb/transactions', array_merge([ + $transaction1 = $this->client->call(Client::METHOD_POST, '/vectorsdb/transactions', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -305,7 +305,7 @@ class ACIDTest extends Scope $transactionId1 = $transaction1['body']['$id']; // Transaction 1: update status to approved - $this->client->call(Client::METHOD_POST, "/vectordb/transactions/{$transactionId1}/operations", array_merge([ + $this->client->call(Client::METHOD_POST, "/vectorsdb/transactions/{$transactionId1}/operations", array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -324,7 +324,7 @@ class ACIDTest extends Scope ]); // Commit first transaction - $response1 = $this->client->call(Client::METHOD_PATCH, "/vectordb/transactions/{$transactionId1}", array_merge([ + $response1 = $this->client->call(Client::METHOD_PATCH, "/vectorsdb/transactions/{$transactionId1}", array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -334,14 +334,14 @@ class ACIDTest extends Scope $this->assertEquals(200, $response1['headers']['status-code']); // Document should reflect the first transaction's update - $document = $this->client->call(Client::METHOD_GET, "/vectordb/{$databaseId}/collections/{$collectionId}/documents/shared_doc", array_merge([ + $document = $this->client->call(Client::METHOD_GET, "/vectorsdb/{$databaseId}/collections/{$collectionId}/documents/shared_doc", array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders())); $this->assertEquals('approved', $document['body']['metadata']['status']); // Create second transaction after first commit - $transaction2 = $this->client->call(Client::METHOD_POST, '/vectordb/transactions', array_merge([ + $transaction2 = $this->client->call(Client::METHOD_POST, '/vectorsdb/transactions', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -352,7 +352,7 @@ class ACIDTest extends Scope $transactionId2 = $transaction2['body']['$id']; // Transaction 2: update status to declined - $this->client->call(Client::METHOD_POST, "/vectordb/transactions/{$transactionId2}/operations", array_merge([ + $this->client->call(Client::METHOD_POST, "/vectorsdb/transactions/{$transactionId2}/operations", array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -371,7 +371,7 @@ class ACIDTest extends Scope ]); // Commit second transaction and ensure isolation guarantees - $response2 = $this->client->call(Client::METHOD_PATCH, "/vectordb/transactions/{$transactionId2}", array_merge([ + $response2 = $this->client->call(Client::METHOD_PATCH, "/vectorsdb/transactions/{$transactionId2}", array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -382,7 +382,7 @@ class ACIDTest extends Scope $this->assertEquals(200, $response2['headers']['status-code']); // Final document should reflect the second transaction's update - $document = $this->client->call(Client::METHOD_GET, "/vectordb/{$databaseId}/collections/{$collectionId}/documents/shared_doc", array_merge([ + $document = $this->client->call(Client::METHOD_GET, "/vectorsdb/{$databaseId}/collections/{$collectionId}/documents/shared_doc", array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders())); @@ -396,7 +396,7 @@ class ACIDTest extends Scope public function testDurability(): void { // Create database - $database = $this->client->call(Client::METHOD_POST, '/vectordb', array_merge([ + $database = $this->client->call(Client::METHOD_POST, '/vectorsdb', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -409,7 +409,7 @@ class ACIDTest extends Scope $databaseId = $database['body']['$id']; // Create collection - $collection = $this->client->call(Client::METHOD_POST, '/vectordb/' . $databaseId . '/collections', array_merge([ + $collection = $this->client->call(Client::METHOD_POST, '/vectorsdb/' . $databaseId . '/collections', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -430,7 +430,7 @@ class ACIDTest extends Scope $collectionId = $collection['body']['$id']; // Create transaction with multiple operations - $transaction = $this->client->call(Client::METHOD_POST, '/vectordb/transactions', array_merge([ + $transaction = $this->client->call(Client::METHOD_POST, '/vectorsdb/transactions', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -441,7 +441,7 @@ class ACIDTest extends Scope $transactionId = $transaction['body']['$id']; // Create two documents via normal route inside transaction - $this->client->call(Client::METHOD_POST, "/vectordb/{$databaseId}/collections/{$collectionId}/documents", array_merge([ + $this->client->call(Client::METHOD_POST, "/vectorsdb/{$databaseId}/collections/{$collectionId}/documents", array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -462,7 +462,7 @@ class ACIDTest extends Scope ]); // Update first document inside the same transaction - $this->client->call(Client::METHOD_PATCH, "/vectordb/{$databaseId}/collections/{$collectionId}/documents/durable_doc_1", array_merge([ + $this->client->call(Client::METHOD_PATCH, "/vectorsdb/{$databaseId}/collections/{$collectionId}/documents/durable_doc_1", array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -474,7 +474,7 @@ class ACIDTest extends Scope ]); // Commit transaction - $response = $this->client->call(Client::METHOD_PATCH, "/vectordb/transactions/{$transactionId}", array_merge([ + $response = $this->client->call(Client::METHOD_PATCH, "/vectorsdb/transactions/{$transactionId}", array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -486,14 +486,14 @@ class ACIDTest extends Scope $this->assertEquals('committed', $response['body']['status']); // Verify documents exist and have correct data - $document1 = $this->client->call(Client::METHOD_GET, "/vectordb/{$databaseId}/collections/{$collectionId}/documents/durable_doc_1", array_merge([ + $document1 = $this->client->call(Client::METHOD_GET, "/vectorsdb/{$databaseId}/collections/{$collectionId}/documents/durable_doc_1", array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders())); $this->assertEquals(200, $document1['headers']['status-code']); $this->assertEquals('Updated important data 1', $document1['body']['metadata']['data']); - $document2 = $this->client->call(Client::METHOD_GET, "/vectordb/{$databaseId}/collections/{$collectionId}/documents/durable_doc_2", array_merge([ + $document2 = $this->client->call(Client::METHOD_GET, "/vectorsdb/{$databaseId}/collections/{$collectionId}/documents/durable_doc_2", array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders())); @@ -501,7 +501,7 @@ class ACIDTest extends Scope $this->assertEquals('Important data 2', $document2['body']['metadata']['data']); // Further update outside transaction to ensure persistence - $update = $this->client->call(Client::METHOD_PATCH, "/vectordb/{$databaseId}/collections/{$collectionId}/documents/durable_doc_1", array_merge([ + $update = $this->client->call(Client::METHOD_PATCH, "/vectorsdb/{$databaseId}/collections/{$collectionId}/documents/durable_doc_1", array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders()), [ @@ -512,14 +512,14 @@ class ACIDTest extends Scope $this->assertEquals(200, $update['headers']['status-code']); // Verify the update persisted - $document1 = $this->client->call(Client::METHOD_GET, "/vectordb/{$databaseId}/collections/{$collectionId}/documents/durable_doc_1", array_merge([ + $document1 = $this->client->call(Client::METHOD_GET, "/vectorsdb/{$databaseId}/collections/{$collectionId}/documents/durable_doc_1", array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders())); $this->assertEquals('Modified outside transaction', $document1['body']['metadata']['data']); // List all documents to verify total count - $documents = $this->client->call(Client::METHOD_GET, "/vectordb/{$databaseId}/collections/{$collectionId}/documents", array_merge([ + $documents = $this->client->call(Client::METHOD_GET, "/vectorsdb/{$databaseId}/collections/{$collectionId}/documents", array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders())); diff --git a/tests/e2e/Services/Databases/VectorDB/Transactions/TransactionsBase.php b/tests/e2e/Services/Databases/VectorsDB/Transactions/TransactionsBase.php similarity index 90% rename from tests/e2e/Services/Databases/VectorDB/Transactions/TransactionsBase.php rename to tests/e2e/Services/Databases/VectorsDB/Transactions/TransactionsBase.php index 6fe6c9e3f7..70150a3bc8 100644 --- a/tests/e2e/Services/Databases/VectorDB/Transactions/TransactionsBase.php +++ b/tests/e2e/Services/Databases/VectorsDB/Transactions/TransactionsBase.php @@ -1,6 +1,6 @@ client->call(Client::METHOD_POST, '/vectordb', array_merge([ + $database = $this->client->call(Client::METHOD_POST, '/vectorsdb', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -39,7 +39,7 @@ trait TransactionsBase $databaseId = $database['body']['$id']; // Test creating a transaction with default TTL - $response = $this->client->call(Client::METHOD_POST, '/vectordb/transactions', array_merge([ + $response = $this->client->call(Client::METHOD_POST, '/vectorsdb/transactions', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders())); @@ -55,7 +55,7 @@ trait TransactionsBase $transactionId1 = $response['body']['$id']; // Test creating a transaction with custom TTL - $response = $this->client->call(Client::METHOD_POST, '/vectordb/transactions', array_merge([ + $response = $this->client->call(Client::METHOD_POST, '/vectorsdb/transactions', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders()), [ @@ -74,7 +74,7 @@ trait TransactionsBase $transactionId2 = $response['body']['$id']; // Test invalid TTL values - $response = $this->client->call(Client::METHOD_POST, '/vectordb/transactions', array_merge([ + $response = $this->client->call(Client::METHOD_POST, '/vectorsdb/transactions', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders()), [ @@ -83,7 +83,7 @@ trait TransactionsBase $this->assertEquals(400, $response['headers']['status-code']); - $response = $this->client->call(Client::METHOD_POST, '/vectordb/transactions', array_merge([ + $response = $this->client->call(Client::METHOD_POST, '/vectorsdb/transactions', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders()), [ @@ -99,7 +99,7 @@ trait TransactionsBase public function testCreateOperations(): void { // Create database first - $database = $this->client->call(Client::METHOD_POST, '/vectordb', array_merge([ + $database = $this->client->call(Client::METHOD_POST, '/vectorsdb', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -112,7 +112,7 @@ trait TransactionsBase $databaseId = $database['body']['$id']; // Create transaction - $transaction = $this->client->call(Client::METHOD_POST, '/vectordb/transactions', array_merge([ + $transaction = $this->client->call(Client::METHOD_POST, '/vectorsdb/transactions', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders())); @@ -121,7 +121,7 @@ trait TransactionsBase $transactionId = $transaction['body']['$id']; // Create a collection for testing - $collection = $this->client->call(Client::METHOD_POST, '/vectordb/' . $databaseId . '/collections', array_merge([ + $collection = $this->client->call(Client::METHOD_POST, '/vectorsdb/' . $databaseId . '/collections', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -142,7 +142,7 @@ trait TransactionsBase $collectionId = $collection['body']['$id']; // Add valid operations - $response = $this->client->call(Client::METHOD_POST, "/vectordb/transactions/{$transactionId}/operations", array_merge([ + $response = $this->client->call(Client::METHOD_POST, "/vectorsdb/transactions/{$transactionId}/operations", array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -175,7 +175,7 @@ trait TransactionsBase $this->assertEquals(2, $response['body']['operations']); // Test adding more operations - $response = $this->client->call(Client::METHOD_POST, "/vectordb/transactions/{$transactionId}/operations", array_merge([ + $response = $this->client->call(Client::METHOD_POST, "/vectorsdb/transactions/{$transactionId}/operations", array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -197,7 +197,7 @@ trait TransactionsBase $this->assertEquals(3, $response['body']['operations']); // Test invalid database ID - $response = $this->client->call(Client::METHOD_POST, "/vectordb/transactions/{$transactionId}/operations", array_merge([ + $response = $this->client->call(Client::METHOD_POST, "/vectorsdb/transactions/{$transactionId}/operations", array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -219,7 +219,7 @@ trait TransactionsBase $this->assertEquals(404, $response['headers']['status-code'], 'Invalid database should return 404. Got: ' . json_encode($response['body'])); // Test invalid collection ID - $response = $this->client->call(Client::METHOD_POST, "/vectordb/transactions/{$transactionId}/operations", array_merge([ + $response = $this->client->call(Client::METHOD_POST, "/vectorsdb/transactions/{$transactionId}/operations", array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -247,7 +247,7 @@ trait TransactionsBase public function testCommit(): void { // Create database first - $database = $this->client->call(Client::METHOD_POST, '/vectordb', array_merge([ + $database = $this->client->call(Client::METHOD_POST, '/vectorsdb', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -260,7 +260,7 @@ trait TransactionsBase $databaseId = $database['body']['$id']; // Create collection - $collection = $this->client->call(Client::METHOD_POST, '/vectordb/' . $databaseId . '/collections', array_merge([ + $collection = $this->client->call(Client::METHOD_POST, '/vectorsdb/' . $databaseId . '/collections', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -281,7 +281,7 @@ trait TransactionsBase $collectionId = $collection['body']['$id']; // Create transaction - $transaction = $this->client->call(Client::METHOD_POST, '/vectordb/transactions', array_merge([ + $transaction = $this->client->call(Client::METHOD_POST, '/vectorsdb/transactions', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders())); @@ -290,7 +290,7 @@ trait TransactionsBase $transactionId = $transaction['body']['$id']; // Add operations - $response = $this->client->call(Client::METHOD_POST, "/vectordb/transactions/{$transactionId}/operations", array_merge([ + $response = $this->client->call(Client::METHOD_POST, "/vectorsdb/transactions/{$transactionId}/operations", array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -332,7 +332,7 @@ trait TransactionsBase $this->assertEquals(3, $response['body']['operations']); // Commit the transaction - $response = $this->client->call(Client::METHOD_PATCH, "/vectordb/transactions/{$transactionId}", array_merge([ + $response = $this->client->call(Client::METHOD_PATCH, "/vectorsdb/transactions/{$transactionId}", array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -344,7 +344,7 @@ trait TransactionsBase $this->assertEquals('committed', $response['body']['status']); // Verify documents were created - $documents = $this->client->call(Client::METHOD_GET, "/vectordb/{$databaseId}/collections/{$collectionId}/documents", array_merge([ + $documents = $this->client->call(Client::METHOD_GET, "/vectorsdb/{$databaseId}/collections/{$collectionId}/documents", array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders())); @@ -363,7 +363,7 @@ trait TransactionsBase $this->assertTrue($doc1Found, 'Document doc1 should exist with updated name'); // Test committing already committed transaction - $response = $this->client->call(Client::METHOD_PATCH, "/vectordb/transactions/{$transactionId}", array_merge([ + $response = $this->client->call(Client::METHOD_PATCH, "/vectorsdb/transactions/{$transactionId}", array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -380,7 +380,7 @@ trait TransactionsBase public function testRollback(): void { // Create database first - $database = $this->client->call(Client::METHOD_POST, '/vectordb', array_merge([ + $database = $this->client->call(Client::METHOD_POST, '/vectorsdb', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -393,7 +393,7 @@ trait TransactionsBase $databaseId = $database['body']['$id']; // Create transaction - $transaction = $this->client->call(Client::METHOD_POST, '/vectordb/transactions', array_merge([ + $transaction = $this->client->call(Client::METHOD_POST, '/vectorsdb/transactions', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders())); @@ -402,7 +402,7 @@ trait TransactionsBase $transactionId = $transaction['body']['$id']; // Create a collection for rollback test - $collection = $this->client->call(Client::METHOD_POST, '/vectordb/' . $databaseId . '/collections', array_merge([ + $collection = $this->client->call(Client::METHOD_POST, '/vectorsdb/' . $databaseId . '/collections', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -422,7 +422,7 @@ trait TransactionsBase $collectionId = $collection['body']['$id']; // Add operations - $response = $this->client->call(Client::METHOD_POST, "/vectordb/transactions/{$transactionId}/operations", array_merge([ + $response = $this->client->call(Client::METHOD_POST, "/vectorsdb/transactions/{$transactionId}/operations", array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -444,7 +444,7 @@ trait TransactionsBase $this->assertEquals(201, $response['headers']['status-code']); // Rollback the transaction - $response = $this->client->call(Client::METHOD_PATCH, "/vectordb/transactions/{$transactionId}", array_merge([ + $response = $this->client->call(Client::METHOD_PATCH, "/vectorsdb/transactions/{$transactionId}", array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -456,7 +456,7 @@ trait TransactionsBase $this->assertEquals('failed', $response['body']['status']); // Verify no documents were created - $documents = $this->client->call(Client::METHOD_GET, "/vectordb/{$databaseId}/collections/{$collectionId}/documents", array_merge([ + $documents = $this->client->call(Client::METHOD_GET, "/vectorsdb/{$databaseId}/collections/{$collectionId}/documents", array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders())); @@ -471,7 +471,7 @@ trait TransactionsBase public function testTransactionExpiration(): void { // Create database and collection - $database = $this->client->call(Client::METHOD_POST, '/vectordb', array_merge([ + $database = $this->client->call(Client::METHOD_POST, '/vectorsdb', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -482,7 +482,7 @@ trait TransactionsBase $databaseId = $database['body']['$id']; - $collection = $this->client->call(Client::METHOD_POST, "/vectordb/{$databaseId}/collections", array_merge([ + $collection = $this->client->call(Client::METHOD_POST, "/vectorsdb/{$databaseId}/collections", array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -501,7 +501,7 @@ trait TransactionsBase $collectionId = $collection['body']['$id']; // Create transaction with minimum TTL (60 seconds) - $transaction = $this->client->call(Client::METHOD_POST, '/vectordb/transactions', array_merge([ + $transaction = $this->client->call(Client::METHOD_POST, '/vectorsdb/transactions', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders()), [ @@ -512,7 +512,7 @@ trait TransactionsBase $transactionId = $transaction['body']['$id']; // Add operation - $response = $this->client->call(Client::METHOD_POST, "/vectordb/transactions/{$transactionId}/operations", array_merge([ + $response = $this->client->call(Client::METHOD_POST, "/vectorsdb/transactions/{$transactionId}/operations", array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -534,7 +534,7 @@ trait TransactionsBase $this->assertEquals(201, $response['headers']['status-code']); // Verify transaction was created with correct expiration - $txnDetails = $this->client->call(Client::METHOD_GET, "/vectordb/transactions/{$transactionId}", array_merge([ + $txnDetails = $this->client->call(Client::METHOD_GET, "/vectorsdb/transactions/{$transactionId}", array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -557,7 +557,7 @@ trait TransactionsBase public function testTransactionSizeLimit(): void { // Create database and collection - $database = $this->client->call(Client::METHOD_POST, '/vectordb', array_merge([ + $database = $this->client->call(Client::METHOD_POST, '/vectorsdb', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -568,7 +568,7 @@ trait TransactionsBase $databaseId = $database['body']['$id']; - $collection = $this->client->call(Client::METHOD_POST, "/vectordb/{$databaseId}/collections", array_merge([ + $collection = $this->client->call(Client::METHOD_POST, "/vectorsdb/{$databaseId}/collections", array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -582,7 +582,7 @@ trait TransactionsBase $collectionId = $collection['body']['$id']; // Create transaction - $transaction = $this->client->call(Client::METHOD_POST, '/vectordb/transactions', array_merge([ + $transaction = $this->client->call(Client::METHOD_POST, '/vectorsdb/transactions', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders())); @@ -606,7 +606,7 @@ trait TransactionsBase } // First batch should succeed - $response = $this->client->call(Client::METHOD_POST, "/vectordb/transactions/{$transactionId}/operations", array_merge([ + $response = $this->client->call(Client::METHOD_POST, "/vectorsdb/transactions/{$transactionId}/operations", array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -632,7 +632,7 @@ trait TransactionsBase ]; } - $response = $this->client->call(Client::METHOD_POST, "/vectordb/transactions/{$transactionId}/operations", array_merge([ + $response = $this->client->call(Client::METHOD_POST, "/vectorsdb/transactions/{$transactionId}/operations", array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -644,7 +644,7 @@ trait TransactionsBase $this->assertEquals(100, $response['body']['operations']); // Try to add one more operation - should fail - $response = $this->client->call(Client::METHOD_POST, "/vectordb/transactions/{$transactionId}/operations", array_merge([ + $response = $this->client->call(Client::METHOD_POST, "/vectorsdb/transactions/{$transactionId}/operations", array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -672,7 +672,7 @@ trait TransactionsBase public function testConcurrentTransactionConflicts(): void { // Create database and collection - $database = $this->client->call(Client::METHOD_POST, '/vectordb', array_merge([ + $database = $this->client->call(Client::METHOD_POST, '/vectorsdb', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -683,7 +683,7 @@ trait TransactionsBase $databaseId = $database['body']['$id']; - $collection = $this->client->call(Client::METHOD_POST, "/vectordb/{$databaseId}/collections", array_merge([ + $collection = $this->client->call(Client::METHOD_POST, "/vectorsdb/{$databaseId}/collections", array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -701,7 +701,7 @@ trait TransactionsBase $collectionId = $collection['body']['$id']; // Create initial document - $doc = $this->client->call(Client::METHOD_POST, "/vectordb/{$databaseId}/collections/{$collectionId}/documents", array_merge([ + $doc = $this->client->call(Client::METHOD_POST, "/vectorsdb/{$databaseId}/collections/{$collectionId}/documents", array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -716,12 +716,12 @@ trait TransactionsBase $this->assertEquals(201, $doc['headers']['status-code']); // Create two transactions - $txn1 = $this->client->call(Client::METHOD_POST, '/vectordb/transactions', array_merge([ + $txn1 = $this->client->call(Client::METHOD_POST, '/vectorsdb/transactions', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders())); - $txn2 = $this->client->call(Client::METHOD_POST, '/vectordb/transactions', array_merge([ + $txn2 = $this->client->call(Client::METHOD_POST, '/vectorsdb/transactions', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders())); @@ -730,7 +730,7 @@ trait TransactionsBase $transactionId2 = $txn2['body']['$id']; // Both transactions try to update the same document - $this->client->call(Client::METHOD_POST, "/vectordb/transactions/{$transactionId1}/operations", array_merge([ + $this->client->call(Client::METHOD_POST, "/vectorsdb/transactions/{$transactionId1}/operations", array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -748,7 +748,7 @@ trait TransactionsBase ] ]); - $this->client->call(Client::METHOD_POST, "/vectordb/transactions/{$transactionId2}/operations", array_merge([ + $this->client->call(Client::METHOD_POST, "/vectorsdb/transactions/{$transactionId2}/operations", array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -767,7 +767,7 @@ trait TransactionsBase ]); // Commit first transaction - $response1 = $this->client->call(Client::METHOD_PATCH, "/vectordb/transactions/{$transactionId1}", array_merge([ + $response1 = $this->client->call(Client::METHOD_PATCH, "/vectorsdb/transactions/{$transactionId1}", array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -778,7 +778,7 @@ trait TransactionsBase $this->assertEquals(200, $response1['headers']['status-code']); // Commit second transaction - should fail with conflict - $response2 = $this->client->call(Client::METHOD_PATCH, "/vectordb/transactions/{$transactionId2}", array_merge([ + $response2 = $this->client->call(Client::METHOD_PATCH, "/vectorsdb/transactions/{$transactionId2}", array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -789,7 +789,7 @@ trait TransactionsBase $this->assertEquals(409, $response2['headers']['status-code']); // Conflict // Verify the document has the value from first transaction - $doc = $this->client->call(Client::METHOD_GET, "/vectordb/{$databaseId}/collections/{$collectionId}/documents/shared_doc", array_merge([ + $doc = $this->client->call(Client::METHOD_GET, "/vectorsdb/{$databaseId}/collections/{$collectionId}/documents/shared_doc", array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders())); @@ -803,7 +803,7 @@ trait TransactionsBase public function testDeleteDocumentDuringTransaction(): void { // Create database and collection - $database = $this->client->call(Client::METHOD_POST, '/vectordb', array_merge([ + $database = $this->client->call(Client::METHOD_POST, '/vectorsdb', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -814,7 +814,7 @@ trait TransactionsBase $databaseId = $database['body']['$id']; - $collection = $this->client->call(Client::METHOD_POST, "/vectordb/{$databaseId}/collections", array_merge([ + $collection = $this->client->call(Client::METHOD_POST, "/vectorsdb/{$databaseId}/collections", array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -833,7 +833,7 @@ trait TransactionsBase $collectionId = $collection['body']['$id']; // Create document - $doc = $this->client->call(Client::METHOD_POST, "/vectordb/{$databaseId}/collections/{$collectionId}/documents", array_merge([ + $doc = $this->client->call(Client::METHOD_POST, "/vectorsdb/{$databaseId}/collections/{$collectionId}/documents", array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -848,7 +848,7 @@ trait TransactionsBase $this->assertEquals(201, $doc['headers']['status-code']); // Create transaction - $transaction = $this->client->call(Client::METHOD_POST, '/vectordb/transactions', array_merge([ + $transaction = $this->client->call(Client::METHOD_POST, '/vectorsdb/transactions', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders())); @@ -856,7 +856,7 @@ trait TransactionsBase $transactionId = $transaction['body']['$id']; // Add update operation to transaction - $this->client->call(Client::METHOD_POST, "/vectordb/transactions/{$transactionId}/operations", array_merge([ + $this->client->call(Client::METHOD_POST, "/vectorsdb/transactions/{$transactionId}/operations", array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -875,7 +875,7 @@ trait TransactionsBase ]); // Delete the document outside of transaction - $response = $this->client->call(Client::METHOD_DELETE, "/vectordb/{$databaseId}/collections/{$collectionId}/documents/target_doc", array_merge([ + $response = $this->client->call(Client::METHOD_DELETE, "/vectorsdb/{$databaseId}/collections/{$collectionId}/documents/target_doc", array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -884,7 +884,7 @@ trait TransactionsBase $this->assertEquals(204, $response['headers']['status-code']); // Try to commit transaction - should fail because document no longer exists - $response = $this->client->call(Client::METHOD_PATCH, "/vectordb/transactions/{$transactionId}", array_merge([ + $response = $this->client->call(Client::METHOD_PATCH, "/vectorsdb/transactions/{$transactionId}", array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -901,7 +901,7 @@ trait TransactionsBase public function testBulkOperations(): void { // Create database and collection - $database = $this->client->call(Client::METHOD_POST, '/vectordb', array_merge([ + $database = $this->client->call(Client::METHOD_POST, '/vectorsdb', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -912,7 +912,7 @@ trait TransactionsBase $databaseId = $database['body']['$id']; - $collection = $this->client->call(Client::METHOD_POST, "/vectordb/{$databaseId}/collections", array_merge([ + $collection = $this->client->call(Client::METHOD_POST, "/vectorsdb/{$databaseId}/collections", array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -932,7 +932,7 @@ trait TransactionsBase // Create some initial documents for ($i = 1; $i <= 5; $i++) { - $this->client->call(Client::METHOD_POST, "/vectordb/{$databaseId}/collections/{$collectionId}/documents", array_merge([ + $this->client->call(Client::METHOD_POST, "/vectorsdb/{$databaseId}/collections/{$collectionId}/documents", array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -949,7 +949,7 @@ trait TransactionsBase } // Create transaction - $transaction = $this->client->call(Client::METHOD_POST, '/vectordb/transactions', array_merge([ + $transaction = $this->client->call(Client::METHOD_POST, '/vectorsdb/transactions', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders())); @@ -957,7 +957,7 @@ trait TransactionsBase $transactionId = $transaction['body']['$id']; // Add bulk operations - $response = $this->client->call(Client::METHOD_POST, "/vectordb/transactions/{$transactionId}/operations", array_merge([ + $response = $this->client->call(Client::METHOD_POST, "/vectorsdb/transactions/{$transactionId}/operations", array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -1011,7 +1011,7 @@ trait TransactionsBase $this->assertEquals(201, $response['headers']['status-code']); // Commit transaction - $response = $this->client->call(Client::METHOD_PATCH, "/vectordb/transactions/{$transactionId}", array_merge([ + $response = $this->client->call(Client::METHOD_PATCH, "/vectorsdb/transactions/{$transactionId}", array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -1022,7 +1022,7 @@ trait TransactionsBase $this->assertEquals(200, $response['headers']['status-code']); // Verify results - $documents = $this->client->call(Client::METHOD_GET, "/vectordb/{$databaseId}/collections/{$collectionId}/documents", array_merge([ + $documents = $this->client->call(Client::METHOD_GET, "/vectorsdb/{$databaseId}/collections/{$collectionId}/documents", array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders())); @@ -1061,7 +1061,7 @@ trait TransactionsBase public function testPartialFailureRollback(): void { // Create database and collection - $database = $this->client->call(Client::METHOD_POST, '/vectordb', array_merge([ + $database = $this->client->call(Client::METHOD_POST, '/vectorsdb', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -1072,7 +1072,7 @@ trait TransactionsBase $databaseId = $database['body']['$id']; - $collection = $this->client->call(Client::METHOD_POST, "/vectordb/{$databaseId}/collections", array_merge([ + $collection = $this->client->call(Client::METHOD_POST, "/vectorsdb/{$databaseId}/collections", array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -1089,7 +1089,7 @@ trait TransactionsBase $collectionId = $collection['body']['$id']; // Create HNSW index on embeddings - $this->client->call(Client::METHOD_POST, "/vectordb/{$databaseId}/collections/{$collectionId}/indexes", array_merge([ + $this->client->call(Client::METHOD_POST, "/vectorsdb/{$databaseId}/collections/{$collectionId}/indexes", array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -1103,7 +1103,7 @@ trait TransactionsBase // Create an existing document $duplicateId = ID::unique(); - $this->client->call(Client::METHOD_POST, "/vectordb/{$databaseId}/collections/{$collectionId}/documents", array_merge([ + $this->client->call(Client::METHOD_POST, "/vectorsdb/{$databaseId}/collections/{$collectionId}/documents", array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -1116,7 +1116,7 @@ trait TransactionsBase ]); // Create transaction - $transaction = $this->client->call(Client::METHOD_POST, '/vectordb/transactions', array_merge([ + $transaction = $this->client->call(Client::METHOD_POST, '/vectorsdb/transactions', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders())); @@ -1124,7 +1124,7 @@ trait TransactionsBase $transactionId = $transaction['body']['$id']; // Add operations - mix of valid and invalid (duplicate id) - $response = $this->client->call(Client::METHOD_POST, "/vectordb/transactions/{$transactionId}/operations", array_merge([ + $response = $this->client->call(Client::METHOD_POST, "/vectorsdb/transactions/{$transactionId}/operations", array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -1176,7 +1176,7 @@ trait TransactionsBase $this->assertEquals(201, $response['headers']['status-code']); // Try to commit - should fail and rollback all operations - $response = $this->client->call(Client::METHOD_PATCH, "/vectordb/transactions/{$transactionId}", array_merge([ + $response = $this->client->call(Client::METHOD_PATCH, "/vectorsdb/transactions/{$transactionId}", array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -1187,7 +1187,7 @@ trait TransactionsBase $this->assertEquals(409, $response['headers']['status-code']); // Conflict due to duplicate // Verify NO new documents were created (atomicity) - $documents = $this->client->call(Client::METHOD_GET, "/vectordb/{$databaseId}/collections/{$collectionId}/documents", array_merge([ + $documents = $this->client->call(Client::METHOD_GET, "/vectorsdb/{$databaseId}/collections/{$collectionId}/documents", array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders())); @@ -1202,7 +1202,7 @@ trait TransactionsBase public function testDoubleCommitRollback(): void { // Create database and collection - $database = $this->client->call(Client::METHOD_POST, '/vectordb', array_merge([ + $database = $this->client->call(Client::METHOD_POST, '/vectorsdb', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -1213,7 +1213,7 @@ trait TransactionsBase $databaseId = $database['body']['$id']; - $collection = $this->client->call(Client::METHOD_POST, "/vectordb/{$databaseId}/collections", array_merge([ + $collection = $this->client->call(Client::METHOD_POST, "/vectorsdb/{$databaseId}/collections", array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -1227,7 +1227,7 @@ trait TransactionsBase $collectionId = $collection['body']['$id']; // Test double commit - $transaction = $this->client->call(Client::METHOD_POST, '/vectordb/transactions', array_merge([ + $transaction = $this->client->call(Client::METHOD_POST, '/vectorsdb/transactions', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders())); @@ -1235,7 +1235,7 @@ trait TransactionsBase $transactionId = $transaction['body']['$id']; // Add operation - $this->client->call(Client::METHOD_POST, "/vectordb/transactions/{$transactionId}/operations", array_merge([ + $this->client->call(Client::METHOD_POST, "/vectorsdb/transactions/{$transactionId}/operations", array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -1255,7 +1255,7 @@ trait TransactionsBase ]); // First commit - $response = $this->client->call(Client::METHOD_PATCH, "/vectordb/transactions/{$transactionId}", array_merge([ + $response = $this->client->call(Client::METHOD_PATCH, "/vectorsdb/transactions/{$transactionId}", array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -1266,7 +1266,7 @@ trait TransactionsBase $this->assertEquals(200, $response['headers']['status-code']); // Second commit attempt - should fail - $response = $this->client->call(Client::METHOD_PATCH, "/vectordb/transactions/{$transactionId}", array_merge([ + $response = $this->client->call(Client::METHOD_PATCH, "/vectorsdb/transactions/{$transactionId}", array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -1277,7 +1277,7 @@ trait TransactionsBase $this->assertEquals(400, $response['headers']['status-code']); // Bad request - already committed // Test double rollback - $transaction2 = $this->client->call(Client::METHOD_POST, '/vectordb/transactions', array_merge([ + $transaction2 = $this->client->call(Client::METHOD_POST, '/vectorsdb/transactions', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders())); @@ -1285,7 +1285,7 @@ trait TransactionsBase $transactionId2 = $transaction2['body']['$id']; // First rollback - $response = $this->client->call(Client::METHOD_PATCH, "/vectordb/transactions/{$transactionId2}", array_merge([ + $response = $this->client->call(Client::METHOD_PATCH, "/vectorsdb/transactions/{$transactionId2}", array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -1296,7 +1296,7 @@ trait TransactionsBase $this->assertEquals(200, $response['headers']['status-code']); // Second rollback attempt - should fail - $response = $this->client->call(Client::METHOD_PATCH, "/vectordb/transactions/{$transactionId2}", array_merge([ + $response = $this->client->call(Client::METHOD_PATCH, "/vectorsdb/transactions/{$transactionId2}", array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -1313,7 +1313,7 @@ trait TransactionsBase public function testOperationsOnNonExistentDocuments(): void { // Create database and collection - $database = $this->client->call(Client::METHOD_POST, '/vectordb', array_merge([ + $database = $this->client->call(Client::METHOD_POST, '/vectorsdb', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -1324,7 +1324,7 @@ trait TransactionsBase $databaseId = $database['body']['$id']; - $collection = $this->client->call(Client::METHOD_POST, "/vectordb/{$databaseId}/collections", array_merge([ + $collection = $this->client->call(Client::METHOD_POST, "/vectorsdb/{$databaseId}/collections", array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -1342,7 +1342,7 @@ trait TransactionsBase $collectionId = $collection['body']['$id']; // Create transaction - $transaction = $this->client->call(Client::METHOD_POST, '/vectordb/transactions', array_merge([ + $transaction = $this->client->call(Client::METHOD_POST, '/vectorsdb/transactions', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders())); @@ -1350,7 +1350,7 @@ trait TransactionsBase $transactionId = $transaction['body']['$id']; // Try to update non-existent document - should fail at staging time with early validation - $response = $this->client->call(Client::METHOD_POST, "/vectordb/transactions/{$transactionId}/operations", array_merge([ + $response = $this->client->call(Client::METHOD_POST, "/vectorsdb/transactions/{$transactionId}/operations", array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -1371,14 +1371,14 @@ trait TransactionsBase $this->assertEquals(404, $response['headers']['status-code']); // Document not found at staging time // Test delete non-existent document - should also fail at staging time with early validation - $transaction2 = $this->client->call(Client::METHOD_POST, '/vectordb/transactions', array_merge([ + $transaction2 = $this->client->call(Client::METHOD_POST, '/vectorsdb/transactions', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders())); $transactionId2 = $transaction2['body']['$id']; - $response = $this->client->call(Client::METHOD_POST, "/vectordb/transactions/{$transactionId2}/operations", array_merge([ + $response = $this->client->call(Client::METHOD_POST, "/vectorsdb/transactions/{$transactionId2}/operations", array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -1403,7 +1403,7 @@ trait TransactionsBase public function testCreateDocument(): void { // Create database and collection - $database = $this->client->call(Client::METHOD_POST, '/vectordb', array_merge([ + $database = $this->client->call(Client::METHOD_POST, '/vectorsdb', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -1414,7 +1414,7 @@ trait TransactionsBase $databaseId = $database['body']['$id']; - $collection = $this->client->call(Client::METHOD_POST, "/vectordb/{$databaseId}/collections", array_merge([ + $collection = $this->client->call(Client::METHOD_POST, "/vectorsdb/{$databaseId}/collections", array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -1434,7 +1434,7 @@ trait TransactionsBase $collectionId = $collection['body']['$id']; // Create transaction - $transaction = $this->client->call(Client::METHOD_POST, '/vectordb/transactions', array_merge([ + $transaction = $this->client->call(Client::METHOD_POST, '/vectorsdb/transactions', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders())); @@ -1443,7 +1443,7 @@ trait TransactionsBase $transactionId = $transaction['body']['$id']; // Create document via normal route with transactionId - $response = $this->client->call(Client::METHOD_POST, "/vectordb/{$databaseId}/collections/{$collectionId}/documents", array_merge([ + $response = $this->client->call(Client::METHOD_POST, "/vectorsdb/{$databaseId}/collections/{$collectionId}/documents", array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -1463,7 +1463,7 @@ trait TransactionsBase $this->assertEquals(201, $response['headers']['status-code']); // Document should not exist outside transaction yet - $response = $this->client->call(Client::METHOD_GET, "/vectordb/{$databaseId}/collections/{$collectionId}/documents/doc_from_route", array_merge([ + $response = $this->client->call(Client::METHOD_GET, "/vectorsdb/{$databaseId}/collections/{$collectionId}/documents/doc_from_route", array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders())); @@ -1471,7 +1471,7 @@ trait TransactionsBase $this->assertEquals(404, $response['headers']['status-code']); // Commit transaction - $response = $this->client->call(Client::METHOD_PATCH, "/vectordb/transactions/{$transactionId}", array_merge([ + $response = $this->client->call(Client::METHOD_PATCH, "/vectorsdb/transactions/{$transactionId}", array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -1482,7 +1482,7 @@ trait TransactionsBase $this->assertEquals(200, $response['headers']['status-code']); // Document should now exist - $response = $this->client->call(Client::METHOD_GET, "/vectordb/{$databaseId}/collections/{$collectionId}/documents/doc_from_route", array_merge([ + $response = $this->client->call(Client::METHOD_GET, "/vectorsdb/{$databaseId}/collections/{$collectionId}/documents/doc_from_route", array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders())); @@ -1497,7 +1497,7 @@ trait TransactionsBase public function testUpdateDocument(): void { // Create database and collection - $database = $this->client->call(Client::METHOD_POST, '/vectordb', array_merge([ + $database = $this->client->call(Client::METHOD_POST, '/vectorsdb', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -1508,7 +1508,7 @@ trait TransactionsBase $databaseId = $database['body']['$id']; - $collection = $this->client->call(Client::METHOD_POST, "/vectordb/{$databaseId}/collections", array_merge([ + $collection = $this->client->call(Client::METHOD_POST, "/vectorsdb/{$databaseId}/collections", array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -1526,7 +1526,7 @@ trait TransactionsBase $collectionId = $collection['body']['$id']; // Create document outside transaction - $doc = $this->client->call(Client::METHOD_POST, "/vectordb/{$databaseId}/collections/{$collectionId}/documents", array_merge([ + $doc = $this->client->call(Client::METHOD_POST, "/vectorsdb/{$databaseId}/collections/{$collectionId}/documents", array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -1545,7 +1545,7 @@ trait TransactionsBase $this->assertEquals(201, $doc['headers']['status-code']); // Create transaction - $transaction = $this->client->call(Client::METHOD_POST, '/vectordb/transactions', array_merge([ + $transaction = $this->client->call(Client::METHOD_POST, '/vectorsdb/transactions', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders())); @@ -1553,7 +1553,7 @@ trait TransactionsBase $transactionId = $transaction['body']['$id']; // Update document via normal route with transactionId - $response = $this->client->call(Client::METHOD_PATCH, "/vectordb/{$databaseId}/collections/{$collectionId}/documents/doc_to_update", array_merge([ + $response = $this->client->call(Client::METHOD_PATCH, "/vectorsdb/{$databaseId}/collections/{$collectionId}/documents/doc_to_update", array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -1571,7 +1571,7 @@ trait TransactionsBase $this->assertEquals(200, $response['headers']['status-code']); // Document should still have original values outside transaction - $response = $this->client->call(Client::METHOD_GET, "/vectordb/{$databaseId}/collections/{$collectionId}/documents/doc_to_update", array_merge([ + $response = $this->client->call(Client::METHOD_GET, "/vectorsdb/{$databaseId}/collections/{$collectionId}/documents/doc_to_update", array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders())); @@ -1580,7 +1580,7 @@ trait TransactionsBase $this->assertEquals(50, $response['body']['metadata']['counter']); // Commit transaction - $response = $this->client->call(Client::METHOD_PATCH, "/vectordb/transactions/{$transactionId}", array_merge([ + $response = $this->client->call(Client::METHOD_PATCH, "/vectorsdb/transactions/{$transactionId}", array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -1591,7 +1591,7 @@ trait TransactionsBase $this->assertEquals(200, $response['headers']['status-code']); // Document should now have updated values - $response = $this->client->call(Client::METHOD_GET, "/vectordb/{$databaseId}/collections/{$collectionId}/documents/doc_to_update", array_merge([ + $response = $this->client->call(Client::METHOD_GET, "/vectorsdb/{$databaseId}/collections/{$collectionId}/documents/doc_to_update", array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders())); @@ -1606,7 +1606,7 @@ trait TransactionsBase public function testUpsertDocument(): void { // Create database and collection - $database = $this->client->call(Client::METHOD_POST, '/vectordb', array_merge([ + $database = $this->client->call(Client::METHOD_POST, '/vectorsdb', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -1617,7 +1617,7 @@ trait TransactionsBase $databaseId = $database['body']['$id']; - $collection = $this->client->call(Client::METHOD_POST, "/vectordb/{$databaseId}/collections", array_merge([ + $collection = $this->client->call(Client::METHOD_POST, "/vectorsdb/{$databaseId}/collections", array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -1635,7 +1635,7 @@ trait TransactionsBase $collectionId = $collection['body']['$id']; // Create transaction - $transaction = $this->client->call(Client::METHOD_POST, '/vectordb/transactions', array_merge([ + $transaction = $this->client->call(Client::METHOD_POST, '/vectorsdb/transactions', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders())); @@ -1643,7 +1643,7 @@ trait TransactionsBase $transactionId = $transaction['body']['$id']; // Upsert document (create) via normal route with transactionId - $response = $this->client->call(Client::METHOD_PUT, "/vectordb/{$databaseId}/collections/{$collectionId}/documents/doc_upsert", array_merge([ + $response = $this->client->call(Client::METHOD_PUT, "/vectorsdb/{$databaseId}/collections/{$collectionId}/documents/doc_upsert", array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -1662,7 +1662,7 @@ trait TransactionsBase $this->assertEquals(201, $response['headers']['status-code']); // Document should not exist outside transaction yet - $response = $this->client->call(Client::METHOD_GET, "/vectordb/{$databaseId}/collections/{$collectionId}/documents/doc_upsert", array_merge([ + $response = $this->client->call(Client::METHOD_GET, "/vectorsdb/{$databaseId}/collections/{$collectionId}/documents/doc_upsert", array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders())); @@ -1670,7 +1670,7 @@ trait TransactionsBase $this->assertEquals(404, $response['headers']['status-code']); // Upsert same document (update) in same transaction - $response = $this->client->call(Client::METHOD_PUT, "/vectordb/{$databaseId}/collections/{$collectionId}/documents/doc_upsert", array_merge([ + $response = $this->client->call(Client::METHOD_PUT, "/vectorsdb/{$databaseId}/collections/{$collectionId}/documents/doc_upsert", array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -1688,7 +1688,7 @@ trait TransactionsBase $this->assertEquals(201, $response['headers']['status-code']); // Upsert in transaction returns 201 // Commit transaction - $response = $this->client->call(Client::METHOD_PATCH, "/vectordb/transactions/{$transactionId}", array_merge([ + $response = $this->client->call(Client::METHOD_PATCH, "/vectorsdb/transactions/{$transactionId}", array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -1699,7 +1699,7 @@ trait TransactionsBase $this->assertEquals(200, $response['headers']['status-code']); // Document should now exist with updated values - $response = $this->client->call(Client::METHOD_GET, "/vectordb/{$databaseId}/collections/{$collectionId}/documents/doc_upsert", array_merge([ + $response = $this->client->call(Client::METHOD_GET, "/vectorsdb/{$databaseId}/collections/{$collectionId}/documents/doc_upsert", array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders())); @@ -1715,7 +1715,7 @@ trait TransactionsBase public function testDeleteDocument(): void { // Create database and collection - $database = $this->client->call(Client::METHOD_POST, '/vectordb', array_merge([ + $database = $this->client->call(Client::METHOD_POST, '/vectorsdb', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -1726,7 +1726,7 @@ trait TransactionsBase $databaseId = $database['body']['$id']; - $collection = $this->client->call(Client::METHOD_POST, "/vectordb/{$databaseId}/collections", array_merge([ + $collection = $this->client->call(Client::METHOD_POST, "/vectorsdb/{$databaseId}/collections", array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -1744,7 +1744,7 @@ trait TransactionsBase $collectionId = $collection['body']['$id']; // Create document outside transaction - $doc = $this->client->call(Client::METHOD_POST, "/vectordb/{$databaseId}/collections/{$collectionId}/documents", array_merge([ + $doc = $this->client->call(Client::METHOD_POST, "/vectorsdb/{$databaseId}/collections/{$collectionId}/documents", array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -1759,7 +1759,7 @@ trait TransactionsBase $this->assertEquals(201, $doc['headers']['status-code']); // Create transaction - $transaction = $this->client->call(Client::METHOD_POST, '/vectordb/transactions', array_merge([ + $transaction = $this->client->call(Client::METHOD_POST, '/vectorsdb/transactions', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders())); @@ -1767,7 +1767,7 @@ trait TransactionsBase $transactionId = $transaction['body']['$id']; // Delete document via normal route with transactionId - $response = $this->client->call(Client::METHOD_DELETE, "/vectordb/{$databaseId}/collections/{$collectionId}/documents/doc_to_delete", array_merge([ + $response = $this->client->call(Client::METHOD_DELETE, "/vectorsdb/{$databaseId}/collections/{$collectionId}/documents/doc_to_delete", array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -1778,7 +1778,7 @@ trait TransactionsBase $this->assertEquals(204, $response['headers']['status-code']); // Document should still exist outside transaction - $response = $this->client->call(Client::METHOD_GET, "/vectordb/{$databaseId}/collections/{$collectionId}/documents/doc_to_delete", array_merge([ + $response = $this->client->call(Client::METHOD_GET, "/vectorsdb/{$databaseId}/collections/{$collectionId}/documents/doc_to_delete", array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders())); @@ -1786,7 +1786,7 @@ trait TransactionsBase $this->assertEquals(200, $response['headers']['status-code']); // Commit transaction - $response = $this->client->call(Client::METHOD_PATCH, "/vectordb/transactions/{$transactionId}", array_merge([ + $response = $this->client->call(Client::METHOD_PATCH, "/vectorsdb/transactions/{$transactionId}", array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -1797,7 +1797,7 @@ trait TransactionsBase $this->assertEquals(200, $response['headers']['status-code']); // Document should no longer exist - $response = $this->client->call(Client::METHOD_GET, "/vectordb/{$databaseId}/collections/{$collectionId}/documents/doc_to_delete", array_merge([ + $response = $this->client->call(Client::METHOD_GET, "/vectorsdb/{$databaseId}/collections/{$collectionId}/documents/doc_to_delete", array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders())); @@ -1811,7 +1811,7 @@ trait TransactionsBase public function testBulkCreate(): void { // Create database and collection - $database = $this->client->call(Client::METHOD_POST, '/vectordb', array_merge([ + $database = $this->client->call(Client::METHOD_POST, '/vectorsdb', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -1822,7 +1822,7 @@ trait TransactionsBase $databaseId = $database['body']['$id']; - $collection = $this->client->call(Client::METHOD_POST, "/vectordb/{$databaseId}/collections", array_merge([ + $collection = $this->client->call(Client::METHOD_POST, "/vectorsdb/{$databaseId}/collections", array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -1839,7 +1839,7 @@ trait TransactionsBase $collectionId = $collection['body']['$id']; // Create transaction - $transaction = $this->client->call(Client::METHOD_POST, '/vectordb/transactions', array_merge([ + $transaction = $this->client->call(Client::METHOD_POST, '/vectorsdb/transactions', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders())); @@ -1847,7 +1847,7 @@ trait TransactionsBase $transactionId = $transaction['body']['$id']; // Bulk create via normal route with transactionId - $response = $this->client->call(Client::METHOD_POST, "/vectordb/{$databaseId}/collections/{$collectionId}/documents", array_merge([ + $response = $this->client->call(Client::METHOD_POST, "/vectorsdb/{$databaseId}/collections/{$collectionId}/documents", array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -1884,7 +1884,7 @@ trait TransactionsBase $this->assertEquals(200, $response['headers']['status-code']); // Bulk operations return 200 // Documents should not exist outside transaction yet - $response = $this->client->call(Client::METHOD_GET, "/vectordb/{$databaseId}/collections/{$collectionId}/documents", array_merge([ + $response = $this->client->call(Client::METHOD_GET, "/vectorsdb/{$databaseId}/collections/{$collectionId}/documents", array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders()), [ @@ -1894,7 +1894,7 @@ trait TransactionsBase $this->assertEquals(0, $response['body']['total']); // Individual document check - $response = $this->client->call(Client::METHOD_GET, "/vectordb/{$databaseId}/collections/{$collectionId}/documents/bulk_create_1", array_merge([ + $response = $this->client->call(Client::METHOD_GET, "/vectorsdb/{$databaseId}/collections/{$collectionId}/documents/bulk_create_1", array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders())); @@ -1902,7 +1902,7 @@ trait TransactionsBase $this->assertEquals(404, $response['headers']['status-code']); // Commit transaction - $response = $this->client->call(Client::METHOD_PATCH, "/vectordb/transactions/{$transactionId}", array_merge([ + $response = $this->client->call(Client::METHOD_PATCH, "/vectorsdb/transactions/{$transactionId}", array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -1913,7 +1913,7 @@ trait TransactionsBase $this->assertEquals(200, $response['headers']['status-code']); // Documents should now exist - $response = $this->client->call(Client::METHOD_GET, "/vectordb/{$databaseId}/collections/{$collectionId}/documents", array_merge([ + $response = $this->client->call(Client::METHOD_GET, "/vectorsdb/{$databaseId}/collections/{$collectionId}/documents", array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders()), [ @@ -1924,7 +1924,7 @@ trait TransactionsBase // Verify individual documents for ($i = 1; $i <= 3; $i++) { - $response = $this->client->call(Client::METHOD_GET, "/vectordb/{$databaseId}/collections/{$collectionId}/documents/bulk_create_{$i}", array_merge([ + $response = $this->client->call(Client::METHOD_GET, "/vectorsdb/{$databaseId}/collections/{$collectionId}/documents/bulk_create_{$i}", array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders())); @@ -1941,7 +1941,7 @@ trait TransactionsBase public function testBulkUpdate(): void { // Create database and collection - $database = $this->client->call(Client::METHOD_POST, '/vectordb', array_merge([ + $database = $this->client->call(Client::METHOD_POST, '/vectorsdb', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -1952,7 +1952,7 @@ trait TransactionsBase $databaseId = $database['body']['$id']; - $collection = $this->client->call(Client::METHOD_POST, "/vectordb/{$databaseId}/collections", array_merge([ + $collection = $this->client->call(Client::METHOD_POST, "/vectorsdb/{$databaseId}/collections", array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -1971,7 +1971,7 @@ trait TransactionsBase // Create documents for bulk testing for ($i = 1; $i <= 3; $i++) { - $this->client->call(Client::METHOD_POST, "/vectordb/{$databaseId}/collections/{$collectionId}/documents", array_merge([ + $this->client->call(Client::METHOD_POST, "/vectorsdb/{$databaseId}/collections/{$collectionId}/documents", array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -1988,7 +1988,7 @@ trait TransactionsBase } // Create transaction - $transaction = $this->client->call(Client::METHOD_POST, '/vectordb/transactions', array_merge([ + $transaction = $this->client->call(Client::METHOD_POST, '/vectorsdb/transactions', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders())); @@ -1996,7 +1996,7 @@ trait TransactionsBase $transactionId = $transaction['body']['$id']; // Bulk update via normal route with transactionId - $response = $this->client->call(Client::METHOD_PATCH, "/vectordb/{$databaseId}/collections/{$collectionId}/documents", array_merge([ + $response = $this->client->call(Client::METHOD_PATCH, "/vectorsdb/{$databaseId}/collections/{$collectionId}/documents", array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -2009,7 +2009,7 @@ trait TransactionsBase $this->assertEquals(200, $response['headers']['status-code']); // Documents should still have original category outside transaction - $response = $this->client->call(Client::METHOD_GET, "/vectordb/{$databaseId}/collections/{$collectionId}/documents", array_merge([ + $response = $this->client->call(Client::METHOD_GET, "/vectorsdb/{$databaseId}/collections/{$collectionId}/documents", array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders()), [ @@ -2019,7 +2019,7 @@ trait TransactionsBase $this->assertEquals(3, $response['body']['total']); // Commit transaction - $response = $this->client->call(Client::METHOD_PATCH, "/vectordb/transactions/{$transactionId}", array_merge([ + $response = $this->client->call(Client::METHOD_PATCH, "/vectorsdb/transactions/{$transactionId}", array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -2030,7 +2030,7 @@ trait TransactionsBase $this->assertEquals(200, $response['headers']['status-code']); // Documents should now have updated category - $response = $this->client->call(Client::METHOD_GET, "/vectordb/{$databaseId}/collections/{$collectionId}/documents", array_merge([ + $response = $this->client->call(Client::METHOD_GET, "/vectorsdb/{$databaseId}/collections/{$collectionId}/documents", array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders()), [ @@ -2046,7 +2046,7 @@ trait TransactionsBase public function testBulkUpsert(): void { // Create database and collection - $database = $this->client->call(Client::METHOD_POST, '/vectordb', array_merge([ + $database = $this->client->call(Client::METHOD_POST, '/vectorsdb', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -2057,7 +2057,7 @@ trait TransactionsBase $databaseId = $database['body']['$id']; - $collection = $this->client->call(Client::METHOD_POST, "/vectordb/{$databaseId}/collections", array_merge([ + $collection = $this->client->call(Client::METHOD_POST, "/vectorsdb/{$databaseId}/collections", array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -2075,7 +2075,7 @@ trait TransactionsBase $collectionId = $collection['body']['$id']; // Create transaction - $transaction = $this->client->call(Client::METHOD_POST, '/vectordb/transactions', array_merge([ + $transaction = $this->client->call(Client::METHOD_POST, '/vectorsdb/transactions', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders())); @@ -2084,7 +2084,7 @@ trait TransactionsBase $transactionId = $transaction['body']['$id']; // Test 1: Invalid action type - $response = $this->client->call(Client::METHOD_POST, "/vectordb/transactions/{$transactionId}/operations", array_merge([ + $response = $this->client->call(Client::METHOD_POST, "/vectorsdb/transactions/{$transactionId}/operations", array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -2103,7 +2103,7 @@ trait TransactionsBase $this->assertEquals(400, $response['headers']['status-code']); // Test 2: Missing required action field - $response = $this->client->call(Client::METHOD_POST, "/vectordb/transactions/{$transactionId}/operations", array_merge([ + $response = $this->client->call(Client::METHOD_POST, "/vectorsdb/transactions/{$transactionId}/operations", array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -2121,7 +2121,7 @@ trait TransactionsBase $this->assertEquals(400, $response['headers']['status-code']); // Test 3: Missing required databaseId field - $response = $this->client->call(Client::METHOD_POST, "/vectordb/transactions/{$transactionId}/operations", array_merge([ + $response = $this->client->call(Client::METHOD_POST, "/vectorsdb/transactions/{$transactionId}/operations", array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -2139,7 +2139,7 @@ trait TransactionsBase $this->assertEquals(400, $response['headers']['status-code']); // Test 4: Missing documentId for create operation - $response = $this->client->call(Client::METHOD_POST, "/vectordb/transactions/{$transactionId}/operations", array_merge([ + $response = $this->client->call(Client::METHOD_POST, "/vectorsdb/transactions/{$transactionId}/operations", array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -2157,7 +2157,7 @@ trait TransactionsBase $this->assertEquals(400, $response['headers']['status-code']); // Test 5: Missing data for create operation - $response = $this->client->call(Client::METHOD_POST, "/vectordb/transactions/{$transactionId}/operations", array_merge([ + $response = $this->client->call(Client::METHOD_POST, "/vectorsdb/transactions/{$transactionId}/operations", array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -2175,7 +2175,7 @@ trait TransactionsBase $this->assertEquals(400, $response['headers']['status-code']); // Test 6: BulkCreate with non-array data - $response = $this->client->call(Client::METHOD_POST, "/vectordb/transactions/{$transactionId}/operations", array_merge([ + $response = $this->client->call(Client::METHOD_POST, "/vectorsdb/transactions/{$transactionId}/operations", array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -2193,7 +2193,7 @@ trait TransactionsBase $this->assertEquals(400, $response['headers']['status-code']); // Test 7: BulkUpdate with missing queries - $response = $this->client->call(Client::METHOD_POST, "/vectordb/transactions/{$transactionId}/operations", array_merge([ + $response = $this->client->call(Client::METHOD_POST, "/vectorsdb/transactions/{$transactionId}/operations", array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -2213,7 +2213,7 @@ trait TransactionsBase $this->assertEquals(400, $response['headers']['status-code']); // Test 8: Empty operations array - $response = $this->client->call(Client::METHOD_POST, "/vectordb/transactions/{$transactionId}/operations", array_merge([ + $response = $this->client->call(Client::METHOD_POST, "/vectorsdb/transactions/{$transactionId}/operations", array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -2224,7 +2224,7 @@ trait TransactionsBase $this->assertEquals(400, $response['headers']['status-code']); // Test 9: Operations not an array - $response = $this->client->call(Client::METHOD_POST, "/vectordb/transactions/{$transactionId}/operations", array_merge([ + $response = $this->client->call(Client::METHOD_POST, "/vectorsdb/transactions/{$transactionId}/operations", array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -2241,7 +2241,7 @@ trait TransactionsBase public function testCommitRollbackValidation(): void { // Create transaction - $transaction = $this->client->call(Client::METHOD_POST, '/vectordb/transactions', array_merge([ + $transaction = $this->client->call(Client::METHOD_POST, '/vectorsdb/transactions', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders())); @@ -2250,7 +2250,7 @@ trait TransactionsBase $transactionId = $transaction['body']['$id']; // Test 1: Missing both commit and rollback - $response = $this->client->call(Client::METHOD_PATCH, "/vectordb/transactions/{$transactionId}", array_merge([ + $response = $this->client->call(Client::METHOD_PATCH, "/vectorsdb/transactions/{$transactionId}", array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -2259,7 +2259,7 @@ trait TransactionsBase $this->assertEquals(400, $response['headers']['status-code']); // Test 2: Both commit and rollback set to true - $response = $this->client->call(Client::METHOD_PATCH, "/vectordb/transactions/{$transactionId}", array_merge([ + $response = $this->client->call(Client::METHOD_PATCH, "/vectorsdb/transactions/{$transactionId}", array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -2271,7 +2271,7 @@ trait TransactionsBase $this->assertEquals(400, $response['headers']['status-code']); // Test 3: Invalid transaction ID - $response = $this->client->call(Client::METHOD_PATCH, "/vectordb/transactions/invalid_id", array_merge([ + $response = $this->client->call(Client::METHOD_PATCH, "/vectorsdb/transactions/invalid_id", array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -2282,7 +2282,7 @@ trait TransactionsBase $this->assertEquals(404, $response['headers']['status-code']); // Commit the transaction - $response = $this->client->call(Client::METHOD_PATCH, "/vectordb/transactions/{$transactionId}", array_merge([ + $response = $this->client->call(Client::METHOD_PATCH, "/vectorsdb/transactions/{$transactionId}", array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -2293,7 +2293,7 @@ trait TransactionsBase $this->assertEquals(200, $response['headers']['status-code']); // Test 4: Attempt to commit already committed transaction - $response = $this->client->call(Client::METHOD_PATCH, "/vectordb/transactions/{$transactionId}", array_merge([ + $response = $this->client->call(Client::METHOD_PATCH, "/vectorsdb/transactions/{$transactionId}", array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -2310,7 +2310,7 @@ trait TransactionsBase public function testNonExistentResources(): void { // Create database and transaction - $database = $this->client->call(Client::METHOD_POST, '/vectordb', array_merge([ + $database = $this->client->call(Client::METHOD_POST, '/vectorsdb', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -2322,7 +2322,7 @@ trait TransactionsBase $this->assertEquals(201, $database['headers']['status-code']); $databaseId = $database['body']['$id']; - $transaction = $this->client->call(Client::METHOD_POST, '/vectordb/transactions', array_merge([ + $transaction = $this->client->call(Client::METHOD_POST, '/vectorsdb/transactions', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders())); @@ -2331,7 +2331,7 @@ trait TransactionsBase $transactionId = $transaction['body']['$id']; // Test 1: Non-existent database - $response = $this->client->call(Client::METHOD_POST, "/vectordb/transactions/{$transactionId}/operations", array_merge([ + $response = $this->client->call(Client::METHOD_POST, "/vectorsdb/transactions/{$transactionId}/operations", array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -2350,7 +2350,7 @@ trait TransactionsBase $this->assertEquals(404, $response['headers']['status-code']); // Test 2: Non-existent collection - $response = $this->client->call(Client::METHOD_POST, "/vectordb/transactions/{$transactionId}/operations", array_merge([ + $response = $this->client->call(Client::METHOD_POST, "/vectorsdb/transactions/{$transactionId}/operations", array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] diff --git a/tests/e2e/Services/Databases/VectorDB/Transactions/TransactionsConsoleClientTest.php b/tests/e2e/Services/Databases/VectorsDB/Transactions/TransactionsConsoleClientTest.php similarity index 78% rename from tests/e2e/Services/Databases/VectorDB/Transactions/TransactionsConsoleClientTest.php rename to tests/e2e/Services/Databases/VectorsDB/Transactions/TransactionsConsoleClientTest.php index 02f7c57da8..40ff27c572 100644 --- a/tests/e2e/Services/Databases/VectorDB/Transactions/TransactionsConsoleClientTest.php +++ b/tests/e2e/Services/Databases/VectorsDB/Transactions/TransactionsConsoleClientTest.php @@ -1,6 +1,6 @@ client->call(Client::METHOD_POST, '/vectordb', array_merge([ + $database = $this->client->call(Client::METHOD_POST, '/vectorsdb', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders()), [ @@ -35,7 +35,7 @@ class VectorDBConsoleClientTest extends Scope /** * Test for SUCCESS */ - $movies = $this->client->call(Client::METHOD_POST, '/vectordb/' . $databaseId . '/collections', array_merge([ + $movies = $this->client->call(Client::METHOD_POST, '/vectorsdb/' . $databaseId . '/collections', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders()), [ @@ -57,7 +57,7 @@ class VectorDBConsoleClientTest extends Scope /** * Test when database is disabled but can still create collections */ - $database = $this->client->call(Client::METHOD_PUT, '/vectordb/' . $databaseId, array_merge([ + $database = $this->client->call(Client::METHOD_PUT, '/vectorsdb/' . $databaseId, array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders()), [ @@ -67,7 +67,7 @@ class VectorDBConsoleClientTest extends Scope $this->assertFalse($database['body']['enabled']); - $tvShows = $this->client->call(Client::METHOD_POST, '/vectordb/' . $databaseId . '/collections', array_merge([ + $tvShows = $this->client->call(Client::METHOD_POST, '/vectorsdb/' . $databaseId . '/collections', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders()), [ @@ -86,7 +86,7 @@ class VectorDBConsoleClientTest extends Scope /** * Test when collection is disabled but can still modify collections */ - $database = $this->client->call(Client::METHOD_PUT, '/vectordb/' . $databaseId . '/collections/' . $movies['body']['$id'], array_merge([ + $database = $this->client->call(Client::METHOD_PUT, '/vectorsdb/' . $databaseId . '/collections/' . $movies['body']['$id'], array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders()), [ @@ -108,7 +108,7 @@ class VectorDBConsoleClientTest extends Scope */ $databaseId = $data['databaseId']; - $collections = $this->client->call(Client::METHOD_GET, '/vectordb/' . $databaseId . '/collections', array_merge([ + $collections = $this->client->call(Client::METHOD_GET, '/vectorsdb/' . $databaseId . '/collections', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'] ], $this->getHeaders())); @@ -126,7 +126,7 @@ class VectorDBConsoleClientTest extends Scope /** * Test when database and collection are disabled but can still call get collection */ - $collection = $this->client->call(Client::METHOD_GET, '/vectordb/' . $databaseId . '/collections/' . $moviesCollectionId, array_merge([ + $collection = $this->client->call(Client::METHOD_GET, '/vectorsdb/' . $databaseId . '/collections/' . $moviesCollectionId, array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders())); @@ -146,7 +146,7 @@ class VectorDBConsoleClientTest extends Scope /** * Test When database and collection are disabled but can still call update collection */ - $collection = $this->client->call(Client::METHOD_PUT, '/vectordb/' . $databaseId . '/collections/' . $moviesCollectionId, array_merge([ + $collection = $this->client->call(Client::METHOD_PUT, '/vectorsdb/' . $databaseId . '/collections/' . $moviesCollectionId, array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders()), [ @@ -169,7 +169,7 @@ class VectorDBConsoleClientTest extends Scope /** * Test when database and collection are disabled but can still call delete collection */ - $response = $this->client->call(Client::METHOD_DELETE, '/vectordb/' . $databaseId . '/collections/' . $tvShowsId, array_merge([ + $response = $this->client->call(Client::METHOD_DELETE, '/vectorsdb/' . $databaseId . '/collections/' . $tvShowsId, array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders())); @@ -186,7 +186,7 @@ class VectorDBConsoleClientTest extends Scope * Test for FAILURE */ - $response = $this->client->call(Client::METHOD_GET, '/vectordb/' . $databaseId . '/usage', array_merge([ + $response = $this->client->call(Client::METHOD_GET, '/vectorsdb/' . $databaseId . '/usage', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'] ], $this->getHeaders()), [ @@ -199,7 +199,7 @@ class VectorDBConsoleClientTest extends Scope * Test for SUCCESS */ - $response = $this->client->call(Client::METHOD_GET, '/vectordb/' . $databaseId . '/usage', array_merge([ + $response = $this->client->call(Client::METHOD_GET, '/vectorsdb/' . $databaseId . '/usage', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'] ], $this->getHeaders()), [ @@ -224,7 +224,7 @@ class VectorDBConsoleClientTest extends Scope * Test for FAILURE */ - $response = $this->client->call(Client::METHOD_GET, '/vectordb/' . $databaseId . '/collections/' . $data['moviesId'] . '/usage', array_merge([ + $response = $this->client->call(Client::METHOD_GET, '/vectorsdb/' . $databaseId . '/collections/' . $data['moviesId'] . '/usage', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'] ], $this->getHeaders()), [ @@ -233,7 +233,7 @@ class VectorDBConsoleClientTest extends Scope $this->assertEquals(400, $response['headers']['status-code']); - $response = $this->client->call(Client::METHOD_GET, '/vectordb/' . $databaseId . '/collections/randomCollectionId/usage', array_merge([ + $response = $this->client->call(Client::METHOD_GET, '/vectorsdb/' . $databaseId . '/collections/randomCollectionId/usage', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'] ], $this->getHeaders()), [ @@ -245,7 +245,7 @@ class VectorDBConsoleClientTest extends Scope /** * Test for SUCCESS */ - $response = $this->client->call(Client::METHOD_GET, '/vectordb/' . $databaseId . '/collections/' . $data['moviesId'] . '/usage', array_merge([ + $response = $this->client->call(Client::METHOD_GET, '/vectorsdb/' . $databaseId . '/collections/' . $data['moviesId'] . '/usage', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'] ], $this->getHeaders()), [ @@ -265,7 +265,7 @@ class VectorDBConsoleClientTest extends Scope /** * Test for SUCCESS */ - $logs = $this->client->call(Client::METHOD_GET, '/vectordb/' . $databaseId . '/collections/' . $data['moviesId'] . '/logs', array_merge([ + $logs = $this->client->call(Client::METHOD_GET, '/vectorsdb/' . $databaseId . '/collections/' . $data['moviesId'] . '/logs', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders())); @@ -274,7 +274,7 @@ class VectorDBConsoleClientTest extends Scope $this->assertIsArray($logs['body']['logs']); $this->assertIsNumeric($logs['body']['total']); - $logs = $this->client->call(Client::METHOD_GET, '/vectordb/' . $databaseId . '/collections/' . $data['moviesId'] . '/logs', array_merge([ + $logs = $this->client->call(Client::METHOD_GET, '/vectorsdb/' . $databaseId . '/collections/' . $data['moviesId'] . '/logs', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders()), [ @@ -286,7 +286,7 @@ class VectorDBConsoleClientTest extends Scope $this->assertLessThanOrEqual(1, count($logs['body']['logs'])); $this->assertIsNumeric($logs['body']['total']); - $logs = $this->client->call(Client::METHOD_GET, '/vectordb/' . $databaseId . '/collections/' . $data['moviesId'] . '/logs', array_merge([ + $logs = $this->client->call(Client::METHOD_GET, '/vectorsdb/' . $databaseId . '/collections/' . $data['moviesId'] . '/logs', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders()), [ @@ -297,7 +297,7 @@ class VectorDBConsoleClientTest extends Scope $this->assertIsArray($logs['body']['logs']); $this->assertIsNumeric($logs['body']['total']); - $logs = $this->client->call(Client::METHOD_GET, '/vectordb/' . $databaseId . '/collections/' . $data['moviesId'] . '/logs', array_merge([ + $logs = $this->client->call(Client::METHOD_GET, '/vectorsdb/' . $databaseId . '/collections/' . $data['moviesId'] . '/logs', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders()), [ diff --git a/tests/e2e/Services/Databases/VectorDBCustomClientTest.php b/tests/e2e/Services/Databases/VectorsDBCustomClientTest.php similarity index 89% rename from tests/e2e/Services/Databases/VectorDBCustomClientTest.php rename to tests/e2e/Services/Databases/VectorsDBCustomClientTest.php index 83ef3ba5ca..7add5c7f71 100644 --- a/tests/e2e/Services/Databases/VectorDBCustomClientTest.php +++ b/tests/e2e/Services/Databases/VectorsDBCustomClientTest.php @@ -6,12 +6,12 @@ use Tests\E2E\Client; use Tests\E2E\Scopes\ProjectCustom; use Tests\E2E\Scopes\Scope; use Tests\E2E\Scopes\SideClient; -use Tests\E2E\Services\Databases\VectorDB\DatabasesBase; +use Tests\E2E\Services\Databases\VectorsDB\DatabasesBase; use Utopia\Database\Helpers\ID; use Utopia\Database\Helpers\Permission; use Utopia\Database\Helpers\Role; -class VectorDBCustomClientTest extends Scope +class VectorsDBCustomClientTest extends Scope { use DatabasesBase; use ProjectCustom; @@ -23,7 +23,7 @@ class VectorDBCustomClientTest extends Scope * Test for SUCCESS */ - $database = $this->client->call(Client::METHOD_POST, '/vectordb', [ + $database = $this->client->call(Client::METHOD_POST, '/vectorsdb', [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -35,7 +35,7 @@ class VectorDBCustomClientTest extends Scope $databaseId = $database['body']['$id']; // Collection aliases write to create, update, delete - $movies = $this->client->call(Client::METHOD_POST, '/vectordb/' . $databaseId . '/collections', array_merge([ + $movies = $this->client->call(Client::METHOD_POST, '/vectorsdb/' . $databaseId . '/collections', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -55,10 +55,10 @@ class VectorDBCustomClientTest extends Scope $this->assertContains(Permission::update(Role::user($this->getUser()['$id'])), $movies['body']['$permissions']); $this->assertContains(Permission::delete(Role::user($this->getUser()['$id'])), $movies['body']['$permissions']); - // VectorDB uses fixed schema (embeddings, metadata). No attribute creation needed. + // VectorsDB uses fixed schema (embeddings, metadata). No attribute creation needed. // Document aliases write to update, delete - $document1 = $this->client->call(Client::METHOD_POST, '/vectordb/' . $databaseId . '/collections/' . $moviesId . '/documents', array_merge([ + $document1 = $this->client->call(Client::METHOD_POST, '/vectorsdb/' . $databaseId . '/collections/' . $moviesId . '/documents', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders()), [ @@ -81,7 +81,7 @@ class VectorDBCustomClientTest extends Scope */ // Document does not allow create permission - $document2 = $this->client->call(Client::METHOD_POST, '/vectordb/' . $databaseId . '/collections/' . $moviesId . '/documents', array_merge([ + $document2 = $this->client->call(Client::METHOD_POST, '/vectorsdb/' . $databaseId . '/collections/' . $moviesId . '/documents', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders()), [ @@ -109,7 +109,7 @@ class VectorDBCustomClientTest extends Scope $userId = $response['body']['$id']; - $database = $this->client->call(Client::METHOD_POST, '/vectordb', array_merge([ + $database = $this->client->call(Client::METHOD_POST, '/vectorsdb', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -122,7 +122,7 @@ class VectorDBCustomClientTest extends Scope $databaseId = $database['body']['$id']; // Create collection - $response = $this->client->call(Client::METHOD_POST, '/vectordb/' . $databaseId . '/collections', array_merge([ + $response = $this->client->call(Client::METHOD_POST, '/vectorsdb/' . $databaseId . '/collections', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -136,7 +136,7 @@ class VectorDBCustomClientTest extends Scope $this->assertEquals(201, $response['headers']['status-code']); // Creating document by server, give read permission to our user + some other user - $response = $this->client->call(Client::METHOD_POST, '/vectordb/' . $databaseId . '/collections/permissionCheck/documents', array_merge([ + $response = $this->client->call(Client::METHOD_POST, '/vectorsdb/' . $databaseId . '/collections/permissionCheck/documents', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -158,7 +158,7 @@ class VectorDBCustomClientTest extends Scope // Update document // This is the point of this test. We should be allowed to do this action, and it should not fail on permission check - $response = $this->client->call(Client::METHOD_PATCH, '/vectordb/' . $databaseId . '/collections/permissionCheck/documents/permissionCheckDocument', array_merge([ + $response = $this->client->call(Client::METHOD_PATCH, '/vectorsdb/' . $databaseId . '/collections/permissionCheck/documents/permissionCheckDocument', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'] ], $this->getHeaders()), [ @@ -171,7 +171,7 @@ class VectorDBCustomClientTest extends Scope $this->assertEquals(200, $response['headers']['status-code']); // Get name of the document, should be the new one - $response = $this->client->call(Client::METHOD_GET, '/vectordb/' . $databaseId . '/collections/permissionCheck/documents/permissionCheckDocument', array_merge([ + $response = $this->client->call(Client::METHOD_GET, '/vectorsdb/' . $databaseId . '/collections/permissionCheck/documents/permissionCheckDocument', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders())); @@ -180,7 +180,7 @@ class VectorDBCustomClientTest extends Scope // Cleanup to prevent collision with other tests // Delete collection - $response = $this->client->call(Client::METHOD_DELETE, '/vectordb/' . $databaseId . '/collections/permissionCheck', array_merge([ + $response = $this->client->call(Client::METHOD_DELETE, '/vectorsdb/' . $databaseId . '/collections/permissionCheck', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -193,7 +193,7 @@ class VectorDBCustomClientTest extends Scope sleep(2); // Make sure collection has been deleted - $response = $this->client->call(Client::METHOD_GET, '/vectordb/' . $databaseId . '/collections/permissionCheck', array_merge([ + $response = $this->client->call(Client::METHOD_GET, '/vectorsdb/' . $databaseId . '/collections/permissionCheck', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] diff --git a/tests/e2e/Services/Databases/VectorDBCustomServerTest.php b/tests/e2e/Services/Databases/VectorsDBCustomServerTest.php similarity index 90% rename from tests/e2e/Services/Databases/VectorDBCustomServerTest.php rename to tests/e2e/Services/Databases/VectorsDBCustomServerTest.php index f7aeb8725c..ceb672443e 100644 --- a/tests/e2e/Services/Databases/VectorDBCustomServerTest.php +++ b/tests/e2e/Services/Databases/VectorsDBCustomServerTest.php @@ -7,13 +7,13 @@ use Tests\E2E\Client; use Tests\E2E\Scopes\ProjectCustom; use Tests\E2E\Scopes\Scope; use Tests\E2E\Scopes\SideServer; -use Tests\E2E\Services\Databases\VectorDB\DatabasesBase; +use Tests\E2E\Services\Databases\VectorsDB\DatabasesBase; use Utopia\Database\Database; use Utopia\Database\Helpers\ID; use Utopia\Database\Helpers\Permission; use Utopia\Database\Helpers\Role; -class VectorDBCustomServerTest extends Scope +class VectorsDBCustomServerTest extends Scope { use DatabasesBase; use ProjectCustom; @@ -21,7 +21,7 @@ class VectorDBCustomServerTest extends Scope public function testListDatabases(): array { - $db1 = $this->client->call(Client::METHOD_POST, '/vectordb', [ + $db1 = $this->client->call(Client::METHOD_POST, '/vectorsdb', [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -31,14 +31,14 @@ class VectorDBCustomServerTest extends Scope ]); $this->assertEquals(201, $db1['headers']['status-code']); $this->assertEquals('Test 1', $db1['body']['name']); - $this->assertEquals('vectordb', $db1['body']['type']); + $this->assertEquals('vectorsdb', $db1['body']['type']); // Validate database response model fields on create $this->assertArrayHasKey('$id', $db1['body']); $this->assertArrayHasKey('$createdAt', $db1['body']); $this->assertArrayHasKey('$updatedAt', $db1['body']); $this->assertArrayHasKey('enabled', $db1['body']); - $db2 = $this->client->call(Client::METHOD_POST, '/vectordb', [ + $db2 = $this->client->call(Client::METHOD_POST, '/vectorsdb', [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -48,9 +48,9 @@ class VectorDBCustomServerTest extends Scope ]); $this->assertEquals(201, $db2['headers']['status-code']); $this->assertEquals('Test 2', $db2['body']['name']); - $this->assertEquals('vectordb', $db2['body']['type']); + $this->assertEquals('vectorsdb', $db2['body']['type']); - $list = $this->client->call(Client::METHOD_GET, '/vectordb', [ + $list = $this->client->call(Client::METHOD_GET, '/vectorsdb', [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -70,7 +70,7 @@ class VectorDBCustomServerTest extends Scope public function testGetDatabase(array $data): array { $databaseId = $data['databaseId']; - $res = $this->client->call(Client::METHOD_GET, '/vectordb/' . $databaseId, [ + $res = $this->client->call(Client::METHOD_GET, '/vectorsdb/' . $databaseId, [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -78,7 +78,7 @@ class VectorDBCustomServerTest extends Scope $this->assertEquals(200, $res['headers']['status-code']); $this->assertEquals($databaseId, $res['body']['$id']); $this->assertEquals('Test 1', $res['body']['name']); - $this->assertEquals('vectordb', $res['body']['type']); + $this->assertEquals('vectorsdb', $res['body']['type']); return ['databaseId' => $databaseId]; } @@ -86,7 +86,7 @@ class VectorDBCustomServerTest extends Scope public function testUpdateDatabase(array $data): array { $databaseId = $data['databaseId']; - $res = $this->client->call(Client::METHOD_PUT, '/vectordb/' . $databaseId, [ + $res = $this->client->call(Client::METHOD_PUT, '/vectorsdb/' . $databaseId, [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -95,7 +95,7 @@ class VectorDBCustomServerTest extends Scope ]); $this->assertEquals(200, $res['headers']['status-code']); $this->assertEquals('Test 1 Updated', $res['body']['name']); - $this->assertEquals('vectordb', $res['body']['type']); + $this->assertEquals('vectorsdb', $res['body']['type']); return ['databaseId' => $databaseId]; } @@ -103,7 +103,7 @@ class VectorDBCustomServerTest extends Scope public function testDeleteDatabase(array $data): void { $databaseId = $data['databaseId']; - $del = $this->client->call(Client::METHOD_DELETE, '/vectordb/' . $databaseId, [ + $del = $this->client->call(Client::METHOD_DELETE, '/vectorsdb/' . $databaseId, [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -111,7 +111,7 @@ class VectorDBCustomServerTest extends Scope $this->assertEquals(204, $del['headers']['status-code']); $this->assertEquals("", $del['body']); - $get = $this->client->call(Client::METHOD_GET, '/vectordb/' . $databaseId, [ + $get = $this->client->call(Client::METHOD_GET, '/vectorsdb/' . $databaseId, [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -122,7 +122,7 @@ class VectorDBCustomServerTest extends Scope public function testCollectionsCRUD(): array { // Create database for collections tests - $database = $this->client->call(Client::METHOD_POST, '/vectordb', [ + $database = $this->client->call(Client::METHOD_POST, '/vectorsdb', [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -134,7 +134,7 @@ class VectorDBCustomServerTest extends Scope $databaseId = $database['body']['$id']; // Create two collections - $col1 = $this->client->call(Client::METHOD_POST, '/vectordb/' . $databaseId . '/collections', [ + $col1 = $this->client->call(Client::METHOD_POST, '/vectorsdb/' . $databaseId . '/collections', [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -159,7 +159,7 @@ class VectorDBCustomServerTest extends Scope $this->assertArrayHasKey('documentSecurity', $col1['body']); $this->assertArrayHasKey('dimension', $col1['body']); - $col2 = $this->client->call(Client::METHOD_POST, '/vectordb/' . $databaseId . '/collections', [ + $col2 = $this->client->call(Client::METHOD_POST, '/vectorsdb/' . $databaseId . '/collections', [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -181,7 +181,7 @@ class VectorDBCustomServerTest extends Scope $this->assertArrayHasKey('$updatedAt', $col2['body']); // List collections - $list = $this->client->call(Client::METHOD_GET, '/vectordb/' . $databaseId . '/collections', [ + $list = $this->client->call(Client::METHOD_GET, '/vectorsdb/' . $databaseId . '/collections', [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -195,7 +195,7 @@ class VectorDBCustomServerTest extends Scope $this->assertArrayHasKey('dimension', $list['body']['collections'][0]); // Get collection - $get = $this->client->call(Client::METHOD_GET, '/vectordb/' . $databaseId . '/collections/' . $col1['body']['$id'], [ + $get = $this->client->call(Client::METHOD_GET, '/vectorsdb/' . $databaseId . '/collections/' . $col1['body']['$id'], [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -206,7 +206,7 @@ class VectorDBCustomServerTest extends Scope $this->assertEquals(3, $get['body']['dimension']); // Update collection (name only) - $upd = $this->client->call(Client::METHOD_PUT, '/vectordb/' . $databaseId . '/collections/' . $col1['body']['$id'], [ + $upd = $this->client->call(Client::METHOD_PUT, '/vectorsdb/' . $databaseId . '/collections/' . $col1['body']['$id'], [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -218,7 +218,7 @@ class VectorDBCustomServerTest extends Scope $this->assertArrayHasKey('$updatedAt', $upd['body']); // Delete collection - $del = $this->client->call(Client::METHOD_DELETE, '/vectordb/' . $databaseId . '/collections/' . $col2['body']['$id'], [ + $del = $this->client->call(Client::METHOD_DELETE, '/vectorsdb/' . $databaseId . '/collections/' . $col2['body']['$id'], [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -239,7 +239,7 @@ class VectorDBCustomServerTest extends Scope $collectionId = $data['collectionId']; // Update collection name and dimensions - $upd = $this->client->call(Client::METHOD_PUT, '/vectordb/' . $databaseId . '/collections/' . $collectionId, [ + $upd = $this->client->call(Client::METHOD_PUT, '/vectorsdb/' . $databaseId . '/collections/' . $collectionId, [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -252,7 +252,7 @@ class VectorDBCustomServerTest extends Scope $this->assertEquals(4, $upd['body']['dimension']); // Read back to confirm - $get = $this->client->call(Client::METHOD_GET, '/vectordb/' . $databaseId . '/collections/' . $collectionId, [ + $get = $this->client->call(Client::METHOD_GET, '/vectorsdb/' . $databaseId . '/collections/' . $collectionId, [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -271,7 +271,7 @@ class VectorDBCustomServerTest extends Scope $collectionId = $data['collectionId']; // Disable collection - $disable = $this->client->call(Client::METHOD_PUT, '/vectordb/' . $databaseId . '/collections/' . $collectionId, [ + $disable = $this->client->call(Client::METHOD_PUT, '/vectorsdb/' . $databaseId . '/collections/' . $collectionId, [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -283,7 +283,7 @@ class VectorDBCustomServerTest extends Scope $this->assertFalse($disable['body']['enabled']); // Re-enable collection - $enable = $this->client->call(Client::METHOD_PUT, '/vectordb/' . $databaseId . '/collections/' . $collectionId, [ + $enable = $this->client->call(Client::METHOD_PUT, '/vectorsdb/' . $databaseId . '/collections/' . $collectionId, [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -300,7 +300,7 @@ class VectorDBCustomServerTest extends Scope public function testUpdateDatabaseNameAndEnabled(): void { // Create isolated database for this test to avoid ordering conflicts - $create = $this->client->call(Client::METHOD_POST, '/vectordb', [ + $create = $this->client->call(Client::METHOD_POST, '/vectorsdb', [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -312,7 +312,7 @@ class VectorDBCustomServerTest extends Scope $databaseId = $create['body']['$id']; // Update name - $rename = $this->client->call(Client::METHOD_PUT, '/vectordb/' . $databaseId, [ + $rename = $this->client->call(Client::METHOD_PUT, '/vectorsdb/' . $databaseId, [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -323,7 +323,7 @@ class VectorDBCustomServerTest extends Scope $this->assertEquals('Test DB Renamed', $rename['body']['name']); // Toggle enabled off then on - $disable = $this->client->call(Client::METHOD_PUT, '/vectordb/' . $databaseId, [ + $disable = $this->client->call(Client::METHOD_PUT, '/vectorsdb/' . $databaseId, [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -334,7 +334,7 @@ class VectorDBCustomServerTest extends Scope $this->assertEquals(200, $disable['headers']['status-code']); $this->assertFalse($disable['body']['enabled']); - $enable = $this->client->call(Client::METHOD_PUT, '/vectordb/' . $databaseId, [ + $enable = $this->client->call(Client::METHOD_PUT, '/vectorsdb/' . $databaseId, [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -346,7 +346,7 @@ class VectorDBCustomServerTest extends Scope $this->assertTrue($enable['body']['enabled']); // Cleanup - $del = $this->client->call(Client::METHOD_DELETE, '/vectordb/' . $databaseId, [ + $del = $this->client->call(Client::METHOD_DELETE, '/vectorsdb/' . $databaseId, [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -361,7 +361,7 @@ class VectorDBCustomServerTest extends Scope $collectionId = $data['collectionId']; // Create a new index variant - $create = $this->client->call(Client::METHOD_POST, "/vectordb/{$databaseId}/collections/{$collectionId}/indexes", [ + $create = $this->client->call(Client::METHOD_POST, "/vectorsdb/{$databaseId}/collections/{$collectionId}/indexes", [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -373,7 +373,7 @@ class VectorDBCustomServerTest extends Scope $this->assertEquals(202, $create['headers']['status-code']); // Ensure it exists - $get = $this->client->call(Client::METHOD_GET, "/vectordb/{$databaseId}/collections/{$collectionId}/indexes/embedding_euclidean_v2", [ + $get = $this->client->call(Client::METHOD_GET, "/vectorsdb/{$databaseId}/collections/{$collectionId}/indexes/embedding_euclidean_v2", [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -382,7 +382,7 @@ class VectorDBCustomServerTest extends Scope $this->assertEquals('embedding_euclidean_v2', $get['body']['key']); // Delete it - $del = $this->client->call(Client::METHOD_DELETE, "/vectordb/{$databaseId}/collections/{$collectionId}/indexes/embedding_euclidean_v2", [ + $del = $this->client->call(Client::METHOD_DELETE, "/vectorsdb/{$databaseId}/collections/{$collectionId}/indexes/embedding_euclidean_v2", [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -397,7 +397,7 @@ class VectorDBCustomServerTest extends Scope $collectionId = $data['collectionId']; // Create indexes - $eu = $this->client->call(Client::METHOD_POST, "/vectordb/{$databaseId}/collections/{$collectionId}/indexes", [ + $eu = $this->client->call(Client::METHOD_POST, "/vectorsdb/{$databaseId}/collections/{$collectionId}/indexes", [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -408,7 +408,7 @@ class VectorDBCustomServerTest extends Scope ]); $this->assertEquals(202, $eu['headers']['status-code']); - $dot = $this->client->call(Client::METHOD_POST, "/vectordb/{$databaseId}/collections/{$collectionId}/indexes", [ + $dot = $this->client->call(Client::METHOD_POST, "/vectorsdb/{$databaseId}/collections/{$collectionId}/indexes", [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -419,7 +419,7 @@ class VectorDBCustomServerTest extends Scope ]); $this->assertEquals(202, $dot['headers']['status-code']); - $cos = $this->client->call(Client::METHOD_POST, "/vectordb/{$databaseId}/collections/{$collectionId}/indexes", [ + $cos = $this->client->call(Client::METHOD_POST, "/vectorsdb/{$databaseId}/collections/{$collectionId}/indexes", [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -431,7 +431,7 @@ class VectorDBCustomServerTest extends Scope $this->assertEquals(202, $cos['headers']['status-code']); // List indexes - $list = $this->client->call(Client::METHOD_GET, "/vectordb/{$databaseId}/collections/{$collectionId}/indexes", [ + $list = $this->client->call(Client::METHOD_GET, "/vectorsdb/{$databaseId}/collections/{$collectionId}/indexes", [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -444,7 +444,7 @@ class VectorDBCustomServerTest extends Scope $this->assertContains('embedding_cosine', $keys); // Get index by key - $get = $this->client->call(Client::METHOD_GET, "/vectordb/{$databaseId}/collections/{$collectionId}/indexes/embedding_euclidean", [ + $get = $this->client->call(Client::METHOD_GET, "/vectorsdb/{$databaseId}/collections/{$collectionId}/indexes/embedding_euclidean", [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -454,7 +454,7 @@ class VectorDBCustomServerTest extends Scope $this->assertEquals(Database::INDEX_HNSW_EUCLIDEAN, $get['body']['type']); // Delete index - $del = $this->client->call(Client::METHOD_DELETE, "/vectordb/{$databaseId}/collections/{$collectionId}/indexes/embedding_dot", [ + $del = $this->client->call(Client::METHOD_DELETE, "/vectorsdb/{$databaseId}/collections/{$collectionId}/indexes/embedding_dot", [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -462,7 +462,7 @@ class VectorDBCustomServerTest extends Scope $this->assertEquals(204, $del['headers']['status-code']); sleep(4); // Ensure it's gone - $getMissing = $this->client->call(Client::METHOD_GET, "/vectordb/{$databaseId}/collections/{$collectionId}/indexes/embedding_dot", [ + $getMissing = $this->client->call(Client::METHOD_GET, "/vectorsdb/{$databaseId}/collections/{$collectionId}/indexes/embedding_dot", [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -473,7 +473,7 @@ class VectorDBCustomServerTest extends Scope public function testBulkCreate(): array { // Setup: create isolated database and collection - $db = $this->client->call(Client::METHOD_POST, '/vectordb', [ + $db = $this->client->call(Client::METHOD_POST, '/vectorsdb', [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -484,7 +484,7 @@ class VectorDBCustomServerTest extends Scope $this->assertEquals(201, $db['headers']['status-code']); $databaseId = $db['body']['$id']; - $col = $this->client->call(Client::METHOD_POST, "/vectordb/{$databaseId}/collections", [ + $col = $this->client->call(Client::METHOD_POST, "/vectorsdb/{$databaseId}/collections", [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -511,7 +511,7 @@ class VectorDBCustomServerTest extends Scope ], ]; - $res = $this->client->call(Client::METHOD_POST, "/vectordb/{$databaseId}/collections/{$collectionId}/documents", [ + $res = $this->client->call(Client::METHOD_POST, "/vectorsdb/{$databaseId}/collections/{$collectionId}/documents", [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -531,7 +531,7 @@ class VectorDBCustomServerTest extends Scope // Fetch and validate persisted data via GET foreach ($ids as $i => $id) { - $get = $this->client->call(Client::METHOD_GET, "/vectordb/{$databaseId}/collections/{$collectionId}/documents/{$id}", [ + $get = $this->client->call(Client::METHOD_GET, "/vectorsdb/{$databaseId}/collections/{$collectionId}/documents/{$id}", [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -549,7 +549,7 @@ class VectorDBCustomServerTest extends Scope public function testCreateTextEmbeddingsSuccessAndErrors(): void { // Setup new database and collection - $db = $this->client->call(Client::METHOD_POST, '/vectordb', [ + $db = $this->client->call(Client::METHOD_POST, '/vectorsdb', [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -560,7 +560,7 @@ class VectorDBCustomServerTest extends Scope $this->assertEquals(201, $db['headers']['status-code']); $databaseId = $db['body']['$id']; - $col = $this->client->call(Client::METHOD_POST, "/vectordb/{$databaseId}/collections", [ + $col = $this->client->call(Client::METHOD_POST, "/vectorsdb/{$databaseId}/collections", [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -576,7 +576,7 @@ class VectorDBCustomServerTest extends Scope // Success: two embeddings $this->assertEventually(function () { - $ok = $this->client->call(Client::METHOD_POST, "/vectordb/embeddings/text", [ + $ok = $this->client->call(Client::METHOD_POST, "/vectorsdb/embeddings/text", [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -602,7 +602,7 @@ class VectorDBCustomServerTest extends Scope }, 3000, 100); // Error: missing texts payload - $missingTexts = $this->client->call(Client::METHOD_POST, "/vectordb/embeddings/text", [ + $missingTexts = $this->client->call(Client::METHOD_POST, "/vectorsdb/embeddings/text", [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -610,7 +610,7 @@ class VectorDBCustomServerTest extends Scope $this->assertEquals(400, $missingTexts['headers']['status-code']); // Error: invalid texts item type (must be strings) - $invalidItem = $this->client->call(Client::METHOD_POST, "/vectordb/embeddings/text", [ + $invalidItem = $this->client->call(Client::METHOD_POST, "/vectorsdb/embeddings/text", [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -624,7 +624,7 @@ class VectorDBCustomServerTest extends Scope $this->assertEquals(400, $invalidItem['headers']['status-code']); // Error: unknown embedding model - $unknownModel = $this->client->call(Client::METHOD_POST, "/vectordb/embeddings/text", [ + $unknownModel = $this->client->call(Client::METHOD_POST, "/vectorsdb/embeddings/text", [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -638,7 +638,7 @@ class VectorDBCustomServerTest extends Scope public function testBulkUpsert(): void { // Setup fresh db/collection - $db = $this->client->call(Client::METHOD_POST, '/vectordb', [ + $db = $this->client->call(Client::METHOD_POST, '/vectorsdb', [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -646,7 +646,7 @@ class VectorDBCustomServerTest extends Scope $this->assertEquals(201, $db['headers']['status-code']); $databaseId = $db['body']['$id']; - $col = $this->client->call(Client::METHOD_POST, "/vectordb/{$databaseId}/collections", [ + $col = $this->client->call(Client::METHOD_POST, "/vectorsdb/{$databaseId}/collections", [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -673,7 +673,7 @@ class VectorDBCustomServerTest extends Scope ], ]; - $res = $this->client->call(Client::METHOD_PUT, "/vectordb/{$databaseId}/collections/{$collectionId}/documents", [ + $res = $this->client->call(Client::METHOD_PUT, "/vectorsdb/{$databaseId}/collections/{$collectionId}/documents", [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -690,7 +690,7 @@ class VectorDBCustomServerTest extends Scope // Fetch and validate updated content $ids = array_map(fn ($d) => $d['$id'], $res['body']['documents']); foreach ($ids as $id) { - $get = $this->client->call(Client::METHOD_GET, "/vectordb/{$databaseId}/collections/{$collectionId}/documents/{$id}", [ + $get = $this->client->call(Client::METHOD_GET, "/vectorsdb/{$databaseId}/collections/{$collectionId}/documents/{$id}", [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -704,7 +704,7 @@ class VectorDBCustomServerTest extends Scope [ 'embeddings' => [0.6, 0.4, 0.0], 'metadata' => ['updatedAgain' => true] ], [ 'embeddings' => [0.3, 0.7, 0.0], 'metadata' => ['updatedAgain' => true] ], ]; - $res2 = $this->client->call(Client::METHOD_PUT, "/vectordb/{$databaseId}/collections/{$collectionId}/documents", [ + $res2 = $this->client->call(Client::METHOD_PUT, "/vectorsdb/{$databaseId}/collections/{$collectionId}/documents", [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -718,7 +718,7 @@ class VectorDBCustomServerTest extends Scope // Fetch again and assert second update persisted $ids2 = array_map(fn ($d) => $d['$id'], $res2['body']['documents']); foreach ($ids2 as $id) { - $get2 = $this->client->call(Client::METHOD_GET, "/vectordb/{$databaseId}/collections/{$collectionId}/documents/{$id}", [ + $get2 = $this->client->call(Client::METHOD_GET, "/vectorsdb/{$databaseId}/collections/{$collectionId}/documents/{$id}", [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -731,7 +731,7 @@ class VectorDBCustomServerTest extends Scope public function testBulkUpdate(): void { // Setup: create db/collection and two docs - $db = $this->client->call(Client::METHOD_POST, '/vectordb', [ + $db = $this->client->call(Client::METHOD_POST, '/vectorsdb', [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -739,7 +739,7 @@ class VectorDBCustomServerTest extends Scope $this->assertEquals(201, $db['headers']['status-code']); $databaseId = $db['body']['$id']; - $col = $this->client->call(Client::METHOD_POST, "/vectordb/{$databaseId}/collections", [ + $col = $this->client->call(Client::METHOD_POST, "/vectorsdb/{$databaseId}/collections", [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -753,7 +753,7 @@ class VectorDBCustomServerTest extends Scope $this->assertEquals(201, $col['headers']['status-code']); $collectionId = $col['body']['$id']; - $seed = $this->client->call(Client::METHOD_PUT, "/vectordb/{$databaseId}/collections/{$collectionId}/documents", [ + $seed = $this->client->call(Client::METHOD_PUT, "/vectorsdb/{$databaseId}/collections/{$collectionId}/documents", [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -766,7 +766,7 @@ class VectorDBCustomServerTest extends Scope $this->assertEquals(200, $seed['headers']['status-code']); $ids = array_map(fn ($d) => $d['$id'], $seed['body']['documents']); - $res = $this->client->call(Client::METHOD_PATCH, "/vectordb/{$databaseId}/collections/{$collectionId}/documents", [ + $res = $this->client->call(Client::METHOD_PATCH, "/vectorsdb/{$databaseId}/collections/{$collectionId}/documents", [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -786,7 +786,7 @@ class VectorDBCustomServerTest extends Scope // Fetch by IDs and assert update persisted foreach ($ids as $id) { - $get = $this->client->call(Client::METHOD_GET, "/vectordb/{$databaseId}/collections/{$collectionId}/documents/{$id}", [ + $get = $this->client->call(Client::METHOD_GET, "/vectorsdb/{$databaseId}/collections/{$collectionId}/documents/{$id}", [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -799,7 +799,7 @@ class VectorDBCustomServerTest extends Scope public function testBulkDelete(): void { // Setup: create db/collection and two docs - $db = $this->client->call(Client::METHOD_POST, '/vectordb', [ + $db = $this->client->call(Client::METHOD_POST, '/vectorsdb', [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -807,7 +807,7 @@ class VectorDBCustomServerTest extends Scope $this->assertEquals(201, $db['headers']['status-code']); $databaseId = $db['body']['$id']; - $col = $this->client->call(Client::METHOD_POST, "/vectordb/{$databaseId}/collections", [ + $col = $this->client->call(Client::METHOD_POST, "/vectorsdb/{$databaseId}/collections", [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -821,7 +821,7 @@ class VectorDBCustomServerTest extends Scope $this->assertEquals(201, $col['headers']['status-code']); $collectionId = $col['body']['$id']; - $seed = $this->client->call(Client::METHOD_PUT, "/vectordb/{$databaseId}/collections/{$collectionId}/documents", [ + $seed = $this->client->call(Client::METHOD_PUT, "/vectorsdb/{$databaseId}/collections/{$collectionId}/documents", [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -834,7 +834,7 @@ class VectorDBCustomServerTest extends Scope $this->assertEquals(200, $seed['headers']['status-code']); $ids = array_map(fn ($d) => $d['$id'], $seed['body']['documents']); - $res = $this->client->call(Client::METHOD_DELETE, "/vectordb/{$databaseId}/collections/{$collectionId}/documents", [ + $res = $this->client->call(Client::METHOD_DELETE, "/vectorsdb/{$databaseId}/collections/{$collectionId}/documents", [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -849,7 +849,7 @@ class VectorDBCustomServerTest extends Scope // Ensure they are deleted foreach ($ids as $id) { - $get = $this->client->call(Client::METHOD_GET, "/vectordb/{$databaseId}/collections/{$collectionId}/documents/{$id}", [ + $get = $this->client->call(Client::METHOD_GET, "/vectorsdb/{$databaseId}/collections/{$collectionId}/documents/{$id}", [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -861,7 +861,7 @@ class VectorDBCustomServerTest extends Scope public function testCustomTimestamps(): void { // Setup: create database and collection - $db = $this->client->call(Client::METHOD_POST, '/vectordb', [ + $db = $this->client->call(Client::METHOD_POST, '/vectorsdb', [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -872,7 +872,7 @@ class VectorDBCustomServerTest extends Scope $this->assertEquals(201, $db['headers']['status-code']); $databaseId = $db['body']['$id']; - $col = $this->client->call(Client::METHOD_POST, "/vectordb/{$databaseId}/collections", [ + $col = $this->client->call(Client::METHOD_POST, "/vectorsdb/{$databaseId}/collections", [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -893,7 +893,7 @@ class VectorDBCustomServerTest extends Scope $vector[0] = 1.0; $documentId = ID::unique(); - $doc = $this->client->call(Client::METHOD_POST, "/vectordb/{$databaseId}/collections/{$collectionId}/documents", [ + $doc = $this->client->call(Client::METHOD_POST, "/vectorsdb/{$databaseId}/collections/{$collectionId}/documents", [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -916,7 +916,7 @@ class VectorDBCustomServerTest extends Scope $this->assertEquals($customUpdatedAt, $doc['body']['$updatedAt'], 'UpdatedAt should match custom timestamp'); // Fetch document and verify timestamps persist - $fetched = $this->client->call(Client::METHOD_GET, "/vectordb/{$databaseId}/collections/{$collectionId}/documents/{$documentId}", [ + $fetched = $this->client->call(Client::METHOD_GET, "/vectorsdb/{$databaseId}/collections/{$collectionId}/documents/{$documentId}", [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -931,7 +931,7 @@ class VectorDBCustomServerTest extends Scope $vector2 = array_fill(0, 1536, 0.0); $vector2[1] = 1.0; - $updated = $this->client->call(Client::METHOD_PUT, "/vectordb/{$databaseId}/collections/{$collectionId}/documents/{$documentId}", [ + $updated = $this->client->call(Client::METHOD_PUT, "/vectorsdb/{$databaseId}/collections/{$collectionId}/documents/{$documentId}", [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -949,7 +949,7 @@ class VectorDBCustomServerTest extends Scope $this->assertEquals($newCustomUpdatedAt, $updated['body']['$updatedAt'], 'UpdatedAt should be updated to new custom timestamp'); // Final verification - $final = $this->client->call(Client::METHOD_GET, "/vectordb/{$databaseId}/collections/{$collectionId}/documents/{$documentId}", [ + $final = $this->client->call(Client::METHOD_GET, "/vectorsdb/{$databaseId}/collections/{$collectionId}/documents/{$documentId}", [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] diff --git a/tests/e2e/Services/Functions/FunctionsConsoleClientTest.php b/tests/e2e/Services/Functions/FunctionsConsoleClientTest.php index 168e0561e2..cc18d14a8e 100644 --- a/tests/e2e/Services/Functions/FunctionsConsoleClientTest.php +++ b/tests/e2e/Services/Functions/FunctionsConsoleClientTest.php @@ -6,6 +6,7 @@ use Tests\E2E\Client; use Tests\E2E\Scopes\ProjectCustom; use Tests\E2E\Scopes\Scope; use Tests\E2E\Scopes\SideConsole; +use Utopia\Console; use Utopia\Database\Helpers\ID; use Utopia\Database\Helpers\Role; @@ -653,4 +654,52 @@ class FunctionsConsoleClientTest extends Scope $this->cleanupFunction($functionId); } + + public function testFunctionDeploymentRetentionWithMaintenance(): void + { + $functionId = $this->setupFunction([ + 'functionId' => ID::unique(), + 'name' => 'Test retention function', + 'runtime' => 'node-22', + 'entrypoint' => 'index.js', + 'deploymentRetention' => 180 + ]); + $this->assertNotEmpty($functionId); + + $deploymentIdInactive = $this->setupDeployment($functionId, [ + 'code' => $this->packageFunction('node'), + 'activate' => true + ]); + $this->assertNotEmpty($deploymentIdInactive); + + $deploymentIdInactiveOld = $this->setupDeployment($functionId, [ + 'code' => $this->packageFunction('node'), + 'activate' => true + ]); + $this->assertNotEmpty($deploymentIdInactiveOld); + + $deploymentIdActive = $this->setupDeployment($functionId, [ + 'code' => $this->packageFunction('node'), + 'activate' => true + ]); + $this->assertNotEmpty($deploymentIdActive); + + $stdout = ''; + $stderr = ''; + $code = Console::execute("docker exec appwrite time-travel --projectId={$this->getProject()['$id']} --resourceType=deployment --resourceId={$deploymentIdInactiveOld} --createdAt=2020-01-01T00:00:00Z", '', $stdout, $stderr); + $this->assertSame(0, $code, "Time-travel command failed with code $code: $stderr ($stdout)"); + + $stdout = ''; + $stderr = ''; + $code = Console::execute("docker exec appwrite maintenance --type=trigger", '', $stdout, $stderr); + $this->assertSame(0, $code, "Maintenance command failed with code $code: $stderr ($stdout)"); + + $this->assertEventually(function () use ($functionId) { + $response = $this->listDeployments($functionId); + $this->assertSame(200, $response['headers']['status-code']); + $this->assertSame(2, $response['body']['total']); + }); + + $this->cleanupFunction($functionId); + } } diff --git a/tests/e2e/Services/Functions/FunctionsCustomServerTest.php b/tests/e2e/Services/Functions/FunctionsCustomServerTest.php index 48208cc7b1..e0002fdafb 100644 --- a/tests/e2e/Services/Functions/FunctionsCustomServerTest.php +++ b/tests/e2e/Services/Functions/FunctionsCustomServerTest.php @@ -196,25 +196,33 @@ class FunctionsCustomServerTest extends Scope { $specifications = $this->listSpecifications(); $this->assertEquals(200, $specifications['headers']['status-code']); - $this->assertGreaterThan(0, $specifications['body']['total']); + $this->assertGreaterThanOrEqual(2, $specifications['body']['total']); $this->assertArrayHasKey(0, $specifications['body']['specifications']); + $this->assertArrayHasKey(1, $specifications['body']['specifications']); $this->assertArrayHasKey('memory', $specifications['body']['specifications'][0]); $this->assertArrayHasKey('cpus', $specifications['body']['specifications'][0]); $this->assertArrayHasKey('enabled', $specifications['body']['specifications'][0]); $this->assertArrayHasKey('slug', $specifications['body']['specifications'][0]); + $this->assertArrayHasKey('memory', $specifications['body']['specifications'][1]); + $this->assertArrayHasKey('cpus', $specifications['body']['specifications'][1]); + $this->assertArrayHasKey('enabled', $specifications['body']['specifications'][1]); + $this->assertArrayHasKey('slug', $specifications['body']['specifications'][1]); $function = $this->createFunction([ 'functionId' => ID::unique(), 'name' => 'Specs function', 'runtime' => 'node-22', - 'specification' => $specifications['body']['specifications'][0]['slug'] + 'buildSpecification' => $specifications['body']['specifications'][0]['slug'], + 'runtimeSpecification' => $specifications['body']['specifications'][1]['slug'], ]); $this->assertEquals(201, $function['headers']['status-code']); - $this->assertEquals($specifications['body']['specifications'][0]['slug'], $function['body']['specification']); + $this->assertEquals($specifications['body']['specifications'][0]['slug'], $function['body']['buildSpecification']); + $this->assertEquals($specifications['body']['specifications'][1]['slug'], $function['body']['runtimeSpecification']); $function = $this->getFunction($function['body']['$id']); $this->assertEquals(200, $function['headers']['status-code']); - $this->assertEquals($specifications['body']['specifications'][0]['slug'], $function['body']['specification']); + $this->assertEquals($specifications['body']['specifications'][0]['slug'], $function['body']['buildSpecification']); + $this->assertEquals($specifications['body']['specifications'][1]['slug'], $function['body']['runtimeSpecification']); $this->cleanupFunction($function['body']['$id']); @@ -222,7 +230,15 @@ class FunctionsCustomServerTest extends Scope 'functionId' => ID::unique(), 'name' => 'Specs function', 'runtime' => 'node-22', - 'specification' => 'cheap-please' + 'buildSpecification' => 'cheap-please' + ]); + $this->assertEquals(400, $function['headers']['status-code']); + + $function = $this->createFunction([ + 'functionId' => ID::unique(), + 'name' => 'Specs function', + 'runtime' => 'node-22', + 'runtimeSpecification' => 'cheap-please' ]); $this->assertEquals(400, $function['headers']['status-code']); } @@ -1552,12 +1568,12 @@ class FunctionsCustomServerTest extends Scope 'timeout' => 15, 'runtime' => 'node-22', 'entrypoint' => 'index.js', - 'specification' => Specification::S_1VCPU_1GB, + 'runtimeSpecification' => Specification::S_1VCPU_1GB, ]); $this->assertEquals(200, $function['headers']['status-code']); $this->assertNotEmpty($function['body']['$id']); - $this->assertEquals(Specification::S_1VCPU_1GB, $function['body']['specification']); + $this->assertEquals(Specification::S_1VCPU_1GB, $function['body']['runtimeSpecification']); // Verify the updated specs $execution = $this->createExecution($functionId); @@ -1586,12 +1602,12 @@ class FunctionsCustomServerTest extends Scope 'timeout' => 15, 'runtime' => 'node-22', 'entrypoint' => 'index.js', - 'specification' => Specification::S_1VCPU_512MB, + 'runtimeSpecification' => Specification::S_1VCPU_512MB, ]); $this->assertEquals(200, $function['headers']['status-code']); $this->assertNotEmpty($function['body']['$id']); - $this->assertEquals(Specification::S_1VCPU_512MB, $function['body']['specification']); + $this->assertEquals(Specification::S_1VCPU_512MB, $function['body']['runtimeSpecification']); // Verify the updated specs $execution = $this->createExecution($functionId); @@ -1616,11 +1632,29 @@ class FunctionsCustomServerTest extends Scope 'timeout' => 15, 'runtime' => 'node-22', 'entrypoint' => 'index.js', - 'specification' => 's-2vcpu-512mb', // Invalid specification + 'buildSpecification' => 's-2vcpu-512mb', // Invalid specification ]); $this->assertEquals(400, $function['headers']['status-code']); - $this->assertStringStartsWith('Invalid `specification` param: Specification must be one of:', $function['body']['message']); + $this->assertStringStartsWith('Invalid `buildSpecification` param: Specification must be one of:', $function['body']['message']); + + $function = $this->client->call(Client::METHOD_PUT, '/functions/' . $data['functionId'], array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'name' => 'Test1', + 'events' => [ + 'users.*.update.name', + 'users.*.update.email', + ], + 'timeout' => 15, + 'runtime' => 'node-22', + 'entrypoint' => 'index.js', + 'runtimeSpecification' => 's-2vcpu-512mb', // Invalid specification + ]); + + $this->assertEquals(400, $function['headers']['status-code']); + $this->assertStringStartsWith('Invalid `runtimeSpecification` param: Specification must be one of:', $function['body']['message']); } public function testDeleteDeployment(): void @@ -2221,6 +2255,8 @@ class FunctionsCustomServerTest extends Scope $this->assertEquals(201, $response['headers']['status-code']); $this->assertArrayNotHasKey('scopes', $response['body']); $this->assertArrayNotHasKey('specification', $response['body']); + $this->assertArrayNotHasKey('buildSpecification', $response['body']); + $this->assertArrayNotHasKey('runtimeSpecification', $response['body']); // get function with 1.5.0 response format header $function = $this->client->call(Client::METHOD_GET, '/functions/' . $response['body']['$id'], array_merge([ @@ -2231,13 +2267,31 @@ class FunctionsCustomServerTest extends Scope $this->assertEquals(200, $function['headers']['status-code']); $this->assertArrayNotHasKey('scopes', $function['body']); + $this->assertArrayNotHasKey('buildSpecification', $function['body']); + $this->assertArrayNotHasKey('runtimeSpecification', $function['body']); $this->assertArrayNotHasKey('specification', $function['body']); - $function = $this->getFunction($function['body']['$id']); + // get function with 1.8.0 response format header + $function = $this->client->call(Client::METHOD_GET, '/functions/' . $response['body']['$id'], array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-response-format' => '1.8.0', // add response format header + ], $this->getHeaders())); $this->assertEquals(200, $function['headers']['status-code']); $this->assertArrayHasKey('scopes', $function['body']); $this->assertArrayHasKey('specification', $function['body']); + $this->assertArrayNotHasKey('buildSpecification', $function['body']); + $this->assertArrayNotHasKey('runtimeSpecification', $function['body']); + + // get function with latest version + $function = $this->getFunction($function['body']['$id']); + + $this->assertEquals(200, $function['headers']['status-code']); + $this->assertArrayHasKey('scopes', $function['body']); + $this->assertArrayNotHasKey('specification', $function['body']); + $this->assertArrayHasKey('buildSpecification', $function['body']); + $this->assertArrayHasKey('runtimeSpecification', $function['body']); $functionId = $function['body']['$id'] ?? ''; $this->cleanupFunction($functionId); @@ -2387,15 +2441,17 @@ class FunctionsCustomServerTest extends Scope 'entrypoint' => 'index.js', 'logging' => false, 'execute' => ['any'], - 'specification' => Specification::S_2VCPU_2GB, + 'buildSpecification' => Specification::S_2VCPU_2GB, + 'runtimeSpecification' => Specification::S_1VCPU_1GB, 'commands' => 'echo $APPWRITE_FUNCTION_MEMORY:$APPWRITE_FUNCTION_CPUS', ]); $this->assertEquals(201, $function['headers']['status-code']); - $this->assertEquals(Specification::S_2VCPU_2GB, $function['body']['specification']); + $this->assertEquals(Specification::S_2VCPU_2GB, $function['body']['buildSpecification']); + $this->assertEquals(Specification::S_1VCPU_1GB, $function['body']['runtimeSpecification']); $this->assertNotEmpty($function['body']['$id']); - $functionId = $functionId = $function['body']['$id'] ?? ''; + $functionId = $function['body']['$id'] ?? ''; $deploymentId = $this->setupDeployment($functionId, [ 'code' => $this->packageFunction('basic'), @@ -2414,8 +2470,8 @@ class FunctionsCustomServerTest extends Scope $this->assertNotEmpty($execution['body']['$id']); $executionResponse = json_decode($execution['body']['responseBody'], true); - $this->assertEquals('2048', $executionResponse['APPWRITE_FUNCTION_MEMORY']); - $this->assertEquals('2', $executionResponse['APPWRITE_FUNCTION_CPUS']); + $this->assertEquals('1024', $executionResponse['APPWRITE_FUNCTION_MEMORY']); + $this->assertEquals('1', $executionResponse['APPWRITE_FUNCTION_CPUS']); $this->cleanupFunction($functionId); } @@ -2782,4 +2838,119 @@ class FunctionsCustomServerTest extends Scope $this->cleanupFunction($functionId); } + + public function testFunctionDeploymentRetention(): void + { + $functionIds = []; + + // Default + $response = $this->createFunction([ + 'functionId' => ID::unique(), + 'name' => 'Test retention function', + 'runtime' => 'node-22', + ]); + $this->assertSame(201, $response['headers']['status-code']); + $this->assertSame(0, $response['body']['deploymentRetention']); + $functionIds[] = $response['body']['$id']; + + $response = $this->getFunction($response['body']['$id']); + $this->assertSame(200, $response['headers']['status-code']); + $this->assertSame(0, $response['body']['deploymentRetention']); + + // Success values + $response = $this->createFunction([ + 'functionId' => ID::unique(), + 'name' => 'Test retention function', + 'runtime' => 'node-22', + 'deploymentRetention' => 0 + ]); + $this->assertSame(201, $response['headers']['status-code']); + $this->assertSame(0, $response['body']['deploymentRetention']); + $functionIds[] = $response['body']['$id']; + + $response = $this->getFunction($response['body']['$id']); + $this->assertSame(200, $response['headers']['status-code']); + $this->assertSame(0, $response['body']['deploymentRetention']); + + $response = $this->createFunction([ + 'functionId' => ID::unique(), + 'name' => 'Test retention function', + 'runtime' => 'node-22', + 'deploymentRetention' => 180 + ]); + $this->assertSame(201, $response['headers']['status-code']); + $this->assertSame(180, $response['body']['deploymentRetention']); + $functionIds[] = $response['body']['$id']; + + $response = $this->getFunction($response['body']['$id']); + $this->assertSame(200, $response['headers']['status-code']); + $this->assertSame(180, $response['body']['deploymentRetention']); + + // Failure values + $response = $this->createFunction([ + 'functionId' => ID::unique(), + 'name' => 'Test retention function', + 'runtime' => 'node-22', + 'deploymentRetention' => 999999 + ]); + $this->assertSame(400, $response['headers']['status-code']); + + $response = $this->createFunction([ + 'functionId' => ID::unique(), + 'name' => 'Test retention function', + 'runtime' => 'node-22', + 'deploymentRetention' => -1 + ]); + $this->assertSame(400, $response['headers']['status-code']); + + // Update flow + $response = $this->createFunction([ + 'functionId' => ID::unique(), + 'name' => 'Test retention function', + 'runtime' => 'node-22', + 'deploymentRetention' => 180 + ]); + $this->assertSame(201, $response['headers']['status-code']); + $this->assertSame(180, $response['body']['deploymentRetention']); + $functionIds[] = $response['body']['$id']; + $functionIdForUpdate = $response['body']['$id']; + + $response = $this->updateFunction($functionIdForUpdate, [ + 'name' => 'Test retention function', + 'deploymentRetention' => 90 + ]); + $this->assertSame(200, $response['headers']['status-code']); + $this->assertSame(90, $response['body']['deploymentRetention']); + + $response = $this->getFunction($functionIdForUpdate); + $this->assertSame(200, $response['headers']['status-code']); + $this->assertSame(90, $response['body']['deploymentRetention']); + + $response = $this->updateFunction($functionIdForUpdate, [ + 'name' => 'Test retention function', + ]); + $this->assertSame(200, $response['headers']['status-code']); + $this->assertSame(0, $response['body']['deploymentRetention']); + + $response = $this->getFunction($functionIdForUpdate); + $this->assertSame(200, $response['headers']['status-code']); + $this->assertSame(0, $response['body']['deploymentRetention']); + + // Failed update flow + $response = $this->updateFunction($functionIdForUpdate, [ + 'name' => 'Test retention function', + 'deploymentRetention' => -1 + ]); + $this->assertSame(400, $response['headers']['status-code']); + + $response = $this->updateFunction($functionIdForUpdate, [ + 'name' => 'Test retention function', + 'deploymentRetention' => 999999 + ]); + $this->assertSame(400, $response['headers']['status-code']); + + foreach ($functionIds as $functionId) { + $this->cleanupFunction($functionId); + } + } } diff --git a/tests/e2e/Services/Migrations/MigrationsBase.php b/tests/e2e/Services/Migrations/MigrationsBase.php index c63c75d705..5dac22f701 100644 --- a/tests/e2e/Services/Migrations/MigrationsBase.php +++ b/tests/e2e/Services/Migrations/MigrationsBase.php @@ -1718,7 +1718,7 @@ trait MigrationsBase } /** - * Import VectorDB documents from CSV + * Import VectorsDB documents from CSV */ public function testImportVectordbCSV(): void { @@ -1727,7 +1727,7 @@ trait MigrationsBase $bucketId = null; try { - $database = $this->client->call(Client::METHOD_POST, '/vectordb', [ + $database = $this->client->call(Client::METHOD_POST, '/vectorsdb', [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -1739,7 +1739,7 @@ trait MigrationsBase $this->assertEquals(201, $database['headers']['status-code']); $databaseId = $database['body']['$id']; - $collection = $this->client->call(Client::METHOD_POST, '/vectordb/' . $databaseId . '/collections', [ + $collection = $this->client->call(Client::METHOD_POST, '/vectorsdb/' . $databaseId . '/collections', [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -1773,7 +1773,7 @@ trait MigrationsBase 'x-appwrite-key' => $this->getProject()['apiKey'], ], [ 'fileId' => ID::unique(), - 'file' => new CURLFile(realpath(__DIR__ . '/../../../resources/csv/vectordb-documents.csv'), 'text/csv', 'vectordb-documents.csv'), + 'file' => new CURLFile(realpath(__DIR__ . '/../../../resources/csv/vectorsdb-documents.csv'), 'text/csv', 'vectorsdb-documents.csv'), ]); $this->assertEquals(201, $file['headers']['status-code']); @@ -1805,7 +1805,7 @@ trait MigrationsBase return true; }, 60_000, 500); - $documents = $this->client->call(Client::METHOD_GET, '/vectordb/' . $databaseId . '/collections/' . $collectionId . '/documents', [ + $documents = $this->client->call(Client::METHOD_GET, '/vectorsdb/' . $databaseId . '/collections/' . $collectionId . '/documents', [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'], @@ -1831,7 +1831,7 @@ trait MigrationsBase } if ($databaseId) { - $this->client->call(Client::METHOD_DELETE, '/vectordb/' . $databaseId, [ + $this->client->call(Client::METHOD_DELETE, '/vectorsdb/' . $databaseId, [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'], @@ -1841,14 +1841,14 @@ trait MigrationsBase } /** - * Export VectorDB documents to CSV + * Export VectorsDB documents to CSV */ public function testExportVectordbCSV(): void { $databaseId = null; try { - $database = $this->client->call(Client::METHOD_POST, '/vectordb', [ + $database = $this->client->call(Client::METHOD_POST, '/vectorsdb', [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'], @@ -1860,7 +1860,7 @@ trait MigrationsBase $this->assertEquals(201, $database['headers']['status-code']); $databaseId = $database['body']['$id']; - $collection = $this->client->call(Client::METHOD_POST, '/vectordb/' . $databaseId . '/collections', [ + $collection = $this->client->call(Client::METHOD_POST, '/vectorsdb/' . $databaseId . '/collections', [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'], @@ -1892,7 +1892,7 @@ trait MigrationsBase ]; foreach ($documentsPayload as $payload) { - $response = $this->client->call(Client::METHOD_POST, '/vectordb/' . $databaseId . '/collections/' . $collectionId . '/documents', [ + $response = $this->client->call(Client::METHOD_POST, '/vectorsdb/' . $databaseId . '/collections/' . $collectionId . '/documents', [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'], @@ -1901,7 +1901,7 @@ trait MigrationsBase $this->assertEquals(201, $response['headers']['status-code']); } - $filename = 'vectordb-export-' . ID::unique(); + $filename = 'vectorsdb-export-' . ID::unique(); $migration = $this->client->call(Client::METHOD_POST, '/migrations/csv/exports', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], @@ -1958,7 +1958,7 @@ trait MigrationsBase $this->assertStringContainsString('[0.11,0.22,0.33]', $csvData); } finally { if ($databaseId) { - $this->client->call(Client::METHOD_DELETE, '/vectordb/' . $databaseId, [ + $this->client->call(Client::METHOD_DELETE, '/vectorsdb/' . $databaseId, [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'], @@ -2030,11 +2030,11 @@ trait MigrationsBase } /** - * VectorDB (embeddings collections) + * VectorsDB (embeddings collections) */ - public function testAppwriteMigrationVectorDBDatabase(): array + public function testAppwriteMigrationVectorsDBDatabase(): array { - $response = $this->client->call(Client::METHOD_POST, '/vectordb', [ + $response = $this->client->call(Client::METHOD_POST, '/vectorsdb', [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'], @@ -2051,7 +2051,7 @@ trait MigrationsBase $result = $this->performMigrationSync([ 'resources' => [ - Resource::TYPE_DATABASE_VECTORDB, + Resource::TYPE_DATABASE_VECTORSDB, ], 'endpoint' => $this->endpoint, 'projectId' => $this->getProject()['$id'], @@ -2059,11 +2059,11 @@ trait MigrationsBase ]); $this->assertEquals('completed', $result['status']); - $this->assertEquals([Resource::TYPE_DATABASE_VECTORDB], $result['resources']); - $this->assertArrayHasKey(Resource::TYPE_DATABASE_VECTORDB, $result['statusCounters']); - $this->assertEquals(0, $result['statusCounters'][Resource::TYPE_DATABASE_VECTORDB]['error'] ?? 0); + $this->assertEquals([Resource::TYPE_DATABASE_VECTORSDB], $result['resources']); + $this->assertArrayHasKey(Resource::TYPE_DATABASE_VECTORSDB, $result['statusCounters']); + $this->assertEquals(0, $result['statusCounters'][Resource::TYPE_DATABASE_VECTORSDB]['error'] ?? 0); - $response = $this->client->call(Client::METHOD_GET, '/vectordb/' . $databaseId, [ + $response = $this->client->call(Client::METHOD_GET, '/vectorsdb/' . $databaseId, [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getDestinationProject()['$id'], 'x-appwrite-key' => $this->getDestinationProject()['apiKey'], @@ -2076,7 +2076,7 @@ trait MigrationsBase $this->assertEquals('VDB - Migration DB', $response['body']['name']); // Cleanup on destination - $this->client->call(Client::METHOD_DELETE, '/vectordb/' . $databaseId, [ + $this->client->call(Client::METHOD_DELETE, '/vectorsdb/' . $databaseId, [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getDestinationProject()['$id'], 'x-appwrite-key' => $this->getDestinationProject()['apiKey'], @@ -2087,12 +2087,12 @@ trait MigrationsBase ]; } - #[Depends('testAppwriteMigrationVectorDBDatabase')] - public function testAppwriteMigrationVectorDBCollection(array $data): array + #[Depends('testAppwriteMigrationVectorsDBDatabase')] + public function testAppwriteMigrationVectorsDBCollection(array $data): array { $databaseId = $data['databaseId']; - $collection = $this->client->call(Client::METHOD_POST, '/vectordb/' . $databaseId . '/collections', [ + $collection = $this->client->call(Client::METHOD_POST, '/vectorsdb/' . $databaseId . '/collections', [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'], @@ -2108,7 +2108,7 @@ trait MigrationsBase $result = $this->performMigrationSync([ 'resources' => [ - Resource::TYPE_DATABASE_VECTORDB, + Resource::TYPE_DATABASE_VECTORSDB, Resource::TYPE_COLLECTION, Resource::TYPE_ATTRIBUTE, ], @@ -2118,7 +2118,7 @@ trait MigrationsBase ]); $this->assertEquals('completed', $result['status']); - $response = $this->client->call(Client::METHOD_GET, '/vectordb/' . $databaseId . '/collections/' . $collectionId, [ + $response = $this->client->call(Client::METHOD_GET, '/vectorsdb/' . $databaseId . '/collections/' . $collectionId, [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getDestinationProject()['$id'], 'x-appwrite-key' => $this->getDestinationProject()['apiKey'], @@ -2133,7 +2133,7 @@ trait MigrationsBase $this->assertIsArray($response['body']['attributes']); // Cleanup - $this->client->call(Client::METHOD_DELETE, '/vectordb/' . $databaseId, [ + $this->client->call(Client::METHOD_DELETE, '/vectorsdb/' . $databaseId, [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getDestinationProject()['$id'], 'x-appwrite-key' => $this->getDestinationProject()['apiKey'], @@ -2145,13 +2145,13 @@ trait MigrationsBase ]; } - #[Depends('testAppwriteMigrationVectorDBCollection')] - public function testAppwriteMigrationVectorDBDocument(array $data): void + #[Depends('testAppwriteMigrationVectorsDBCollection')] + public function testAppwriteMigrationVectorsDBDocument(array $data): void { $databaseId = $data['databaseId']; $collectionId = $data['collectionId']; - $document = $this->client->call(Client::METHOD_POST, '/vectordb/' . $databaseId . '/collections/' . $collectionId . '/documents', [ + $document = $this->client->call(Client::METHOD_POST, '/vectorsdb/' . $databaseId . '/collections/' . $collectionId . '/documents', [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'], @@ -2169,7 +2169,7 @@ trait MigrationsBase // Ensure attributes are exported before documents $result = $this->performMigrationSync([ 'resources' => [ - Resource::TYPE_DATABASE_VECTORDB, + Resource::TYPE_DATABASE_VECTORSDB, Resource::TYPE_COLLECTION, Resource::TYPE_ATTRIBUTE, Resource::TYPE_DOCUMENT, @@ -2180,11 +2180,11 @@ trait MigrationsBase ]); $this->assertEquals('completed', $result['status']); - // Verify that TYPE_ATTRIBUTE appears in the resources array for VectorDB - $this->assertContains(Resource::TYPE_ATTRIBUTE, $result['resources'], 'TYPE_ATTRIBUTE should be in resources array for VectorDB'); + // Verify that TYPE_ATTRIBUTE appears in the resources array for VectorsDB + $this->assertContains(Resource::TYPE_ATTRIBUTE, $result['resources'], 'TYPE_ATTRIBUTE should be in resources array for VectorsDB'); // Verify attributes exist on destination before checking document - $collectionResponse = $this->client->call(Client::METHOD_GET, '/vectordb/' . $databaseId . '/collections/' . $collectionId, [ + $collectionResponse = $this->client->call(Client::METHOD_GET, '/vectorsdb/' . $databaseId . '/collections/' . $collectionId, [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getDestinationProject()['$id'], 'x-appwrite-key' => $this->getDestinationProject()['apiKey'], @@ -2194,7 +2194,7 @@ trait MigrationsBase $this->assertArrayHasKey('attributes', $collectionResponse['body']); $this->assertIsArray($collectionResponse['body']['attributes']); - $response = $this->client->call(Client::METHOD_GET, '/vectordb/' . $databaseId . '/collections/' . $collectionId . '/documents/' . $documentId, [ + $response = $this->client->call(Client::METHOD_GET, '/vectorsdb/' . $databaseId . '/collections/' . $collectionId . '/documents/' . $documentId, [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getDestinationProject()['$id'], 'x-appwrite-key' => $this->getDestinationProject()['apiKey'], @@ -2206,13 +2206,13 @@ trait MigrationsBase $this->assertEquals('Migration Test Movie', $response['body']['metadata']['title']); // Cleanup - $this->client->call(Client::METHOD_DELETE, '/vectordb/' . $databaseId, [ + $this->client->call(Client::METHOD_DELETE, '/vectorsdb/' . $databaseId, [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getDestinationProject()['$id'], 'x-appwrite-key' => $this->getDestinationProject()['apiKey'], ]); - $this->client->call(Client::METHOD_DELETE, '/vectordb/' . $databaseId, [ + $this->client->call(Client::METHOD_DELETE, '/vectorsdb/' . $databaseId, [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'], @@ -2517,22 +2517,22 @@ trait MigrationsBase $this->assertEquals(201, $document['headers']['status-code']); $documentId = $document['body']['$id']; - // ====== Create VectorDB (/vectordb) with collection and document ====== - $vector = $this->client->call(Client::METHOD_POST, '/vectordb', [ + // ====== Create VectorsDB (/vectorsdb) with collection and document ====== + $vector = $this->client->call(Client::METHOD_POST, '/vectorsdb', [ 'content-type' => 'application/json', 'x-appwrite-project' => $sourceProject['$id'], 'x-appwrite-key' => $sourceProject['apiKey'], ], [ 'databaseId' => ID::unique(), - 'name' => 'Mixed VectorDB', + 'name' => 'Mixed VectorsDB', ]); $this->assertEquals(201, $vector['headers']['status-code']); $this->assertNotEmpty($vector['body']['$id']); $vectorDatabaseId = $vector['body']['$id']; - // Create Collection in VectorDB - $vectorCollection = $this->client->call(Client::METHOD_POST, '/vectordb/' . $vectorDatabaseId . '/collections', [ + // Create Collection in VectorsDB + $vectorCollection = $this->client->call(Client::METHOD_POST, '/vectorsdb/' . $vectorDatabaseId . '/collections', [ 'content-type' => 'application/json', 'x-appwrite-project' => $sourceProject['$id'], 'x-appwrite-key' => $sourceProject['apiKey'], @@ -2545,9 +2545,9 @@ trait MigrationsBase $this->assertEquals(201, $vectorCollection['headers']['status-code']); $vectorCollectionId = $vectorCollection['body']['$id']; - // Wait for VectorDB collection attributes to be ready + // Wait for VectorsDB collection attributes to be ready $this->assertEventually(function () use ($vectorDatabaseId, $vectorCollectionId, $sourceProject) { - $response = $this->client->call(Client::METHOD_GET, '/vectordb/' . $vectorDatabaseId . '/collections/' . $vectorCollectionId, [ + $response = $this->client->call(Client::METHOD_GET, '/vectorsdb/' . $vectorDatabaseId . '/collections/' . $vectorCollectionId, [ 'content-type' => 'application/json', 'x-appwrite-project' => $sourceProject['$id'], 'x-appwrite-key' => $sourceProject['apiKey'], @@ -2570,7 +2570,7 @@ trait MigrationsBase }, 10000, 500); $metadataIndexKey = '_key_metadata'; - $vectorIndexes = $this->client->call(Client::METHOD_GET, '/vectordb/' . $vectorDatabaseId . '/collections/' . $vectorCollectionId . '/indexes', [ + $vectorIndexes = $this->client->call(Client::METHOD_GET, '/vectorsdb/' . $vectorDatabaseId . '/collections/' . $vectorCollectionId . '/indexes', [ 'content-type' => 'application/json', 'x-appwrite-project' => $sourceProject['$id'], 'x-appwrite-key' => $sourceProject['apiKey'], @@ -2587,7 +2587,7 @@ trait MigrationsBase $this->assertEquals(Database::INDEX_OBJECT, $metadataIndex['type']); $vectorEmbeddingIndexKey = 'embedding_euclidean'; - $vectorEmbeddingIndex = $this->client->call(Client::METHOD_POST, '/vectordb/' . $vectorDatabaseId . '/collections/' . $vectorCollectionId . '/indexes', [ + $vectorEmbeddingIndex = $this->client->call(Client::METHOD_POST, '/vectorsdb/' . $vectorDatabaseId . '/collections/' . $vectorCollectionId . '/indexes', [ 'content-type' => 'application/json', 'x-appwrite-project' => $sourceProject['$id'], 'x-appwrite-key' => $sourceProject['apiKey'], @@ -2599,7 +2599,7 @@ trait MigrationsBase $this->assertEquals(202, $vectorEmbeddingIndex['headers']['status-code']); $this->assertEventually(function () use ($vectorDatabaseId, $vectorCollectionId, $vectorEmbeddingIndexKey, $sourceProject) { - $index = $this->client->call(Client::METHOD_GET, '/vectordb/' . $vectorDatabaseId . '/collections/' . $vectorCollectionId . '/indexes/' . $vectorEmbeddingIndexKey, [ + $index = $this->client->call(Client::METHOD_GET, '/vectorsdb/' . $vectorDatabaseId . '/collections/' . $vectorCollectionId . '/indexes/' . $vectorEmbeddingIndexKey, [ 'content-type' => 'application/json', 'x-appwrite-project' => $sourceProject['$id'], 'x-appwrite-key' => $sourceProject['apiKey'], @@ -2612,8 +2612,8 @@ trait MigrationsBase } }, 30000, 500); - // Create Document in VectorDB Collection - $vectorDocument = $this->client->call(Client::METHOD_POST, '/vectordb/' . $vectorDatabaseId . '/collections/' . $vectorCollectionId . '/documents', [ + // Create Document in VectorsDB Collection + $vectorDocument = $this->client->call(Client::METHOD_POST, '/vectorsdb/' . $vectorDatabaseId . '/collections/' . $vectorCollectionId . '/documents', [ 'content-type' => 'application/json', 'x-appwrite-project' => $sourceProject['$id'], 'x-appwrite-key' => $sourceProject['apiKey'], @@ -2638,7 +2638,7 @@ trait MigrationsBase Resource::TYPE_DATABASE_DOCUMENTSDB, Resource::TYPE_COLLECTION, Resource::TYPE_DOCUMENT, - Resource::TYPE_DATABASE_VECTORDB, + Resource::TYPE_DATABASE_VECTORSDB, Resource::TYPE_ATTRIBUTE, Resource::TYPE_INDEX, ], @@ -2661,7 +2661,7 @@ trait MigrationsBase Resource::TYPE_DATABASE_DOCUMENTSDB, Resource::TYPE_COLLECTION, Resource::TYPE_DOCUMENT, - Resource::TYPE_DATABASE_VECTORDB, + Resource::TYPE_DATABASE_VECTORSDB, Resource::TYPE_ATTRIBUTE, Resource::TYPE_INDEX, ], $result['resources']); @@ -2734,7 +2734,7 @@ trait MigrationsBase return $pendingCount === 0; }, 30000, 1000); // 30 second timeout, check every 1 second - // Assert Collection counters (covers both DocumentsDB and VectorDB collections) + // Assert Collection counters (covers both DocumentsDB and VectorsDB collections) $this->assertArrayHasKey(Resource::TYPE_COLLECTION, $result['statusCounters']); $this->assertEquals(0, $result['statusCounters'][Resource::TYPE_COLLECTION]['error']); $this->assertEquals(0, $result['statusCounters'][Resource::TYPE_COLLECTION]['pending']); @@ -2744,7 +2744,7 @@ trait MigrationsBase // Get migration status before asserting Document counters $result = $this->getMigrationStatus($migrationId); - // Assert Document counters (covers both DocumentsDB and VectorDB documents) + // Assert Document counters (covers both DocumentsDB and VectorsDB documents) $this->assertArrayHasKey(Resource::TYPE_DOCUMENT, $result['statusCounters']); $this->assertEquals(0, $result['statusCounters'][Resource::TYPE_DOCUMENT]['error']); $this->assertEquals(0, $result['statusCounters'][Resource::TYPE_DOCUMENT]['pending']); @@ -2752,19 +2752,19 @@ trait MigrationsBase $this->assertEquals(0, $result['statusCounters'][Resource::TYPE_DOCUMENT]['processing']); $this->assertEquals(0, $result['statusCounters'][Resource::TYPE_DOCUMENT]['warning']); - // Get migration status before asserting VectorDB counters + // Get migration status before asserting VectorsDB counters $result = $this->getMigrationStatus($migrationId); - // Assert VectorDB counters - $this->assertArrayHasKey(Resource::TYPE_DATABASE_VECTORDB, $result['statusCounters']); - $this->assertEquals(0, $result['statusCounters'][Resource::TYPE_DATABASE_VECTORDB]['error']); - $this->assertEquals(0, $result['statusCounters'][Resource::TYPE_DATABASE_VECTORDB]['pending']); - $this->assertEquals(1, $result['statusCounters'][Resource::TYPE_DATABASE_VECTORDB]['success']); - $this->assertEquals(0, $result['statusCounters'][Resource::TYPE_DATABASE_VECTORDB]['processing']); - $this->assertEquals(0, $result['statusCounters'][Resource::TYPE_DATABASE_VECTORDB]['warning']); + // Assert VectorsDB counters + $this->assertArrayHasKey(Resource::TYPE_DATABASE_VECTORSDB, $result['statusCounters']); + $this->assertEquals(0, $result['statusCounters'][Resource::TYPE_DATABASE_VECTORSDB]['error']); + $this->assertEquals(0, $result['statusCounters'][Resource::TYPE_DATABASE_VECTORSDB]['pending']); + $this->assertEquals(1, $result['statusCounters'][Resource::TYPE_DATABASE_VECTORSDB]['success']); + $this->assertEquals(0, $result['statusCounters'][Resource::TYPE_DATABASE_VECTORSDB]['processing']); + $this->assertEquals(0, $result['statusCounters'][Resource::TYPE_DATABASE_VECTORSDB]['warning']); // Get migration status before asserting Attribute counters $result = $this->getMigrationStatus($migrationId); - // Assert Attribute counters (for VectorDB) + // Assert Attribute counters (for VectorsDB) $this->assertArrayHasKey(Resource::TYPE_ATTRIBUTE, $result['statusCounters']); $this->assertEquals(0, $result['statusCounters'][Resource::TYPE_ATTRIBUTE]['error']); $this->assertEquals(0, $result['statusCounters'][Resource::TYPE_ATTRIBUTE]['pending']); @@ -2889,8 +2889,8 @@ trait MigrationsBase $this->assertEquals(['email'], $documentsIndexDestination['body']['attributes']); } - // ====== Validate on destination: VectorDB resources ====== - $response = $this->client->call(Client::METHOD_GET, '/vectordb/' . $vectorDatabaseId, [ + // ====== Validate on destination: VectorsDB resources ====== + $response = $this->client->call(Client::METHOD_GET, '/vectorsdb/' . $vectorDatabaseId, [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getDestinationProject()['$id'], 'x-appwrite-key' => $this->getDestinationProject()['apiKey'], @@ -2898,10 +2898,10 @@ trait MigrationsBase $this->assertEquals(200, $response['headers']['status-code']); $this->assertEquals($vectorDatabaseId, $response['body']['$id']); - $this->assertEquals('Mixed VectorDB', $response['body']['name']); + $this->assertEquals('Mixed VectorsDB', $response['body']['name']); - // Validate VectorDB Collection - $response = $this->client->call(Client::METHOD_GET, '/vectordb/' . $vectorDatabaseId . '/collections/' . $vectorCollectionId, [ + // Validate VectorsDB Collection + $response = $this->client->call(Client::METHOD_GET, '/vectorsdb/' . $vectorDatabaseId . '/collections/' . $vectorCollectionId, [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getDestinationProject()['$id'], 'x-appwrite-key' => $this->getDestinationProject()['apiKey'], @@ -2914,7 +2914,7 @@ trait MigrationsBase $this->assertArrayHasKey('attributes', $response['body']); $this->assertIsArray($response['body']['attributes']); - $vectorIndexesDestination = $this->client->call(Client::METHOD_GET, '/vectordb/' . $vectorDatabaseId . '/collections/' . $vectorCollectionId . '/indexes', [ + $vectorIndexesDestination = $this->client->call(Client::METHOD_GET, '/vectorsdb/' . $vectorDatabaseId . '/collections/' . $vectorCollectionId . '/indexes', [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getDestinationProject()['$id'], 'x-appwrite-key' => $this->getDestinationProject()['apiKey'], @@ -2931,8 +2931,8 @@ trait MigrationsBase $this->assertArrayHasKey($vectorEmbeddingIndexKey, $indexByKey, 'Embeddings HNSW index should exist on destination'); $this->assertEquals(Database::INDEX_HNSW_EUCLIDEAN, $indexByKey[$vectorEmbeddingIndexKey]['type']); - // Validate VectorDB Document - $response = $this->client->call(Client::METHOD_GET, '/vectordb/' . $vectorDatabaseId . '/collections/' . $vectorCollectionId . '/documents/' . $vectorDocumentId, [ + // Validate VectorsDB Document + $response = $this->client->call(Client::METHOD_GET, '/vectorsdb/' . $vectorDatabaseId . '/collections/' . $vectorCollectionId . '/documents/' . $vectorDocumentId, [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getDestinationProject()['$id'], 'x-appwrite-key' => $this->getDestinationProject()['apiKey'], @@ -2955,7 +2955,7 @@ trait MigrationsBase 'x-appwrite-key' => $this->getDestinationProject()['apiKey'], ]); - $this->client->call(Client::METHOD_DELETE, '/vectordb/' . $vectorDatabaseId, [ + $this->client->call(Client::METHOD_DELETE, '/vectorsdb/' . $vectorDatabaseId, [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getDestinationProject()['$id'], 'x-appwrite-key' => $this->getDestinationProject()['apiKey'], @@ -2974,7 +2974,7 @@ trait MigrationsBase 'x-appwrite-key' => $sourceProject['apiKey'], ]); - $this->client->call(Client::METHOD_DELETE, '/vectordb/' . $vectorDatabaseId, [ + $this->client->call(Client::METHOD_DELETE, '/vectorsdb/' . $vectorDatabaseId, [ 'content-type' => 'application/json', 'x-appwrite-project' => $sourceProject['$id'], 'x-appwrite-key' => $sourceProject['apiKey'], diff --git a/tests/e2e/Services/Projects/ProjectsConsoleClientTest.php b/tests/e2e/Services/Projects/ProjectsConsoleClientTest.php index 6eecc13a7b..28cb146508 100644 --- a/tests/e2e/Services/Projects/ProjectsConsoleClientTest.php +++ b/tests/e2e/Services/Projects/ProjectsConsoleClientTest.php @@ -177,15 +177,15 @@ class ProjectsConsoleClientTest extends Scope ]); $this->assertEquals(201, $documentsCollection['headers']['status-code']); - // Create vectordb database and collection - $vectorDb = $this->client->call(Client::METHOD_POST, '/vectordb', $projectAdminHeaders, [ + // Create vectorsdb database and collection + $vectorDb = $this->client->call(Client::METHOD_POST, '/vectorsdb', $projectAdminHeaders, [ 'databaseId' => ID::unique(), 'name' => 'Vector DB', ]); $this->assertEquals(201, $vectorDb['headers']['status-code']); $vectorDbId = $vectorDb['body']['$id']; - $vectorCollection = $this->client->call(Client::METHOD_POST, '/vectordb/' . $vectorDbId . '/collections', $projectAdminHeaders, [ + $vectorCollection = $this->client->call(Client::METHOD_POST, '/vectorsdb/' . $vectorDbId . '/collections', $projectAdminHeaders, [ 'collectionId' => ID::unique(), 'name' => 'Vector Collection', 'dimension' => 3, diff --git a/tests/e2e/Services/Realtime/RealtimeCustomClientTest.php b/tests/e2e/Services/Realtime/RealtimeCustomClientTest.php index 2c949ca07e..774d0016f9 100644 --- a/tests/e2e/Services/Realtime/RealtimeCustomClientTest.php +++ b/tests/e2e/Services/Realtime/RealtimeCustomClientTest.php @@ -5061,7 +5061,7 @@ class RealtimeCustomClientTest extends Scope $client->close(); } - public function testChannelVectorDB() + public function testChannelVectorsDB() { $user = $this->getUser(); $session = $user['session'] ?? ''; @@ -5084,8 +5084,8 @@ class RealtimeCustomClientTest extends Scope $this->assertNotEmpty($response['data']['user']); $this->assertEquals($user['$id'], $response['data']['user']['$id']); - // Create VectorDB database - $database = $this->client->call(Client::METHOD_POST, '/vectordb', array_merge([ + // Create VectorsDB database + $database = $this->client->call(Client::METHOD_POST, '/vectorsdb', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -5096,8 +5096,8 @@ class RealtimeCustomClientTest extends Scope $databaseId = $database['body']['$id']; - // Create collection in VectorDB - $actors = $this->client->call(Client::METHOD_POST, '/vectordb/' . $databaseId . '/collections', array_merge([ + // Create collection in VectorsDB + $actors = $this->client->call(Client::METHOD_POST, '/vectorsdb/' . $databaseId . '/collections', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -5113,8 +5113,8 @@ class RealtimeCustomClientTest extends Scope $actorsId = $actors['body']['$id']; - // Create document in VectorDB - $document = $this->client->call(Client::METHOD_POST, '/vectordb/' . $databaseId . '/collections/' . $actorsId . '/documents', array_merge([ + // Create document in VectorsDB + $document = $this->client->call(Client::METHOD_POST, '/vectorsdb/' . $databaseId . '/collections/' . $actorsId . '/documents', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders()), [ @@ -5138,18 +5138,18 @@ class RealtimeCustomClientTest extends Scope $this->assertEquals('event', $response['type']); $this->assertNotEmpty($response['data']); $this->assertArrayHasKey('timestamp', $response['data']); - // vectordb channels should include 3 items like documentsdb + // vectorsdb channels should include 3 items like documentsdb $this->assertCount(3, $response['data']['channels']); $this->assertContains('documents', $response['data']['channels']); - $this->assertContains('vectordb.' . $databaseId . '.collections.' . $actorsId . '.documents.' . $documentId, $response['data']['channels']); - $this->assertContains('vectordb.' . $databaseId . '.collections.' . $actorsId . '.documents', $response['data']['channels']); + $this->assertContains('vectorsdb.' . $databaseId . '.collections.' . $actorsId . '.documents.' . $documentId, $response['data']['channels']); + $this->assertContains('vectorsdb.' . $databaseId . '.collections.' . $actorsId . '.documents', $response['data']['channels']); $this->assertNotEmpty($response['data']['payload']); $this->assertIsArray($response['data']['payload']['embeddings']); $this->assertCount(3, $response['data']['payload']['embeddings']); $this->assertEquals('Chris Evans', $response['data']['payload']['metadata']['name']); // Update document - $this->client->call(Client::METHOD_PATCH, '/vectordb/' . $databaseId . '/collections/' . $actorsId . '/documents/' . $documentId, array_merge([ + $this->client->call(Client::METHOD_PATCH, '/vectorsdb/' . $databaseId . '/collections/' . $actorsId . '/documents/' . $documentId, array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders()), [ @@ -5171,14 +5171,14 @@ class RealtimeCustomClientTest extends Scope $this->assertNotEmpty($response['data']); $this->assertArrayHasKey('timestamp', $response['data']); $this->assertCount(3, $response['data']['channels']); - $this->assertContains('vectordb.' . $databaseId . '.collections.' . $actorsId . '.documents.' . $documentId, $response['data']['channels']); - $this->assertContains('vectordb.' . $databaseId . '.collections.' . $actorsId . '.documents', $response['data']['channels']); + $this->assertContains('vectorsdb.' . $databaseId . '.collections.' . $actorsId . '.documents.' . $documentId, $response['data']['channels']); + $this->assertContains('vectorsdb.' . $databaseId . '.collections.' . $actorsId . '.documents', $response['data']['channels']); $this->assertNotEmpty($response['data']['payload']); $this->assertIsArray($response['data']['payload']['embeddings']); $this->assertEquals('Chris Evans 2', $response['data']['payload']['metadata']['name']); // Delete document - $this->client->call(Client::METHOD_DELETE, '/vectordb/' . $databaseId . '/collections/' . $actorsId . '/documents/' . $documentId, array_merge([ + $this->client->call(Client::METHOD_DELETE, '/vectorsdb/' . $databaseId . '/collections/' . $actorsId . '/documents/' . $documentId, array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders())); @@ -5190,11 +5190,11 @@ class RealtimeCustomClientTest extends Scope $this->assertNotEmpty($response['data']); $this->assertArrayHasKey('timestamp', $response['data']); $this->assertCount(3, $response['data']['channels']); - $this->assertContains('vectordb.' . $databaseId . '.collections.' . $actorsId . '.documents.' . $documentId, $response['data']['channels']); - $this->assertContains('vectordb.' . $databaseId . '.collections.' . $actorsId . '.documents', $response['data']['channels']); + $this->assertContains('vectorsdb.' . $databaseId . '.collections.' . $actorsId . '.documents.' . $documentId, $response['data']['channels']); + $this->assertContains('vectorsdb.' . $databaseId . '.collections.' . $actorsId . '.documents', $response['data']['channels']); // Bulk create two documents - $this->client->call(Client::METHOD_POST, "/vectordb/{$databaseId}/collections/{$actorsId}/documents", array_merge([ + $this->client->call(Client::METHOD_POST, "/vectorsdb/{$databaseId}/collections/{$actorsId}/documents", array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] @@ -5229,10 +5229,10 @@ class RealtimeCustomClientTest extends Scope $this->assertNotEmpty($response['data']); $this->assertArrayHasKey('timestamp', $response['data']); $this->assertCount(3, $response['data']['channels']); - $this->assertContains('vectordb.' . $databaseId . '.collections.' . $actorsId . '.documents.' . $response['data']['payload']['$id'] . '.create', $response['data']['events']); - $this->assertContains('vectordb.*.collections.*.documents.*.create', $response['data']['events']); - $this->assertContains('vectordb.' . $databaseId . '.collections.*.documents.*.create', $response['data']['events']); - $this->assertContains('vectordb.*.collections.' . $actorsId . '.documents.*.create', $response['data']['events']); + $this->assertContains('vectorsdb.' . $databaseId . '.collections.' . $actorsId . '.documents.' . $response['data']['payload']['$id'] . '.create', $response['data']['events']); + $this->assertContains('vectorsdb.*.collections.*.documents.*.create', $response['data']['events']); + $this->assertContains('vectorsdb.' . $databaseId . '.collections.*.documents.*.create', $response['data']['events']); + $this->assertContains('vectorsdb.*.collections.' . $actorsId . '.documents.*.create', $response['data']['events']); $this->assertNotEmpty($response['data']['payload']); $this->assertIsArray($response['data']['payload']); @@ -5244,7 +5244,7 @@ class RealtimeCustomClientTest extends Scope $this->assertNotEmpty($response['data']); $this->assertArrayHasKey('timestamp', $response['data']); $this->assertCount(3, $response['data']['channels']); - $this->assertContains('vectordb.' . $databaseId . '.collections.' . $actorsId . '.documents.' . $response['data']['payload']['$id'] . '.create', $response['data']['events']); + $this->assertContains('vectorsdb.' . $databaseId . '.collections.' . $actorsId . '.documents.' . $response['data']['payload']['$id'] . '.create', $response['data']['events']); $client->close(); } diff --git a/tests/e2e/Services/Sites/SitesConsoleClientTest.php b/tests/e2e/Services/Sites/SitesConsoleClientTest.php index d8a352843e..2a94dded5f 100644 --- a/tests/e2e/Services/Sites/SitesConsoleClientTest.php +++ b/tests/e2e/Services/Sites/SitesConsoleClientTest.php @@ -7,6 +7,7 @@ use Tests\E2E\Client; use Tests\E2E\Scopes\ProjectCustom; use Tests\E2E\Scopes\Scope; use Tests\E2E\Scopes\SideConsole; +use Utopia\Console; use Utopia\Database\Helpers\ID; class SitesConsoleClientTest extends Scope @@ -147,4 +148,52 @@ class SitesConsoleClientTest extends Scope $this->cleanupSite($siteId); } + + public function testSiteDeploymentRetentionWithMaintenance(): void + { + $siteId = $this->setupSite([ + 'siteId' => ID::unique(), + 'name' => 'Test retention site', + 'framework' => 'other', + 'deploymentRetention' => 180, + 'buildRuntime' => 'node-22', + ]); + $this->assertNotEmpty($siteId); + + $deploymentIdInactive = $this->setupDeployment($siteId, [ + 'code' => $this->packageSite('static'), + 'activate' => true + ]); + $this->assertNotEmpty($deploymentIdInactive); + + $deploymentIdInactiveOld = $this->setupDeployment($siteId, [ + 'code' => $this->packageSite('static'), + 'activate' => true + ]); + $this->assertNotEmpty($deploymentIdInactiveOld); + + $deploymentIdActive = $this->setupDeployment($siteId, [ + 'code' => $this->packageSite('static'), + 'activate' => true + ]); + $this->assertNotEmpty($deploymentIdActive); + + $stdout = ''; + $stderr = ''; + $code = Console::execute("docker exec appwrite-task-maintenance time-travel --projectId={$this->getProject()['$id']} --resourceType=deployment --resourceId={$deploymentIdInactiveOld} --createdAt=2020-01-01T00:00:00Z", '', $stdout, $stderr); + $this->assertSame(0, $code, "Time-travel command failed with code $code: $stderr ($stdout)"); + + $stdout = ''; + $stderr = ''; + $code = Console::execute("docker exec appwrite-task-maintenance maintenance --type=trigger", '', $stdout, $stderr); + $this->assertSame(0, $code, "Maintenance command failed with code $code: $stderr ($stdout)"); + + $this->assertEventually(function () use ($siteId) { + $response = $this->listDeployments($siteId); + $this->assertSame(200, $response['headers']['status-code']); + $this->assertSame(2, $response['body']['total']); + }); + + $this->cleanupSite($siteId); + } } diff --git a/tests/e2e/Services/Sites/SitesCustomServerTest.php b/tests/e2e/Services/Sites/SitesCustomServerTest.php index dbed1e884b..9bb4a34ff5 100644 --- a/tests/e2e/Services/Sites/SitesCustomServerTest.php +++ b/tests/e2e/Services/Sites/SitesCustomServerTest.php @@ -26,26 +26,34 @@ class SitesCustomServerTest extends Scope { $specifications = $this->listSpecifications(); $this->assertEquals(200, $specifications['headers']['status-code']); - $this->assertGreaterThan(0, $specifications['body']['total']); + $this->assertGreaterThanOrEqual(2, $specifications['body']['total']); $this->assertArrayHasKey(0, $specifications['body']['specifications']); + $this->assertArrayHasKey(1, $specifications['body']['specifications']); $this->assertArrayHasKey('memory', $specifications['body']['specifications'][0]); $this->assertArrayHasKey('cpus', $specifications['body']['specifications'][0]); $this->assertArrayHasKey('enabled', $specifications['body']['specifications'][0]); $this->assertArrayHasKey('slug', $specifications['body']['specifications'][0]); + $this->assertArrayHasKey('memory', $specifications['body']['specifications'][1]); + $this->assertArrayHasKey('cpus', $specifications['body']['specifications'][1]); + $this->assertArrayHasKey('enabled', $specifications['body']['specifications'][1]); + $this->assertArrayHasKey('slug', $specifications['body']['specifications'][1]); $site = $this->createSite([ 'buildRuntime' => 'node-22', 'framework' => 'other', 'name' => 'Specs site', 'siteId' => ID::unique(), - 'specification' => $specifications['body']['specifications'][0]['slug'] + 'buildSpecification' => $specifications['body']['specifications'][0]['slug'], + 'runtimeSpecification' => $specifications['body']['specifications'][1]['slug'], ]); $this->assertEquals(201, $site['headers']['status-code']); - $this->assertEquals($specifications['body']['specifications'][0]['slug'], $site['body']['specification']); + $this->assertEquals($specifications['body']['specifications'][0]['slug'], $site['body']['buildSpecification']); + $this->assertEquals($specifications['body']['specifications'][1]['slug'], $site['body']['runtimeSpecification']); $site = $this->getSite($site['body']['$id']); $this->assertEquals(200, $site['headers']['status-code']); - $this->assertEquals($specifications['body']['specifications'][0]['slug'], $site['body']['specification']); + $this->assertEquals($specifications['body']['specifications'][0]['slug'], $site['body']['buildSpecification']); + $this->assertEquals($specifications['body']['specifications'][1]['slug'], $site['body']['runtimeSpecification']); $this->cleanupSite($site['body']['$id']); @@ -54,7 +62,16 @@ class SitesCustomServerTest extends Scope 'framework' => 'other', 'name' => 'Specs site', 'siteId' => ID::unique(), - 'specification' => 'cheap-please' + 'buildSpecification' => 'cheap-please' + ]); + $this->assertEquals(400, $site['headers']['status-code']); + + $site = $this->createSite([ + 'buildRuntime' => 'node-22', + 'framework' => 'other', + 'name' => 'Specs site', + 'siteId' => ID::unique(), + 'runtimeSpecification' => 'cheap-please' ]); $this->assertEquals(400, $site['headers']['status-code']); } @@ -1292,12 +1309,12 @@ class SitesCustomServerTest extends Scope 'providerBranch' => 'main', 'providerRootDirectory' => './', '$id' => $siteId, - 'specification' => Specification::S_1VCPU_1GB, + 'runtimeSpecification' => Specification::S_1VCPU_1GB, ]); $this->assertEquals(200, $site['headers']['status-code']); $this->assertNotEmpty($site['body']['$id']); - $this->assertEquals(Specification::S_1VCPU_1GB, $site['body']['specification']); + $this->assertEquals(Specification::S_1VCPU_1GB, $site['body']['runtimeSpecification']); // Change the specs to 1vcpu 512mb $site = $this->updateSite([ @@ -1309,12 +1326,12 @@ class SitesCustomServerTest extends Scope 'providerBranch' => 'main', 'providerRootDirectory' => './', '$id' => $siteId, - 'specification' => Specification::S_1VCPU_512MB, + 'runtimeSpecification' => Specification::S_1VCPU_512MB, ]); $this->assertEquals(200, $site['headers']['status-code']); $this->assertNotEmpty($site['body']['$id']); - $this->assertEquals(Specification::S_1VCPU_512MB, $site['body']['specification']); + $this->assertEquals(Specification::S_1VCPU_512MB, $site['body']['runtimeSpecification']); /** * Test for FAILURE @@ -1329,11 +1346,26 @@ class SitesCustomServerTest extends Scope 'providerBranch' => 'main', 'providerRootDirectory' => './', '$id' => $siteId, - 'specification' => 's-2vcpu-512mb', // Invalid specification + 'buildSpecification' => 's-2vcpu-512mb', // Invalid specification ]); $this->assertEquals(400, $site['headers']['status-code']); - $this->assertStringStartsWith('Invalid `specification` param: Specification must be one of:', $site['body']['message']); + $this->assertStringStartsWith('Invalid `buildSpecification` param: Specification must be one of:', $site['body']['message']); + + $site = $this->updateSite([ + 'buildRuntime' => 'node-22', + 'fallbackFile' => '', + 'framework' => 'other', + 'name' => 'Test Site', + 'outputDirectory' => './', + 'providerBranch' => 'main', + 'providerRootDirectory' => './', + '$id' => $siteId, + 'runtimeSpecification' => 's-2vcpu-512mb', // Invalid specification + ]); + + $this->assertEquals(400, $site['headers']['status-code']); + $this->assertStringStartsWith('Invalid `runtimeSpecification` param: Specification must be one of:', $site['body']['message']); $this->cleanupSite($siteId); } @@ -3006,4 +3038,244 @@ class SitesCustomServerTest extends Scope $this->cleanupSite($siteId); } + + public function testSiteCustomStartCommand(): void + { + $siteId = $this->setupSite([ + 'siteId' => ID::unique(), + 'name' => 'Astro site', + 'framework' => 'astro', + 'adapter' => 'ssr', + 'startCommand' => 'node custom-server.js', + 'buildRuntime' => 'node-22', + 'outputDirectory' => './dist', + 'buildCommand' => 'npm run build', + 'installCommand' => 'npm install', + 'fallbackFile' => '', + ]); + + $this->assertNotEmpty($siteId); + + $domain = $this->setupSiteDomain($siteId); + + $deploymentId = $this->setupDeployment($siteId, [ + 'code' => $this->packageSite('astro-custom-start-command'), + 'activate' => 'true' + ]); + + $this->assertNotEmpty($deploymentId); + + $domain = $this->getSiteDomain($siteId); + $proxyClient = new Client(); + $proxyClient->setEndpoint('http://' . $domain); + + $response = $proxyClient->call(Client::METHOD_GET, '/'); + $this->assertEquals(200, $response['headers']['status-code']); + $this->assertStringContainsString("Homepage OK", $response['body']); + + $response = $proxyClient->call(Client::METHOD_GET, '/ssr'); + $this->assertEquals(200, $response['headers']['status-code']); + $this->assertStringContainsString("SSR OK", $response['body']); + $originalBody = $response['body']; + $response = $proxyClient->call(Client::METHOD_GET, '/ssr'); + $this->assertEquals(200, $response['headers']['status-code']); + $this->assertStringContainsString("SSR OK", $response['body']); + $this->assertNotEquals($originalBody, $response['body']); // Includes Date.now() + + $response = $proxyClient->call(Client::METHOD_GET, '/ssr-custom'); + $this->assertEquals(200, $response['headers']['status-code']); + $this->assertStringContainsString("Custom SSR OK", $response['body']); + $originalBody = $response['body']; + $response = $proxyClient->call(Client::METHOD_GET, '/ssr-custom'); + $this->assertEquals(200, $response['headers']['status-code']); + $this->assertStringContainsString("Custom SSR OK", $response['body']); + $this->assertNotEquals($originalBody, $response['body']); // Includes Date.now() + + $response = $proxyClient->call(Client::METHOD_GET, '/non-existing'); + $this->assertEquals(500, $response['headers']['status-code']); + $this->assertStringContainsString("Custom error", $response['body']); + + $this->cleanupSite($siteId); + } + + public function testSiteSpecifications() + { + // Check if the site specifications are correctly set in builds + $site = $this->createSite([ + 'siteId' => ID::unique(), + 'name' => 'Astro site', + 'framework' => 'astro', + 'adapter' => 'ssr', + 'buildRuntime' => 'node-22', + 'outputDirectory' => './dist', + 'buildCommand' => 'npm run build && echo $APPWRITE_SITE_MEMORY:$APPWRITE_SITE_CPUS', + 'installCommand' => 'npm ci', + 'fallbackFile' => '', + 'buildSpecification' => Specification::S_1VCPU_1GB, + 'runtimeSpecification' => Specification::S_05VCPU_512MB, + ]); + + $this->assertEquals(201, $site['headers']['status-code']); + $this->assertEquals(Specification::S_1VCPU_1GB, $site['body']['buildSpecification']); + $this->assertEquals(Specification::S_05VCPU_512MB, $site['body']['runtimeSpecification']); + $this->assertNotEmpty($site['body']['$id']); + + $siteId = $site['body']['$id'] ?? ''; + + $domain = $this->setupSiteDomain($siteId); + + $deploymentId = $this->setupDeployment($siteId, [ + 'code' => $this->packageSite('astro'), + 'activate' => true + ]); + + $this->assertEventually(function () use ($siteId, $deploymentId) { + $deployment = $this->getDeployment($siteId, $deploymentId); + // TODO: This assertion is not testing what we set in create function, because build worker currently overrides to minimal build specs + $this->assertStringContainsString('2048:1', $deployment['body']['buildLogs']); + }, 10000, 500); + + // Check if the sites specifications are correctly set in executions + $proxyClient = new Client(); + $proxyClient->setEndpoint('http://' . $domain); + + $response = $proxyClient->call(Client::METHOD_GET, '/specs'); + + $this->assertEquals(200, $response['headers']['status-code']); + $this->assertNotEmpty($response['body']); + $this->assertEquals('512', $response['body']['APPWRITE_SITE_MEMORY']); + $this->assertEquals('0.5', $response['body']['APPWRITE_SITE_CPUS']); + + $this->cleanupSite($siteId); + } + + public function testSiteDeploymentRetention(): void + { + $siteIds = []; + + // Default + $response = $this->createSite([ + 'siteId' => ID::unique(), + 'name' => 'Test retention site', + 'framework' => 'other', + 'buildRuntime' => 'node-22', + ]); + $this->assertSame(201, $response['headers']['status-code']); + $this->assertSame(0, $response['body']['deploymentRetention']); + $siteIds[] = $response['body']['$id']; + + $response = $this->getSite($response['body']['$id']); + $this->assertSame(200, $response['headers']['status-code']); + $this->assertSame(0, $response['body']['deploymentRetention']); + + // Success values + $response = $this->createSite([ + 'siteId' => ID::unique(), + 'name' => 'Test retention site', + 'framework' => 'other', + 'buildRuntime' => 'node-22', + 'deploymentRetention' => 0 + ]); + $this->assertSame(201, $response['headers']['status-code']); + $this->assertSame(0, $response['body']['deploymentRetention']); + $siteIds[] = $response['body']['$id']; + + $response = $this->getSite($response['body']['$id']); + $this->assertSame(200, $response['headers']['status-code']); + $this->assertSame(0, $response['body']['deploymentRetention']); + + $response = $this->createSite([ + 'siteId' => ID::unique(), + 'name' => 'Test retention site', + 'framework' => 'other', + 'buildRuntime' => 'node-22', + 'deploymentRetention' => 180 + ]); + $this->assertSame(201, $response['headers']['status-code']); + $this->assertSame(180, $response['body']['deploymentRetention']); + $siteIds[] = $response['body']['$id']; + + $response = $this->getSite($response['body']['$id']); + $this->assertSame(200, $response['headers']['status-code']); + $this->assertSame(180, $response['body']['deploymentRetention']); + + // Failure values + $response = $this->createSite([ + 'siteId' => ID::unique(), + 'name' => 'Test retention site', + 'framework' => 'other', + 'buildRuntime' => 'node-22', + 'deploymentRetention' => 999999 + ]); + $this->assertSame(400, $response['headers']['status-code']); + + $response = $this->createSite([ + 'siteId' => ID::unique(), + 'name' => 'Test retention site', + 'framework' => 'other', + 'buildRuntime' => 'node-22', + 'deploymentRetention' => -1 + ]); + $this->assertSame(400, $response['headers']['status-code']); + + // Update flow + $response = $this->createSite([ + 'siteId' => ID::unique(), + 'name' => 'Test retention site', + 'framework' => 'other', + 'buildRuntime' => 'node-22', + 'deploymentRetention' => 180 + ]); + $this->assertSame(201, $response['headers']['status-code']); + $this->assertSame(180, $response['body']['deploymentRetention']); + $siteIds[] = $response['body']['$id']; + $siteIdToUpdate = $response['body']['$id']; + + $response = $this->updateSite([ + '$id' => $siteIdToUpdate, + 'name' => 'Test retention site', + 'framework' => 'other', + 'deploymentRetention' => 90 + ]); + + $this->assertSame(200, $response['headers']['status-code']); + $this->assertSame(90, $response['body']['deploymentRetention']); + + $response = $this->getSite($siteIdToUpdate); + $this->assertSame(200, $response['headers']['status-code']); + $this->assertSame(90, $response['body']['deploymentRetention']); + + $response = $this->updateSite([ + '$id' => $siteIdToUpdate, + 'name' => 'Test retention site', + 'framework' => 'other', + ]); + $this->assertSame(200, $response['headers']['status-code']); + $this->assertSame(0, $response['body']['deploymentRetention']); + + $response = $this->getSite($siteIdToUpdate); + $this->assertSame(200, $response['headers']['status-code']); + $this->assertSame(0, $response['body']['deploymentRetention']); + + // Failed update flow + $response = $this->updateSite([ + '$id' => $siteIdToUpdate, + 'name' => 'Test retention site', + 'framework' => 'other', + 'deploymentRetention' => -1 + ]); + $this->assertSame(400, $response['headers']['status-code']); + + $response = $this->updateSite([ + '$id' => $siteIdToUpdate, + 'name' => 'Test retention site', + 'framework' => 'other', + 'deploymentRetention' => 999999 + ]); + $this->assertSame(400, $response['headers']['status-code']); + + foreach ($siteIds as $siteId) { + $this->cleanupSite($siteId); + } + } } diff --git a/tests/resources/csv/vectordb-documents.csv b/tests/resources/csv/vectorsdb-documents.csv similarity index 100% rename from tests/resources/csv/vectordb-documents.csv rename to tests/resources/csv/vectorsdb-documents.csv diff --git a/tests/resources/sites/astro-custom-start-command/.gitignore b/tests/resources/sites/astro-custom-start-command/.gitignore new file mode 100644 index 0000000000..16d54bb13c --- /dev/null +++ b/tests/resources/sites/astro-custom-start-command/.gitignore @@ -0,0 +1,24 @@ +# build output +dist/ +# generated types +.astro/ + +# dependencies +node_modules/ + +# logs +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* + + +# environment variables +.env +.env.production + +# macOS-specific files +.DS_Store + +# jetbrains setting folder +.idea/ diff --git a/tests/resources/sites/astro-custom-start-command/astro.config.mjs b/tests/resources/sites/astro-custom-start-command/astro.config.mjs new file mode 100644 index 0000000000..b522ffdf90 --- /dev/null +++ b/tests/resources/sites/astro-custom-start-command/astro.config.mjs @@ -0,0 +1,10 @@ +// @ts-check +import { defineConfig } from 'astro/config'; +import node from '@astrojs/node'; + +// https://astro.build/config +export default defineConfig({ + adapter: node({ + mode: 'middleware', + }), +}); diff --git a/tests/resources/sites/astro-custom-start-command/custom-server.js b/tests/resources/sites/astro-custom-start-command/custom-server.js new file mode 100644 index 0000000000..1abb0c0f1c --- /dev/null +++ b/tests/resources/sites/astro-custom-start-command/custom-server.js @@ -0,0 +1,16 @@ +import express from 'express'; +import { handler as ssrHandler } from './server/entry.mjs'; + +const app = express(); +const base = '/'; +app.use(base, express.static('client/')); +app.get('/ssr-custom', (_req, res) => { + res.send('Custom SSR OK (' + Date.now() + ')'); +}); +app.use(ssrHandler); + +app.use((_req, res) => { + res.status(500).send('Custom error'); +}); + +app.listen(3000); \ No newline at end of file diff --git a/tests/resources/sites/astro-custom-start-command/package-lock.json b/tests/resources/sites/astro-custom-start-command/package-lock.json new file mode 100644 index 0000000000..f2cf215af1 --- /dev/null +++ b/tests/resources/sites/astro-custom-start-command/package-lock.json @@ -0,0 +1,5666 @@ +{ + "name": "astro-custom-start-command", + "version": "0.0.1", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "astro-custom-start-command", + "version": "0.0.1", + "dependencies": { + "@astrojs/node": "^9.5.4", + "astro": "^5.2.5" + }, + "devDependencies": {} + }, + "node_modules/@astrojs/compiler": { + "version": "2.13.0", + "resolved": "https://registry.npmjs.org/@astrojs/compiler/-/compiler-2.13.0.tgz", + "integrity": "sha512-mqVORhUJViA28fwHYaWmsXSzLO9osbdZ5ImUfxBarqsYdMlPbqAqGJCxsNzvppp1BEzc1mJNjOVvQqeDN8Vspw==", + "license": "MIT" + }, + "node_modules/@astrojs/internal-helpers": { + "version": "0.7.5", + "resolved": "https://registry.npmjs.org/@astrojs/internal-helpers/-/internal-helpers-0.7.5.tgz", + "integrity": "sha512-vreGnYSSKhAjFJCWAwe/CNhONvoc5lokxtRoZims+0wa3KbHBdPHSSthJsKxPd8d/aic6lWKpRTYGY/hsgK6EA==", + "license": "MIT" + }, + "node_modules/@astrojs/markdown-remark": { + "version": "6.3.10", + "resolved": "https://registry.npmjs.org/@astrojs/markdown-remark/-/markdown-remark-6.3.10.tgz", + "integrity": "sha512-kk4HeYR6AcnzC4QV8iSlOfh+N8TZ3MEStxPyenyCtemqn8IpEATBFMTJcfrNW32dgpt6MY3oCkMM/Tv3/I4G3A==", + "license": "MIT", + "dependencies": { + "@astrojs/internal-helpers": "0.7.5", + "@astrojs/prism": "3.3.0", + "github-slugger": "^2.0.0", + "hast-util-from-html": "^2.0.3", + "hast-util-to-text": "^4.0.2", + "import-meta-resolve": "^4.2.0", + "js-yaml": "^4.1.1", + "mdast-util-definitions": "^6.0.0", + "rehype-raw": "^7.0.0", + "rehype-stringify": "^10.0.1", + "remark-gfm": "^4.0.1", + "remark-parse": "^11.0.0", + "remark-rehype": "^11.1.2", + "remark-smartypants": "^3.0.2", + "shiki": "^3.19.0", + "smol-toml": "^1.5.2", + "unified": "^11.0.5", + "unist-util-remove-position": "^5.0.0", + "unist-util-visit": "^5.0.0", + "unist-util-visit-parents": "^6.0.2", + "vfile": "^6.0.3" + } + }, + "node_modules/@astrojs/node": { + "version": "9.5.4", + "resolved": "https://registry.npmjs.org/@astrojs/node/-/node-9.5.4.tgz", + "integrity": "sha512-AbPSZsMGu8hXPR2XxV79RaKy8h6wijhtoqZGeUf4OXg2w1mxXlx4VnIc1D+QvtsgauSz7P5PLhmvf6w/J41GJg==", + "license": "MIT", + "dependencies": { + "@astrojs/internal-helpers": "0.7.5", + "send": "^1.2.1", + "server-destroy": "^1.0.1" + }, + "peerDependencies": { + "astro": "^5.17.3" + } + }, + "node_modules/@astrojs/prism": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@astrojs/prism/-/prism-3.3.0.tgz", + "integrity": "sha512-q8VwfU/fDZNoDOf+r7jUnMC2//H2l0TuQ6FkGJL8vD8nw/q5KiL3DS1KKBI3QhI9UQhpJ5dc7AtqfbXWuOgLCQ==", + "license": "MIT", + "dependencies": { + "prismjs": "^1.30.0" + }, + "engines": { + "node": "18.20.8 || ^20.3.0 || >=22.0.0" + } + }, + "node_modules/@astrojs/telemetry": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@astrojs/telemetry/-/telemetry-3.3.0.tgz", + "integrity": "sha512-UFBgfeldP06qu6khs/yY+q1cDAaArM2/7AEIqQ9Cuvf7B1hNLq0xDrZkct+QoIGyjq56y8IaE2I3CTvG99mlhQ==", + "license": "MIT", + "dependencies": { + "ci-info": "^4.2.0", + "debug": "^4.4.0", + "dlv": "^1.1.3", + "dset": "^3.1.4", + "is-docker": "^3.0.0", + "is-wsl": "^3.1.0", + "which-pm-runs": "^1.1.0" + }, + "engines": { + "node": "18.20.8 || ^20.3.0 || >=22.0.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", + "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", + "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.5.tgz", + "integrity": "sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ==", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.28.5" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/types": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.5.tgz", + "integrity": "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==", + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.27.1", + "@babel/helper-validator-identifier": "^7.28.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@capsizecss/unpack": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@capsizecss/unpack/-/unpack-4.0.0.tgz", + "integrity": "sha512-VERIM64vtTP1C4mxQ5thVT9fK0apjPFobqybMtA1UdUujWka24ERHbRHFGmpbbhp73MhV+KSsHQH9C6uOTdEQA==", + "license": "MIT", + "dependencies": { + "fontkitten": "^1.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@emnapi/runtime": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.8.1.tgz", + "integrity": "sha512-mehfKSMWjjNol8659Z8KxEMrdSJDDot5SXMq00dM8BN4o+CLNXQ0xH2V7EchNHV4RmbZLmmPdEaXZc5H2FXmDg==", + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.12.tgz", + "integrity": "sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.12.tgz", + "integrity": "sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.12.tgz", + "integrity": "sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.12.tgz", + "integrity": "sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.12.tgz", + "integrity": "sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.12.tgz", + "integrity": "sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.12.tgz", + "integrity": "sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.12.tgz", + "integrity": "sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.12.tgz", + "integrity": "sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.12.tgz", + "integrity": "sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.12.tgz", + "integrity": "sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.12.tgz", + "integrity": "sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==", + "cpu": [ + "loong64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.12.tgz", + "integrity": "sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==", + "cpu": [ + "mips64el" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.12.tgz", + "integrity": "sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.12.tgz", + "integrity": "sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==", + "cpu": [ + "riscv64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.12.tgz", + "integrity": "sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==", + "cpu": [ + "s390x" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.12.tgz", + "integrity": "sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.12.tgz", + "integrity": "sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.12.tgz", + "integrity": "sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.12.tgz", + "integrity": "sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.12.tgz", + "integrity": "sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.12.tgz", + "integrity": "sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.12.tgz", + "integrity": "sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.12.tgz", + "integrity": "sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.12.tgz", + "integrity": "sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.12.tgz", + "integrity": "sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@img/colour": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@img/colour/-/colour-1.0.0.tgz", + "integrity": "sha512-A5P/LfWGFSl6nsckYtjw9da+19jB8hkJ6ACTGcDfEJ0aE+l2n2El7dsVM7UVHZQ9s2lmYMWlrS21YLy2IR1LUw==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/@img/sharp-darwin-arm64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.34.5.tgz", + "integrity": "sha512-imtQ3WMJXbMY4fxb/Ndp6HBTNVtWCUI0WdobyheGf5+ad6xX8VIDO8u2xE4qc/fr08CKG/7dDseFtn6M6g/r3w==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-arm64": "1.2.4" + } + }, + "node_modules/@img/sharp-darwin-x64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.34.5.tgz", + "integrity": "sha512-YNEFAF/4KQ/PeW0N+r+aVVsoIY0/qxxikF2SWdp+NRkmMB7y9LBZAVqQ4yhGCm/H3H270OSykqmQMKLBhBJDEw==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-x64": "1.2.4" + } + }, + "node_modules/@img/sharp-libvips-darwin-arm64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.2.4.tgz", + "integrity": "sha512-zqjjo7RatFfFoP0MkQ51jfuFZBnVE2pRiaydKJ1G/rHZvnsrHAOcQALIi9sA5co5xenQdTugCvtb1cuf78Vf4g==", + "cpu": [ + "arm64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "darwin" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-darwin-x64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.2.4.tgz", + "integrity": "sha512-1IOd5xfVhlGwX+zXv2N93k0yMONvUlANylbJw1eTah8K/Jtpi15KC+WSiaX/nBmbm2HxRM1gZ0nSdjSsrZbGKg==", + "cpu": [ + "x64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "darwin" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-arm": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.2.4.tgz", + "integrity": "sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A==", + "cpu": [ + "arm" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-arm64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.2.4.tgz", + "integrity": "sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw==", + "cpu": [ + "arm64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-ppc64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-ppc64/-/sharp-libvips-linux-ppc64-1.2.4.tgz", + "integrity": "sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA==", + "cpu": [ + "ppc64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-riscv64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-riscv64/-/sharp-libvips-linux-riscv64-1.2.4.tgz", + "integrity": "sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA==", + "cpu": [ + "riscv64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-s390x": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.2.4.tgz", + "integrity": "sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ==", + "cpu": [ + "s390x" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-x64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.2.4.tgz", + "integrity": "sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw==", + "cpu": [ + "x64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linuxmusl-arm64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.2.4.tgz", + "integrity": "sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw==", + "cpu": [ + "arm64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linuxmusl-x64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.2.4.tgz", + "integrity": "sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg==", + "cpu": [ + "x64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-linux-arm": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.34.5.tgz", + "integrity": "sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw==", + "cpu": [ + "arm" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm": "1.2.4" + } + }, + "node_modules/@img/sharp-linux-arm64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.34.5.tgz", + "integrity": "sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm64": "1.2.4" + } + }, + "node_modules/@img/sharp-linux-ppc64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-ppc64/-/sharp-linux-ppc64-0.34.5.tgz", + "integrity": "sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA==", + "cpu": [ + "ppc64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-ppc64": "1.2.4" + } + }, + "node_modules/@img/sharp-linux-riscv64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-riscv64/-/sharp-linux-riscv64-0.34.5.tgz", + "integrity": "sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw==", + "cpu": [ + "riscv64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-riscv64": "1.2.4" + } + }, + "node_modules/@img/sharp-linux-s390x": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.34.5.tgz", + "integrity": "sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg==", + "cpu": [ + "s390x" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-s390x": "1.2.4" + } + }, + "node_modules/@img/sharp-linux-x64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.34.5.tgz", + "integrity": "sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-x64": "1.2.4" + } + }, + "node_modules/@img/sharp-linuxmusl-arm64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.34.5.tgz", + "integrity": "sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-arm64": "1.2.4" + } + }, + "node_modules/@img/sharp-linuxmusl-x64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.34.5.tgz", + "integrity": "sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-x64": "1.2.4" + } + }, + "node_modules/@img/sharp-wasm32": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.34.5.tgz", + "integrity": "sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw==", + "cpu": [ + "wasm32" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later AND MIT", + "optional": true, + "dependencies": { + "@emnapi/runtime": "^1.7.0" + }, + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-arm64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-arm64/-/sharp-win32-arm64-0.34.5.tgz", + "integrity": "sha512-WQ3AgWCWYSb2yt+IG8mnC6Jdk9Whs7O0gxphblsLvdhSpSTtmu69ZG1Gkb6NuvxsNACwiPV6cNSZNzt0KPsw7g==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-ia32": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.34.5.tgz", + "integrity": "sha512-FV9m/7NmeCmSHDD5j4+4pNI8Cp3aW+JvLoXcTUo0IqyjSfAZJ8dIUmijx1qaJsIiU+Hosw6xM5KijAWRJCSgNg==", + "cpu": [ + "ia32" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-x64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.34.5.tgz", + "integrity": "sha512-+29YMsqY2/9eFEiW93eqWnuLcWcufowXewwSNIT6UwZdUUCrM3oFjMWH/Z6/TMmb4hlFenmfAVbpWeup2jryCw==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "license": "MIT" + }, + "node_modules/@oslojs/encoding": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@oslojs/encoding/-/encoding-1.1.0.tgz", + "integrity": "sha512-70wQhgYmndg4GCPxPPxPGevRKqTIJ2Nh4OkiMWmDAVYsTQ+Ta7Sq+rPevXyXGdzr30/qZBnyOalCszoMxlyldQ==", + "license": "MIT" + }, + "node_modules/@rollup/pluginutils": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.3.0.tgz", + "integrity": "sha512-5EdhGZtnu3V88ces7s53hhfK5KSASnJZv8Lulpc04cWO3REESroJXg73DFsOmgbU2BhwV0E20bu2IDZb3VKW4Q==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "estree-walker": "^2.0.2", + "picomatch": "^4.0.2" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@rollup/pluginutils/node_modules/estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", + "license": "MIT" + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.59.0.tgz", + "integrity": "sha512-upnNBkA6ZH2VKGcBj9Fyl9IGNPULcjXRlg0LLeaioQWueH30p6IXtJEbKAgvyv+mJaMxSm1l6xwDXYjpEMiLMg==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.59.0.tgz", + "integrity": "sha512-hZ+Zxj3SySm4A/DylsDKZAeVg0mvi++0PYVceVyX7hemkw7OreKdCvW2oQ3T1FMZvCaQXqOTHb8qmBShoqk69Q==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.59.0.tgz", + "integrity": "sha512-W2Psnbh1J8ZJw0xKAd8zdNgF9HRLkdWwwdWqubSVk0pUuQkoHnv7rx4GiF9rT4t5DIZGAsConRE3AxCdJ4m8rg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.59.0.tgz", + "integrity": "sha512-ZW2KkwlS4lwTv7ZVsYDiARfFCnSGhzYPdiOU4IM2fDbL+QGlyAbjgSFuqNRbSthybLbIJ915UtZBtmuLrQAT/w==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.59.0.tgz", + "integrity": "sha512-EsKaJ5ytAu9jI3lonzn3BgG8iRBjV4LxZexygcQbpiU0wU0ATxhNVEpXKfUa0pS05gTcSDMKpn3Sx+QB9RlTTA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.59.0.tgz", + "integrity": "sha512-d3DuZi2KzTMjImrxoHIAODUZYoUUMsuUiY4SRRcJy6NJoZ6iIqWnJu9IScV9jXysyGMVuW+KNzZvBLOcpdl3Vg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.59.0.tgz", + "integrity": "sha512-t4ONHboXi/3E0rT6OZl1pKbl2Vgxf9vJfWgmUoCEVQVxhW6Cw/c8I6hbbu7DAvgp82RKiH7TpLwxnJeKv2pbsw==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.59.0.tgz", + "integrity": "sha512-CikFT7aYPA2ufMD086cVORBYGHffBo4K8MQ4uPS/ZnY54GKj36i196u8U+aDVT2LX4eSMbyHtyOh7D7Zvk2VvA==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.59.0.tgz", + "integrity": "sha512-jYgUGk5aLd1nUb1CtQ8E+t5JhLc9x5WdBKew9ZgAXg7DBk0ZHErLHdXM24rfX+bKrFe+Xp5YuJo54I5HFjGDAA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.59.0.tgz", + "integrity": "sha512-peZRVEdnFWZ5Bh2KeumKG9ty7aCXzzEsHShOZEFiCQlDEepP1dpUl/SrUNXNg13UmZl+gzVDPsiCwnV1uI0RUA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-gnu": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.59.0.tgz", + "integrity": "sha512-gbUSW/97f7+r4gHy3Jlup8zDG190AuodsWnNiXErp9mT90iCy9NKKU0Xwx5k8VlRAIV2uU9CsMnEFg/xXaOfXg==", + "cpu": [ + "loong64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-musl": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.59.0.tgz", + "integrity": "sha512-yTRONe79E+o0FWFijasoTjtzG9EBedFXJMl888NBEDCDV9I2wGbFFfJQQe63OijbFCUZqxpHz1GzpbtSFikJ4Q==", + "cpu": [ + "loong64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-gnu": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.59.0.tgz", + "integrity": "sha512-sw1o3tfyk12k3OEpRddF68a1unZ5VCN7zoTNtSn2KndUE+ea3m3ROOKRCZxEpmT9nsGnogpFP9x6mnLTCaoLkA==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-musl": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.59.0.tgz", + "integrity": "sha512-+2kLtQ4xT3AiIxkzFVFXfsmlZiG5FXYW7ZyIIvGA7Bdeuh9Z0aN4hVyXS/G1E9bTP/vqszNIN/pUKCk/BTHsKA==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.59.0.tgz", + "integrity": "sha512-NDYMpsXYJJaj+I7UdwIuHHNxXZ/b/N2hR15NyH3m2qAtb/hHPA4g4SuuvrdxetTdndfj9b1WOmy73kcPRoERUg==", + "cpu": [ + "riscv64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-musl": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.59.0.tgz", + "integrity": "sha512-nLckB8WOqHIf1bhymk+oHxvM9D3tyPndZH8i8+35p/1YiVoVswPid2yLzgX7ZJP0KQvnkhM4H6QZ5m0LzbyIAg==", + "cpu": [ + "riscv64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.59.0.tgz", + "integrity": "sha512-oF87Ie3uAIvORFBpwnCvUzdeYUqi2wY6jRFWJAy1qus/udHFYIkplYRW+wo+GRUP4sKzYdmE1Y3+rY5Gc4ZO+w==", + "cpu": [ + "s390x" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.59.0.tgz", + "integrity": "sha512-3AHmtQq/ppNuUspKAlvA8HtLybkDflkMuLK4DPo77DfthRb71V84/c4MlWJXixZz4uruIH4uaa07IqoAkG64fg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.59.0.tgz", + "integrity": "sha512-2UdiwS/9cTAx7qIUZB/fWtToJwvt0Vbo0zmnYt7ED35KPg13Q0ym1g442THLC7VyI6JfYTP4PiSOWyoMdV2/xg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-openbsd-x64": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.59.0.tgz", + "integrity": "sha512-M3bLRAVk6GOwFlPTIxVBSYKUaqfLrn8l0psKinkCFxl4lQvOSz8ZrKDz2gxcBwHFpci0B6rttydI4IpS4IS/jQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ] + }, + "node_modules/@rollup/rollup-openharmony-arm64": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.59.0.tgz", + "integrity": "sha512-tt9KBJqaqp5i5HUZzoafHZX8b5Q2Fe7UjYERADll83O4fGqJ49O1FsL6LpdzVFQcpwvnyd0i+K/VSwu/o/nWlA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.59.0.tgz", + "integrity": "sha512-V5B6mG7OrGTwnxaNUzZTDTjDS7F75PO1ae6MJYdiMu60sq0CqN5CVeVsbhPxalupvTX8gXVSU9gq+Rx1/hvu6A==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.59.0.tgz", + "integrity": "sha512-UKFMHPuM9R0iBegwzKF4y0C4J9u8C6MEJgFuXTBerMk7EJ92GFVFYBfOZaSGLu6COf7FxpQNqhNS4c4icUPqxA==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-gnu": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.59.0.tgz", + "integrity": "sha512-laBkYlSS1n2L8fSo1thDNGrCTQMmxjYY5G0WFWjFFYZkKPjsMBsgJfGf4TLxXrF6RyhI60L8TMOjBMvXiTcxeA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.59.0.tgz", + "integrity": "sha512-2HRCml6OztYXyJXAvdDXPKcawukWY2GpR5/nxKp4iBgiO3wcoEGkAaqctIbZcNB6KlUQBIqt8VYkNSj2397EfA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@shikijs/core": { + "version": "3.23.0", + "resolved": "https://registry.npmjs.org/@shikijs/core/-/core-3.23.0.tgz", + "integrity": "sha512-NSWQz0riNb67xthdm5br6lAkvpDJRTgB36fxlo37ZzM2yq0PQFFzbd8psqC2XMPgCzo1fW6cVi18+ArJ44wqgA==", + "license": "MIT", + "dependencies": { + "@shikijs/types": "3.23.0", + "@shikijs/vscode-textmate": "^10.0.2", + "@types/hast": "^3.0.4", + "hast-util-to-html": "^9.0.5" + } + }, + "node_modules/@shikijs/engine-javascript": { + "version": "3.23.0", + "resolved": "https://registry.npmjs.org/@shikijs/engine-javascript/-/engine-javascript-3.23.0.tgz", + "integrity": "sha512-aHt9eiGFobmWR5uqJUViySI1bHMqrAgamWE1TYSUoftkAeCCAiGawPMwM+VCadylQtF4V3VNOZ5LmfItH5f3yA==", + "license": "MIT", + "dependencies": { + "@shikijs/types": "3.23.0", + "@shikijs/vscode-textmate": "^10.0.2", + "oniguruma-to-es": "^4.3.4" + } + }, + "node_modules/@shikijs/engine-oniguruma": { + "version": "3.23.0", + "resolved": "https://registry.npmjs.org/@shikijs/engine-oniguruma/-/engine-oniguruma-3.23.0.tgz", + "integrity": "sha512-1nWINwKXxKKLqPibT5f4pAFLej9oZzQTsby8942OTlsJzOBZ0MWKiwzMsd+jhzu8YPCHAswGnnN1YtQfirL35g==", + "license": "MIT", + "dependencies": { + "@shikijs/types": "3.23.0", + "@shikijs/vscode-textmate": "^10.0.2" + } + }, + "node_modules/@shikijs/langs": { + "version": "3.23.0", + "resolved": "https://registry.npmjs.org/@shikijs/langs/-/langs-3.23.0.tgz", + "integrity": "sha512-2Ep4W3Re5aB1/62RSYQInK9mM3HsLeB91cHqznAJMuylqjzNVAVCMnNWRHFtcNHXsoNRayP9z1qj4Sq3nMqYXg==", + "license": "MIT", + "dependencies": { + "@shikijs/types": "3.23.0" + } + }, + "node_modules/@shikijs/themes": { + "version": "3.23.0", + "resolved": "https://registry.npmjs.org/@shikijs/themes/-/themes-3.23.0.tgz", + "integrity": "sha512-5qySYa1ZgAT18HR/ypENL9cUSGOeI2x+4IvYJu4JgVJdizn6kG4ia5Q1jDEOi7gTbN4RbuYtmHh0W3eccOrjMA==", + "license": "MIT", + "dependencies": { + "@shikijs/types": "3.23.0" + } + }, + "node_modules/@shikijs/types": { + "version": "3.23.0", + "resolved": "https://registry.npmjs.org/@shikijs/types/-/types-3.23.0.tgz", + "integrity": "sha512-3JZ5HXOZfYjsYSk0yPwBrkupyYSLpAE26Qc0HLghhZNGTZg/SKxXIIgoxOpmmeQP0RRSDJTk1/vPfw9tbw+jSQ==", + "license": "MIT", + "dependencies": { + "@shikijs/vscode-textmate": "^10.0.2", + "@types/hast": "^3.0.4" + } + }, + "node_modules/@shikijs/vscode-textmate": { + "version": "10.0.2", + "resolved": "https://registry.npmjs.org/@shikijs/vscode-textmate/-/vscode-textmate-10.0.2.tgz", + "integrity": "sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==", + "license": "MIT" + }, + "node_modules/@types/debug": { + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz", + "integrity": "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==", + "license": "MIT", + "dependencies": { + "@types/ms": "*" + } + }, + "node_modules/@types/estree": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", + "license": "MIT" + }, + "node_modules/@types/hast": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz", + "integrity": "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==", + "license": "MIT", + "dependencies": { + "@types/unist": "*" + } + }, + "node_modules/@types/mdast": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz", + "integrity": "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==", + "license": "MIT", + "dependencies": { + "@types/unist": "*" + } + }, + "node_modules/@types/ms": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@types/ms/-/ms-2.1.0.tgz", + "integrity": "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==", + "license": "MIT" + }, + "node_modules/@types/nlcst": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@types/nlcst/-/nlcst-2.0.3.tgz", + "integrity": "sha512-vSYNSDe6Ix3q+6Z7ri9lyWqgGhJTmzRjZRqyq15N0Z/1/UnVsno9G/N40NBijoYx2seFDIl0+B2mgAb9mezUCA==", + "license": "MIT", + "dependencies": { + "@types/unist": "*" + } + }, + "node_modules/@types/node": { + "version": "25.0.3", + "resolved": "https://registry.npmjs.org/@types/node/-/node-25.0.3.tgz", + "integrity": "sha512-W609buLVRVmeW693xKfzHeIV6nJGGz98uCPfeXI1ELMLXVeKYZ9m15fAMSaUPBHYLGFsVRcMmSCksQOrZV9BYA==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "undici-types": "~7.16.0" + } + }, + "node_modules/@types/unist": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", + "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==", + "license": "MIT" + }, + "node_modules/@ungap/structured-clone": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.0.tgz", + "integrity": "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==", + "license": "ISC" + }, + "node_modules/acorn": { + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", + "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/ansi-align": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.1.tgz", + "integrity": "sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==", + "license": "ISC", + "dependencies": { + "string-width": "^4.1.0" + } + }, + "node_modules/ansi-align/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-align/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "license": "MIT" + }, + "node_modules/ansi-align/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-align/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-regex": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/ansi-styles": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "license": "ISC", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/anymatch/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "license": "Python-2.0" + }, + "node_modules/aria-query": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.2.tgz", + "integrity": "sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==", + "license": "Apache-2.0", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/array-iterate": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/array-iterate/-/array-iterate-2.0.1.tgz", + "integrity": "sha512-I1jXZMjAgCMmxT4qxXfPXa6SthSoE8h6gkSI9BGGNv8mP8G/v0blc+qFnZu6K42vTOiuME596QaLO0TP3Lk0xg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/astro": { + "version": "5.18.0", + "resolved": "https://registry.npmjs.org/astro/-/astro-5.18.0.tgz", + "integrity": "sha512-CHiohwJIS4L0G6/IzE1Fx3dgWqXBCXus/od0eGUfxrZJD2um2pE7ehclMmgL/fXqbU7NfE1Ze2pq34h2QaA6iQ==", + "license": "MIT", + "dependencies": { + "@astrojs/compiler": "^2.13.0", + "@astrojs/internal-helpers": "0.7.5", + "@astrojs/markdown-remark": "6.3.10", + "@astrojs/telemetry": "3.3.0", + "@capsizecss/unpack": "^4.0.0", + "@oslojs/encoding": "^1.1.0", + "@rollup/pluginutils": "^5.3.0", + "acorn": "^8.15.0", + "aria-query": "^5.3.2", + "axobject-query": "^4.1.0", + "boxen": "8.0.1", + "ci-info": "^4.3.1", + "clsx": "^2.1.1", + "common-ancestor-path": "^1.0.1", + "cookie": "^1.1.1", + "cssesc": "^3.0.0", + "debug": "^4.4.3", + "deterministic-object-hash": "^2.0.2", + "devalue": "^5.6.2", + "diff": "^8.0.3", + "dlv": "^1.1.3", + "dset": "^3.1.4", + "es-module-lexer": "^1.7.0", + "esbuild": "^0.27.3", + "estree-walker": "^3.0.3", + "flattie": "^1.1.1", + "fontace": "~0.4.0", + "github-slugger": "^2.0.0", + "html-escaper": "3.0.3", + "http-cache-semantics": "^4.2.0", + "import-meta-resolve": "^4.2.0", + "js-yaml": "^4.1.1", + "magic-string": "^0.30.21", + "magicast": "^0.5.1", + "mrmime": "^2.0.1", + "neotraverse": "^0.6.18", + "p-limit": "^6.2.0", + "p-queue": "^8.1.1", + "package-manager-detector": "^1.6.0", + "piccolore": "^0.1.3", + "picomatch": "^4.0.3", + "prompts": "^2.4.2", + "rehype": "^13.0.2", + "semver": "^7.7.3", + "shiki": "^3.21.0", + "smol-toml": "^1.6.0", + "svgo": "^4.0.0", + "tinyexec": "^1.0.2", + "tinyglobby": "^0.2.15", + "tsconfck": "^3.1.6", + "ultrahtml": "^1.6.0", + "unifont": "~0.7.3", + "unist-util-visit": "^5.0.0", + "unstorage": "^1.17.4", + "vfile": "^6.0.3", + "vite": "^6.4.1", + "vitefu": "^1.1.1", + "xxhash-wasm": "^1.1.0", + "yargs-parser": "^21.1.1", + "yocto-spinner": "^0.2.3", + "zod": "^3.25.76", + "zod-to-json-schema": "^3.25.1", + "zod-to-ts": "^1.2.0" + }, + "bin": { + "astro": "astro.js" + }, + "engines": { + "node": "18.20.8 || ^20.3.0 || >=22.0.0", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/astrodotbuild" + }, + "optionalDependencies": { + "sharp": "^0.34.0" + } + }, + "node_modules/astro/node_modules/@esbuild/aix-ppc64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.3.tgz", + "integrity": "sha512-9fJMTNFTWZMh5qwrBItuziu834eOCUcEqymSH7pY+zoMVEZg3gcPuBNxH1EvfVYe9h0x/Ptw8KBzv7qxb7l8dg==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/astro/node_modules/@esbuild/android-arm": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.3.tgz", + "integrity": "sha512-i5D1hPY7GIQmXlXhs2w8AWHhenb00+GxjxRncS2ZM7YNVGNfaMxgzSGuO8o8SJzRc/oZwU2bcScvVERk03QhzA==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/astro/node_modules/@esbuild/android-arm64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.3.tgz", + "integrity": "sha512-YdghPYUmj/FX2SYKJ0OZxf+iaKgMsKHVPF1MAq/P8WirnSpCStzKJFjOjzsW0QQ7oIAiccHdcqjbHmJxRb/dmg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/astro/node_modules/@esbuild/android-x64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.3.tgz", + "integrity": "sha512-IN/0BNTkHtk8lkOM8JWAYFg4ORxBkZQf9zXiEOfERX/CzxW3Vg1ewAhU7QSWQpVIzTW+b8Xy+lGzdYXV6UZObQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/astro/node_modules/@esbuild/darwin-arm64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.3.tgz", + "integrity": "sha512-Re491k7ByTVRy0t3EKWajdLIr0gz2kKKfzafkth4Q8A5n1xTHrkqZgLLjFEHVD+AXdUGgQMq+Godfq45mGpCKg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/astro/node_modules/@esbuild/darwin-x64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.3.tgz", + "integrity": "sha512-vHk/hA7/1AckjGzRqi6wbo+jaShzRowYip6rt6q7VYEDX4LEy1pZfDpdxCBnGtl+A5zq8iXDcyuxwtv3hNtHFg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/astro/node_modules/@esbuild/freebsd-arm64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.3.tgz", + "integrity": "sha512-ipTYM2fjt3kQAYOvo6vcxJx3nBYAzPjgTCk7QEgZG8AUO3ydUhvelmhrbOheMnGOlaSFUoHXB6un+A7q4ygY9w==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/astro/node_modules/@esbuild/freebsd-x64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.3.tgz", + "integrity": "sha512-dDk0X87T7mI6U3K9VjWtHOXqwAMJBNN2r7bejDsc+j03SEjtD9HrOl8gVFByeM0aJksoUuUVU9TBaZa2rgj0oA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/astro/node_modules/@esbuild/linux-arm": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.3.tgz", + "integrity": "sha512-s6nPv2QkSupJwLYyfS+gwdirm0ukyTFNl3KTgZEAiJDd+iHZcbTPPcWCcRYH+WlNbwChgH2QkE9NSlNrMT8Gfw==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/astro/node_modules/@esbuild/linux-arm64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.3.tgz", + "integrity": "sha512-sZOuFz/xWnZ4KH3YfFrKCf1WyPZHakVzTiqji3WDc0BCl2kBwiJLCXpzLzUBLgmp4veFZdvN5ChW4Eq/8Fc2Fg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/astro/node_modules/@esbuild/linux-ia32": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.3.tgz", + "integrity": "sha512-yGlQYjdxtLdh0a3jHjuwOrxQjOZYD/C9PfdbgJJF3TIZWnm/tMd/RcNiLngiu4iwcBAOezdnSLAwQDPqTmtTYg==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/astro/node_modules/@esbuild/linux-loong64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.3.tgz", + "integrity": "sha512-WO60Sn8ly3gtzhyjATDgieJNet/KqsDlX5nRC5Y3oTFcS1l0KWba+SEa9Ja1GfDqSF1z6hif/SkpQJbL63cgOA==", + "cpu": [ + "loong64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/astro/node_modules/@esbuild/linux-mips64el": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.3.tgz", + "integrity": "sha512-APsymYA6sGcZ4pD6k+UxbDjOFSvPWyZhjaiPyl/f79xKxwTnrn5QUnXR5prvetuaSMsb4jgeHewIDCIWljrSxw==", + "cpu": [ + "mips64el" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/astro/node_modules/@esbuild/linux-ppc64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.3.tgz", + "integrity": "sha512-eizBnTeBefojtDb9nSh4vvVQ3V9Qf9Df01PfawPcRzJH4gFSgrObw+LveUyDoKU3kxi5+9RJTCWlj4FjYXVPEA==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/astro/node_modules/@esbuild/linux-riscv64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.3.tgz", + "integrity": "sha512-3Emwh0r5wmfm3ssTWRQSyVhbOHvqegUDRd0WhmXKX2mkHJe1SFCMJhagUleMq+Uci34wLSipf8Lagt4LlpRFWQ==", + "cpu": [ + "riscv64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/astro/node_modules/@esbuild/linux-s390x": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.3.tgz", + "integrity": "sha512-pBHUx9LzXWBc7MFIEEL0yD/ZVtNgLytvx60gES28GcWMqil8ElCYR4kvbV2BDqsHOvVDRrOxGySBM9Fcv744hw==", + "cpu": [ + "s390x" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/astro/node_modules/@esbuild/linux-x64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.3.tgz", + "integrity": "sha512-Czi8yzXUWIQYAtL/2y6vogER8pvcsOsk5cpwL4Gk5nJqH5UZiVByIY8Eorm5R13gq+DQKYg0+JyQoytLQas4dA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/astro/node_modules/@esbuild/netbsd-arm64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.3.tgz", + "integrity": "sha512-sDpk0RgmTCR/5HguIZa9n9u+HVKf40fbEUt+iTzSnCaGvY9kFP0YKBWZtJaraonFnqef5SlJ8/TiPAxzyS+UoA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/astro/node_modules/@esbuild/netbsd-x64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.3.tgz", + "integrity": "sha512-P14lFKJl/DdaE00LItAukUdZO5iqNH7+PjoBm+fLQjtxfcfFE20Xf5CrLsmZdq5LFFZzb5JMZ9grUwvtVYzjiA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/astro/node_modules/@esbuild/openbsd-arm64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.3.tgz", + "integrity": "sha512-AIcMP77AvirGbRl/UZFTq5hjXK+2wC7qFRGoHSDrZ5v5b8DK/GYpXW3CPRL53NkvDqb9D+alBiC/dV0Fb7eJcw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/astro/node_modules/@esbuild/openbsd-x64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.3.tgz", + "integrity": "sha512-DnW2sRrBzA+YnE70LKqnM3P+z8vehfJWHXECbwBmH/CU51z6FiqTQTHFenPlHmo3a8UgpLyH3PT+87OViOh1AQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/astro/node_modules/@esbuild/openharmony-arm64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.3.tgz", + "integrity": "sha512-NinAEgr/etERPTsZJ7aEZQvvg/A6IsZG/LgZy+81wON2huV7SrK3e63dU0XhyZP4RKGyTm7aOgmQk0bGp0fy2g==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/astro/node_modules/@esbuild/sunos-x64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.3.tgz", + "integrity": "sha512-PanZ+nEz+eWoBJ8/f8HKxTTD172SKwdXebZ0ndd953gt1HRBbhMsaNqjTyYLGLPdoWHy4zLU7bDVJztF5f3BHA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/astro/node_modules/@esbuild/win32-arm64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.3.tgz", + "integrity": "sha512-B2t59lWWYrbRDw/tjiWOuzSsFh1Y/E95ofKz7rIVYSQkUYBjfSgf6oeYPNWHToFRr2zx52JKApIcAS/D5TUBnA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/astro/node_modules/@esbuild/win32-ia32": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.3.tgz", + "integrity": "sha512-QLKSFeXNS8+tHW7tZpMtjlNb7HKau0QDpwm49u0vUp9y1WOF+PEzkU84y9GqYaAVW8aH8f3GcBck26jh54cX4Q==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/astro/node_modules/@esbuild/win32-x64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.3.tgz", + "integrity": "sha512-4uJGhsxuptu3OcpVAzli+/gWusVGwZZHTlS63hh++ehExkVT8SgiEf7/uC/PclrPPkLhZqGgCTjd0VWLo6xMqA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/astro/node_modules/esbuild": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.3.tgz", + "integrity": "sha512-8VwMnyGCONIs6cWue2IdpHxHnAjzxnw2Zr7MkVxB2vjmQ2ivqGFb4LEG3SMnv0Gb2F/G/2yA8zUaiL1gywDCCg==", + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.27.3", + "@esbuild/android-arm": "0.27.3", + "@esbuild/android-arm64": "0.27.3", + "@esbuild/android-x64": "0.27.3", + "@esbuild/darwin-arm64": "0.27.3", + "@esbuild/darwin-x64": "0.27.3", + "@esbuild/freebsd-arm64": "0.27.3", + "@esbuild/freebsd-x64": "0.27.3", + "@esbuild/linux-arm": "0.27.3", + "@esbuild/linux-arm64": "0.27.3", + "@esbuild/linux-ia32": "0.27.3", + "@esbuild/linux-loong64": "0.27.3", + "@esbuild/linux-mips64el": "0.27.3", + "@esbuild/linux-ppc64": "0.27.3", + "@esbuild/linux-riscv64": "0.27.3", + "@esbuild/linux-s390x": "0.27.3", + "@esbuild/linux-x64": "0.27.3", + "@esbuild/netbsd-arm64": "0.27.3", + "@esbuild/netbsd-x64": "0.27.3", + "@esbuild/openbsd-arm64": "0.27.3", + "@esbuild/openbsd-x64": "0.27.3", + "@esbuild/openharmony-arm64": "0.27.3", + "@esbuild/sunos-x64": "0.27.3", + "@esbuild/win32-arm64": "0.27.3", + "@esbuild/win32-ia32": "0.27.3", + "@esbuild/win32-x64": "0.27.3" + } + }, + "node_modules/axobject-query": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.1.0.tgz", + "integrity": "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==", + "license": "Apache-2.0", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/bail": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.2.tgz", + "integrity": "sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/base-64": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/base-64/-/base-64-1.0.0.tgz", + "integrity": "sha512-kwDPIFCGx0NZHog36dj+tHiwP4QMzsZ3AgMViUBKI0+V5n4U0ufTCUMhnQ04diaRI8EX/QcPfql7zlhZ7j4zgg==", + "license": "MIT" + }, + "node_modules/boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", + "license": "ISC" + }, + "node_modules/boxen": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/boxen/-/boxen-8.0.1.tgz", + "integrity": "sha512-F3PH5k5juxom4xktynS7MoFY+NUWH5LC4CnH11YB8NPew+HLpmBLCybSAEyb2F+4pRXhuhWqFesoQd6DAyc2hw==", + "license": "MIT", + "dependencies": { + "ansi-align": "^3.0.1", + "camelcase": "^8.0.0", + "chalk": "^5.3.0", + "cli-boxes": "^3.0.0", + "string-width": "^7.2.0", + "type-fest": "^4.21.0", + "widest-line": "^5.0.0", + "wrap-ansi": "^9.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/camelcase": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-8.0.0.tgz", + "integrity": "sha512-8WB3Jcas3swSvjIeA2yvCJ+Miyz5l1ZmB6HFb9R1317dt9LCQoswg/BGrmAmkWVEszSrrg4RwmO46qIm2OEnSA==", + "license": "MIT", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ccount": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/ccount/-/ccount-2.0.1.tgz", + "integrity": "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/chalk": { + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz", + "integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==", + "license": "MIT", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/character-entities": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-2.0.2.tgz", + "integrity": "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-entities-html4": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/character-entities-html4/-/character-entities-html4-2.1.0.tgz", + "integrity": "sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-entities-legacy": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-3.0.0.tgz", + "integrity": "sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "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/ci-info": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.3.1.tgz", + "integrity": "sha512-Wdy2Igu8OcBpI2pZePZ5oWjPC38tmDVx5WKUXKwlLYkA0ozo85sLsLvkBbBn/sZaSCMFOGZJ14fvW9t5/d7kdA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/cli-boxes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-3.0.0.tgz", + "integrity": "sha512-/lzGpEWL/8PfI0BmBOPRwp0c/wFNX1RdUML3jK/RcSBA9T8mZDdQpqYBKtCFTOfQbwPqWEOpjqW+Fnayc0969g==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/clsx": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", + "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/comma-separated-tokens": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz", + "integrity": "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/commander": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-11.1.0.tgz", + "integrity": "sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==", + "license": "MIT", + "engines": { + "node": ">=16" + } + }, + "node_modules/common-ancestor-path": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/common-ancestor-path/-/common-ancestor-path-1.0.1.tgz", + "integrity": "sha512-L3sHRo1pXXEqX8VU28kfgUY+YGsk09hPqZiZmLacNib6XNTCM8ubYeT7ryXQw8asB1sKgcU5lkB7ONug08aB8w==", + "license": "ISC" + }, + "node_modules/cookie": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-1.1.1.tgz", + "integrity": "sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/cookie-es": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/cookie-es/-/cookie-es-1.2.2.tgz", + "integrity": "sha512-+W7VmiVINB+ywl1HGXJXmrqkOhpKrIiVZV6tQuV54ZyQC7MMuBt81Vc336GMLoHBq5hV/F9eXgt5Mnx0Rha5Fg==", + "license": "MIT" + }, + "node_modules/crossws": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/crossws/-/crossws-0.3.5.tgz", + "integrity": "sha512-ojKiDvcmByhwa8YYqbQI/hg7MEU0NC03+pSdEq4ZUnZR9xXpwk7E43SMNGkn+JxJGPFtNvQ48+vV2p+P1ml5PA==", + "license": "MIT", + "dependencies": { + "uncrypto": "^0.1.3" + } + }, + "node_modules/css-select": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.2.2.tgz", + "integrity": "sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw==", + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0", + "css-what": "^6.1.0", + "domhandler": "^5.0.2", + "domutils": "^3.0.1", + "nth-check": "^2.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/css-tree": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-3.1.0.tgz", + "integrity": "sha512-0eW44TGN5SQXU1mWSkKwFstI/22X2bG1nYzZTYMAWjylYURhse752YgbE4Cx46AC+bAvI+/dYTPRk1LqSUnu6w==", + "license": "MIT", + "dependencies": { + "mdn-data": "2.12.2", + "source-map-js": "^1.0.1" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0" + } + }, + "node_modules/css-what": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.2.2.tgz", + "integrity": "sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==", + "license": "BSD-2-Clause", + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "license": "MIT", + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/csso": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/csso/-/csso-5.0.5.tgz", + "integrity": "sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==", + "license": "MIT", + "dependencies": { + "css-tree": "~2.2.0" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0", + "npm": ">=7.0.0" + } + }, + "node_modules/csso/node_modules/css-tree": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.2.1.tgz", + "integrity": "sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA==", + "license": "MIT", + "dependencies": { + "mdn-data": "2.0.28", + "source-map-js": "^1.0.1" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0", + "npm": ">=7.0.0" + } + }, + "node_modules/csso/node_modules/mdn-data": { + "version": "2.0.28", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.28.tgz", + "integrity": "sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==", + "license": "CC0-1.0" + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decode-named-character-reference": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.2.0.tgz", + "integrity": "sha512-c6fcElNV6ShtZXmsgNgFFV5tVX2PaV4g+MOAkb8eXHvn6sryJBrZa9r0zV6+dtTyoCKxtDy5tyQ5ZwQuidtd+Q==", + "license": "MIT", + "dependencies": { + "character-entities": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/defu": { + "version": "6.1.4", + "resolved": "https://registry.npmjs.org/defu/-/defu-6.1.4.tgz", + "integrity": "sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==", + "license": "MIT" + }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/dequal": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/destr": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/destr/-/destr-2.0.5.tgz", + "integrity": "sha512-ugFTXCtDZunbzasqBxrK93Ik/DRYsO6S/fedkWEMKqt04xZ4csmnmwGDBAb07QWNaGMAmnTIemsYZCksjATwsA==", + "license": "MIT" + }, + "node_modules/detect-libc": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", + "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", + "license": "Apache-2.0", + "optional": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/deterministic-object-hash": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/deterministic-object-hash/-/deterministic-object-hash-2.0.2.tgz", + "integrity": "sha512-KxektNH63SrbfUyDiwXqRb1rLwKt33AmMv+5Nhsw1kqZ13SJBRTgZHtGbE+hH3a1mVW1cz+4pqSWVPAtLVXTzQ==", + "license": "MIT", + "dependencies": { + "base-64": "^1.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/devalue": { + "version": "5.6.3", + "resolved": "https://registry.npmjs.org/devalue/-/devalue-5.6.3.tgz", + "integrity": "sha512-nc7XjUU/2Lb+SvEFVGcWLiKkzfw8+qHI7zn8WYXKkLMgfGSHbgCEaR6bJpev8Cm6Rmrb19Gfd/tZvGqx9is3wg==", + "license": "MIT" + }, + "node_modules/devlop": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/devlop/-/devlop-1.1.0.tgz", + "integrity": "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==", + "license": "MIT", + "dependencies": { + "dequal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/diff": { + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/diff/-/diff-8.0.3.tgz", + "integrity": "sha512-qejHi7bcSD4hQAZE0tNAawRK1ZtafHDmMTMkrrIGgSLl7hTnQHmKCeB45xAcbfTqK2zowkM3j3bHt/4b/ARbYQ==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/dlv": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", + "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==", + "license": "MIT" + }, + "node_modules/dom-serializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", + "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", + "license": "MIT", + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.2", + "entities": "^4.2.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/dom-serializer/node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/domelementtype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "BSD-2-Clause" + }, + "node_modules/domhandler": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", + "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", + "license": "BSD-2-Clause", + "dependencies": { + "domelementtype": "^2.3.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/domutils": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.2.2.tgz", + "integrity": "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==", + "license": "BSD-2-Clause", + "dependencies": { + "dom-serializer": "^2.0.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, + "node_modules/dset": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/dset/-/dset-3.1.4.tgz", + "integrity": "sha512-2QF/g9/zTaPDc3BjNcVTGoBbXBgYfMTTceLaYcFJ/W9kggFUkhxD/hMEeuLKbugyef9SqAx8cpgwlIP/jinUTA==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", + "license": "MIT" + }, + "node_modules/emoji-regex": { + "version": "10.6.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz", + "integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==", + "license": "MIT" + }, + "node_modules/encodeurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/entities": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz", + "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/es-module-lexer": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.7.0.tgz", + "integrity": "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==", + "license": "MIT" + }, + "node_modules/esbuild": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.12.tgz", + "integrity": "sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==", + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.25.12", + "@esbuild/android-arm": "0.25.12", + "@esbuild/android-arm64": "0.25.12", + "@esbuild/android-x64": "0.25.12", + "@esbuild/darwin-arm64": "0.25.12", + "@esbuild/darwin-x64": "0.25.12", + "@esbuild/freebsd-arm64": "0.25.12", + "@esbuild/freebsd-x64": "0.25.12", + "@esbuild/linux-arm": "0.25.12", + "@esbuild/linux-arm64": "0.25.12", + "@esbuild/linux-ia32": "0.25.12", + "@esbuild/linux-loong64": "0.25.12", + "@esbuild/linux-mips64el": "0.25.12", + "@esbuild/linux-ppc64": "0.25.12", + "@esbuild/linux-riscv64": "0.25.12", + "@esbuild/linux-s390x": "0.25.12", + "@esbuild/linux-x64": "0.25.12", + "@esbuild/netbsd-arm64": "0.25.12", + "@esbuild/netbsd-x64": "0.25.12", + "@esbuild/openbsd-arm64": "0.25.12", + "@esbuild/openbsd-x64": "0.25.12", + "@esbuild/openharmony-arm64": "0.25.12", + "@esbuild/sunos-x64": "0.25.12", + "@esbuild/win32-arm64": "0.25.12", + "@esbuild/win32-ia32": "0.25.12", + "@esbuild/win32-x64": "0.25.12" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", + "license": "MIT" + }, + "node_modules/escape-string-regexp": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", + "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0" + } + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/eventemitter3": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", + "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==", + "license": "MIT" + }, + "node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "license": "MIT" + }, + "node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/flattie": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/flattie/-/flattie-1.1.1.tgz", + "integrity": "sha512-9UbaD6XdAL97+k/n+N7JwX46K/M6Zc6KcFYskrYL8wbBV/Uyk0CTAMY0VT+qiK5PM7AIc9aTWYtq65U7T+aCNQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/fontace": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/fontace/-/fontace-0.4.1.tgz", + "integrity": "sha512-lDMvbAzSnHmbYMTEld5qdtvNH2/pWpICOqpean9IgC7vUbUJc3k+k5Dokp85CegamqQpFbXf0rAVkbzpyTA8aw==", + "license": "MIT", + "dependencies": { + "fontkitten": "^1.0.2" + } + }, + "node_modules/fontkitten": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/fontkitten/-/fontkitten-1.0.3.tgz", + "integrity": "sha512-Wp1zXWPVUPBmfoa3Cqc9ctaKuzKAV6uLstRqlR56kSjplf5uAce+qeyYym7F+PHbGTk+tCEdkCW6RD7DX/gBZw==", + "license": "MIT", + "dependencies": { + "tiny-inflate": "^1.0.3" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/fresh": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-2.0.0.tgz", + "integrity": "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/get-east-asian-width": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.4.0.tgz", + "integrity": "sha512-QZjmEOC+IT1uk6Rx0sX22V6uHWVwbdbxf1faPqJ1QhLdGgsRGCZoyaQBm/piRdJy/D2um6hM1UP7ZEeQ4EkP+Q==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/github-slugger": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/github-slugger/-/github-slugger-2.0.0.tgz", + "integrity": "sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw==", + "license": "ISC" + }, + "node_modules/h3": { + "version": "1.15.6", + "resolved": "https://registry.npmjs.org/h3/-/h3-1.15.6.tgz", + "integrity": "sha512-oi15ESLW5LRthZ+qPCi5GNasY/gvynSKUQxgiovrY63bPAtG59wtM+LSrlcwvOHAXzGrXVLnI97brbkdPF9WoQ==", + "license": "MIT", + "dependencies": { + "cookie-es": "^1.2.2", + "crossws": "^0.3.5", + "defu": "^6.1.4", + "destr": "^2.0.5", + "iron-webcrypto": "^1.2.1", + "node-mock-http": "^1.0.4", + "radix3": "^1.1.2", + "ufo": "^1.6.3", + "uncrypto": "^0.1.3" + } + }, + "node_modules/hast-util-from-html": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/hast-util-from-html/-/hast-util-from-html-2.0.3.tgz", + "integrity": "sha512-CUSRHXyKjzHov8yKsQjGOElXy/3EKpyX56ELnkHH34vDVw1N1XSQ1ZcAvTyAPtGqLTuKP/uxM+aLkSPqF/EtMw==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "devlop": "^1.1.0", + "hast-util-from-parse5": "^8.0.0", + "parse5": "^7.0.0", + "vfile": "^6.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-from-parse5": { + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/hast-util-from-parse5/-/hast-util-from-parse5-8.0.3.tgz", + "integrity": "sha512-3kxEVkEKt0zvcZ3hCRYI8rqrgwtlIOFMWkbclACvjlDw8Li9S2hk/d51OI0nr/gIpdMHNepwgOKqZ/sy0Clpyg==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "devlop": "^1.0.0", + "hastscript": "^9.0.0", + "property-information": "^7.0.0", + "vfile": "^6.0.0", + "vfile-location": "^5.0.0", + "web-namespaces": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-is-element": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/hast-util-is-element/-/hast-util-is-element-3.0.0.tgz", + "integrity": "sha512-Val9mnv2IWpLbNPqc/pUem+a7Ipj2aHacCwgNfTiK0vJKl0LF+4Ba4+v1oPHFpf3bLYmreq0/l3Gud9S5OH42g==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-parse-selector": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-4.0.0.tgz", + "integrity": "sha512-wkQCkSYoOGCRKERFWcxMVMOcYE2K1AaNLU8DXS9arxnLOUEWbOXKXiJUNzEpqZ3JOKpnha3jkFrumEjVliDe7A==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-raw": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/hast-util-raw/-/hast-util-raw-9.1.0.tgz", + "integrity": "sha512-Y8/SBAHkZGoNkpzqqfCldijcuUKh7/su31kEBp67cFY09Wy0mTRgtsLYsiIxMJxlu0f6AA5SUTbDR8K0rxnbUw==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "@ungap/structured-clone": "^1.0.0", + "hast-util-from-parse5": "^8.0.0", + "hast-util-to-parse5": "^8.0.0", + "html-void-elements": "^3.0.0", + "mdast-util-to-hast": "^13.0.0", + "parse5": "^7.0.0", + "unist-util-position": "^5.0.0", + "unist-util-visit": "^5.0.0", + "vfile": "^6.0.0", + "web-namespaces": "^2.0.0", + "zwitch": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-to-html": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/hast-util-to-html/-/hast-util-to-html-9.0.5.tgz", + "integrity": "sha512-OguPdidb+fbHQSU4Q4ZiLKnzWo8Wwsf5bZfbvu7//a9oTYoqD/fWpe96NuHkoS9h0ccGOTe0C4NGXdtS0iObOw==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "ccount": "^2.0.0", + "comma-separated-tokens": "^2.0.0", + "hast-util-whitespace": "^3.0.0", + "html-void-elements": "^3.0.0", + "mdast-util-to-hast": "^13.0.0", + "property-information": "^7.0.0", + "space-separated-tokens": "^2.0.0", + "stringify-entities": "^4.0.0", + "zwitch": "^2.0.4" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-to-parse5": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/hast-util-to-parse5/-/hast-util-to-parse5-8.0.1.tgz", + "integrity": "sha512-MlWT6Pjt4CG9lFCjiz4BH7l9wmrMkfkJYCxFwKQic8+RTZgWPuWxwAfjJElsXkex7DJjfSJsQIt931ilUgmwdA==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "comma-separated-tokens": "^2.0.0", + "devlop": "^1.0.0", + "property-information": "^7.0.0", + "space-separated-tokens": "^2.0.0", + "web-namespaces": "^2.0.0", + "zwitch": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-to-text": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/hast-util-to-text/-/hast-util-to-text-4.0.2.tgz", + "integrity": "sha512-KK6y/BN8lbaq654j7JgBydev7wuNMcID54lkRav1P0CaE1e47P72AWWPiGKXTJU271ooYzcvTAn/Zt0REnvc7A==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "hast-util-is-element": "^3.0.0", + "unist-util-find-after": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-whitespace": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-3.0.0.tgz", + "integrity": "sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hastscript": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-9.0.1.tgz", + "integrity": "sha512-g7df9rMFX/SPi34tyGCyUBREQoKkapwdY/T04Qn9TDWfHhAYt4/I0gMVirzK5wEzeUqIjEB+LXC/ypb7Aqno5w==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "comma-separated-tokens": "^2.0.0", + "hast-util-parse-selector": "^4.0.0", + "property-information": "^7.0.0", + "space-separated-tokens": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/html-escaper": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-3.0.3.tgz", + "integrity": "sha512-RuMffC89BOWQoY0WKGpIhn5gX3iI54O6nRA0yC124NYVtzjmFWBIiFd8M0x+ZdX0P9R4lADg1mgP8C7PxGOWuQ==", + "license": "MIT" + }, + "node_modules/html-void-elements": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/html-void-elements/-/html-void-elements-3.0.0.tgz", + "integrity": "sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/http-cache-semantics": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.2.0.tgz", + "integrity": "sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ==", + "license": "BSD-2-Clause" + }, + "node_modules/http-errors": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz", + "integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==", + "license": "MIT", + "dependencies": { + "depd": "~2.0.0", + "inherits": "~2.0.4", + "setprototypeof": "~1.2.0", + "statuses": "~2.0.2", + "toidentifier": "~1.0.1" + }, + "engines": { + "node": ">= 0.8" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/import-meta-resolve": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/import-meta-resolve/-/import-meta-resolve-4.2.0.tgz", + "integrity": "sha512-Iqv2fzaTQN28s/FwZAoFq0ZSs/7hMAHJVX+w8PZl3cY19Pxk6jFFalxQoIfW2826i/fDLXv8IiEZRIT0lDuWcg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "license": "ISC" + }, + "node_modules/iron-webcrypto": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/iron-webcrypto/-/iron-webcrypto-1.2.1.tgz", + "integrity": "sha512-feOM6FaSr6rEABp/eDfVseKyTMDt+KGpeB35SkVn9Tyn0CqvVsY3EwI0v5i8nMHyJnzCIQf7nsy3p41TPkJZhg==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/brc-dd" + } + }, + "node_modules/is-docker": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz", + "integrity": "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==", + "license": "MIT", + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-inside-container": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-inside-container/-/is-inside-container-1.0.0.tgz", + "integrity": "sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==", + "license": "MIT", + "dependencies": { + "is-docker": "^3.0.0" + }, + "bin": { + "is-inside-container": "cli.js" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-plain-obj": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", + "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-wsl": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-3.1.0.tgz", + "integrity": "sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw==", + "license": "MIT", + "dependencies": { + "is-inside-container": "^1.0.0" + }, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/js-yaml": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", + "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/longest-streak": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-3.1.0.tgz", + "integrity": "sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/lru-cache": { + "version": "11.2.6", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.6.tgz", + "integrity": "sha512-ESL2CrkS/2wTPfuend7Zhkzo2u0daGJ/A2VucJOgQ/C48S/zB8MMeMHSGKYpXhIjbPxfuezITkaBH1wqv00DDQ==", + "license": "BlueOak-1.0.0", + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/magic-string": { + "version": "0.30.21", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", + "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==", + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.5" + } + }, + "node_modules/magicast": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/magicast/-/magicast-0.5.1.tgz", + "integrity": "sha512-xrHS24IxaLrvuo613F719wvOIv9xPHFWQHuvGUBmPnCA/3MQxKI3b+r7n1jAoDHmsbC5bRhTZYR77invLAxVnw==", + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.28.5", + "@babel/types": "^7.28.5", + "source-map-js": "^1.2.1" + } + }, + "node_modules/markdown-table": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-3.0.4.tgz", + "integrity": "sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/mdast-util-definitions": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-definitions/-/mdast-util-definitions-6.0.0.tgz", + "integrity": "sha512-scTllyX6pnYNZH/AIp/0ePz6s4cZtARxImwoPJ7kS42n+MnVsI4XbnG6d4ibehRIldYMWM2LD7ImQblVhUejVQ==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "unist-util-visit": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-find-and-replace": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/mdast-util-find-and-replace/-/mdast-util-find-and-replace-3.0.2.tgz", + "integrity": "sha512-Tmd1Vg/m3Xz43afeNxDIhWRtFZgM2VLyaf4vSTYwudTyeuTneoL3qtWMA5jeLyz/O1vDJmmV4QuScFCA2tBPwg==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "escape-string-regexp": "^5.0.0", + "unist-util-is": "^6.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-from-markdown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-2.0.2.tgz", + "integrity": "sha512-uZhTV/8NBuw0WHkPTrCqDOl0zVe1BIng5ZtHoDk49ME1qqcjYmmLmOf0gELgcRMxN4w2iuIeVso5/6QymSrgmA==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "mdast-util-to-string": "^4.0.0", + "micromark": "^4.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-decode-string": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "unist-util-stringify-position": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm/-/mdast-util-gfm-3.1.0.tgz", + "integrity": "sha512-0ulfdQOM3ysHhCJ1p06l0b0VKlhU0wuQs3thxZQagjcjPrlFRqY215uZGHHJan9GEAXd9MbfPjFJz+qMkVR6zQ==", + "license": "MIT", + "dependencies": { + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-gfm-autolink-literal": "^2.0.0", + "mdast-util-gfm-footnote": "^2.0.0", + "mdast-util-gfm-strikethrough": "^2.0.0", + "mdast-util-gfm-table": "^2.0.0", + "mdast-util-gfm-task-list-item": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-autolink-literal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-autolink-literal/-/mdast-util-gfm-autolink-literal-2.0.1.tgz", + "integrity": "sha512-5HVP2MKaP6L+G6YaxPNjuL0BPrq9orG3TsrZ9YXbA3vDw/ACI4MEsnoDpn6ZNm7GnZgtAcONJyPhOP8tNJQavQ==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "ccount": "^2.0.0", + "devlop": "^1.0.0", + "mdast-util-find-and-replace": "^3.0.0", + "micromark-util-character": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-footnote": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-footnote/-/mdast-util-gfm-footnote-2.1.0.tgz", + "integrity": "sha512-sqpDWlsHn7Ac9GNZQMeUzPQSMzR6Wv0WKRNvQRg0KqHh02fpTz69Qc1QSseNX29bhz1ROIyNyxExfawVKTm1GQ==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.1.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-strikethrough": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-strikethrough/-/mdast-util-gfm-strikethrough-2.0.0.tgz", + "integrity": "sha512-mKKb915TF+OC5ptj5bJ7WFRPdYtuHv0yTRxK2tJvi+BDqbkiG7h7u/9SI89nRAYcmap2xHQL9D+QG/6wSrTtXg==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-table": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-table/-/mdast-util-gfm-table-2.0.0.tgz", + "integrity": "sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "markdown-table": "^3.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-task-list-item": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-task-list-item/-/mdast-util-gfm-task-list-item-2.0.0.tgz", + "integrity": "sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-phrasing": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-phrasing/-/mdast-util-phrasing-4.1.0.tgz", + "integrity": "sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "unist-util-is": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-hast": { + "version": "13.2.1", + "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-13.2.1.tgz", + "integrity": "sha512-cctsq2wp5vTsLIcaymblUriiTcZd0CwWtCbLvrOzYCDZoWyMNV8sZ7krj09FSnsiJi3WVsHLM4k6Dq/yaPyCXA==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "@ungap/structured-clone": "^1.0.0", + "devlop": "^1.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "trim-lines": "^3.0.0", + "unist-util-position": "^5.0.0", + "unist-util-visit": "^5.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-markdown": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-2.1.2.tgz", + "integrity": "sha512-xj68wMTvGXVOKonmog6LwyJKrYXZPvlwabaryTjLh9LuvovB/KAH+kvi8Gjj+7rJjsFi23nkUxRQv1KqSroMqA==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "longest-streak": "^3.0.0", + "mdast-util-phrasing": "^4.0.0", + "mdast-util-to-string": "^4.0.0", + "micromark-util-classify-character": "^2.0.0", + "micromark-util-decode-string": "^2.0.0", + "unist-util-visit": "^5.0.0", + "zwitch": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-4.0.0.tgz", + "integrity": "sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdn-data": { + "version": "2.12.2", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.12.2.tgz", + "integrity": "sha512-IEn+pegP1aManZuckezWCO+XZQDplx1366JoVhTpMpBB1sPey/SbveZQUosKiKiGYjg1wH4pMlNgXbCiYgihQA==", + "license": "CC0-1.0" + }, + "node_modules/micromark": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/micromark/-/micromark-4.0.2.tgz", + "integrity": "sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "@types/debug": "^4.0.0", + "debug": "^4.0.0", + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "micromark-core-commonmark": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-combine-extensions": "^2.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-encode": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-subtokenize": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-core-commonmark": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-2.0.3.tgz", + "integrity": "sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "micromark-factory-destination": "^2.0.0", + "micromark-factory-label": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-factory-title": "^2.0.0", + "micromark-factory-whitespace": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-classify-character": "^2.0.0", + "micromark-util-html-tag-name": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-subtokenize": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-gfm": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm/-/micromark-extension-gfm-3.0.0.tgz", + "integrity": "sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w==", + "license": "MIT", + "dependencies": { + "micromark-extension-gfm-autolink-literal": "^2.0.0", + "micromark-extension-gfm-footnote": "^2.0.0", + "micromark-extension-gfm-strikethrough": "^2.0.0", + "micromark-extension-gfm-table": "^2.0.0", + "micromark-extension-gfm-tagfilter": "^2.0.0", + "micromark-extension-gfm-task-list-item": "^2.0.0", + "micromark-util-combine-extensions": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-autolink-literal": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-autolink-literal/-/micromark-extension-gfm-autolink-literal-2.1.0.tgz", + "integrity": "sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw==", + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-footnote": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-footnote/-/micromark-extension-gfm-footnote-2.1.0.tgz", + "integrity": "sha512-/yPhxI1ntnDNsiHtzLKYnE3vf9JZ6cAisqVDauhp4CEHxlb4uoOTxOCJ+9s51bIB8U1N1FJ1RXOKTIlD5B/gqw==", + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-core-commonmark": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-strikethrough": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-strikethrough/-/micromark-extension-gfm-strikethrough-2.1.0.tgz", + "integrity": "sha512-ADVjpOOkjz1hhkZLlBiYA9cR2Anf8F4HqZUO6e5eDcPQd0Txw5fxLzzxnEkSkfnD0wziSGiv7sYhk/ktvbf1uw==", + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-classify-character": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-table": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-table/-/micromark-extension-gfm-table-2.1.1.tgz", + "integrity": "sha512-t2OU/dXXioARrC6yWfJ4hqB7rct14e8f7m0cbI5hUmDyyIlwv5vEtooptH8INkbLzOatzKuVbQmAYcbWoyz6Dg==", + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-tagfilter": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-tagfilter/-/micromark-extension-gfm-tagfilter-2.0.0.tgz", + "integrity": "sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg==", + "license": "MIT", + "dependencies": { + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-task-list-item": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-task-list-item/-/micromark-extension-gfm-task-list-item-2.1.0.tgz", + "integrity": "sha512-qIBZhqxqI6fjLDYFTBIa4eivDMnP+OZqsNwmQ3xNLE4Cxwc+zfQEfbs6tzAo2Hjq+bh6q5F+Z8/cksrLFYWQQw==", + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-factory-destination": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-2.0.1.tgz", + "integrity": "sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-label": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-2.0.1.tgz", + "integrity": "sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-space": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz", + "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-title": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-2.0.1.tgz", + "integrity": "sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-whitespace": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-2.0.1.tgz", + "integrity": "sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-character": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", + "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-chunked": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-2.0.1.tgz", + "integrity": "sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-classify-character": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-2.0.1.tgz", + "integrity": "sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-combine-extensions": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-2.0.1.tgz", + "integrity": "sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-chunked": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-decode-numeric-character-reference": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-2.0.2.tgz", + "integrity": "sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-decode-string": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-2.0.1.tgz", + "integrity": "sha512-nDV/77Fj6eH1ynwscYTOsbK7rR//Uj0bZXBwJZRfaLEJ1iGBR6kIfNmlNqaqJf649EP0F3NWNdeJi03elllNUQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "decode-named-character-reference": "^1.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-encode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.1.tgz", + "integrity": "sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-html-tag-name": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-2.0.1.tgz", + "integrity": "sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-normalize-identifier": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-2.0.1.tgz", + "integrity": "sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-resolve-all": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-2.0.1.tgz", + "integrity": "sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-sanitize-uri": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.1.tgz", + "integrity": "sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-encode": "^2.0.0", + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-subtokenize": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-2.1.0.tgz", + "integrity": "sha512-XQLu552iSctvnEcgXw6+Sx75GflAPNED1qx7eBJ+wydBb2KCbRZe+NwvIEEMM83uml1+2WSXpBAcp9IUCgCYWA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-symbol": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-types": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.2.tgz", + "integrity": "sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/mime-db": { + "version": "1.54.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", + "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.2.tgz", + "integrity": "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==", + "license": "MIT", + "dependencies": { + "mime-db": "^1.54.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/mrmime": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.1.tgz", + "integrity": "sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==", + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, + "node_modules/nanoid": { + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", + "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/neotraverse": { + "version": "0.6.18", + "resolved": "https://registry.npmjs.org/neotraverse/-/neotraverse-0.6.18.tgz", + "integrity": "sha512-Z4SmBUweYa09+o6pG+eASabEpP6QkQ70yHj351pQoEXIs8uHbaU2DWVmzBANKgflPa47A50PtB2+NgRpQvr7vA==", + "license": "MIT", + "engines": { + "node": ">= 10" + } + }, + "node_modules/nlcst-to-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/nlcst-to-string/-/nlcst-to-string-4.0.0.tgz", + "integrity": "sha512-YKLBCcUYKAg0FNlOBT6aI91qFmSiFKiluk655WzPF+DDMA02qIyy8uiRqI8QXtcFpEvll12LpL5MXqEmAZ+dcA==", + "license": "MIT", + "dependencies": { + "@types/nlcst": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/node-fetch-native": { + "version": "1.6.7", + "resolved": "https://registry.npmjs.org/node-fetch-native/-/node-fetch-native-1.6.7.tgz", + "integrity": "sha512-g9yhqoedzIUm0nTnTqAQvueMPVOuIY16bqgAJJC8XOOubYFNwz6IER9qs0Gq2Xd0+CecCKFjtdDTMA4u4xG06Q==", + "license": "MIT" + }, + "node_modules/node-mock-http": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/node-mock-http/-/node-mock-http-1.0.4.tgz", + "integrity": "sha512-8DY+kFsDkNXy1sJglUfuODx1/opAGJGyrTuFqEoN90oRc2Vk0ZbD4K2qmKXBBEhZQzdKHIVfEJpDU8Ak2NJEvQ==", + "license": "MIT" + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/nth-check": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", + "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0" + }, + "funding": { + "url": "https://github.com/fb55/nth-check?sponsor=1" + } + }, + "node_modules/ofetch": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/ofetch/-/ofetch-1.5.1.tgz", + "integrity": "sha512-2W4oUZlVaqAPAil6FUg/difl6YhqhUR7x2eZY4bQCko22UXg3hptq9KLQdqFClV+Wu85UX7hNtdGTngi/1BxcA==", + "license": "MIT", + "dependencies": { + "destr": "^2.0.5", + "node-fetch-native": "^1.6.7", + "ufo": "^1.6.1" + } + }, + "node_modules/ohash": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/ohash/-/ohash-2.0.11.tgz", + "integrity": "sha512-RdR9FQrFwNBNXAr4GixM8YaRZRJ5PUWbKYbE5eOsrwAjJW0q2REGcf79oYPsLyskQCZG1PLN+S/K1V00joZAoQ==", + "license": "MIT" + }, + "node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "license": "MIT", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/oniguruma-parser": { + "version": "0.12.1", + "resolved": "https://registry.npmjs.org/oniguruma-parser/-/oniguruma-parser-0.12.1.tgz", + "integrity": "sha512-8Unqkvk1RYc6yq2WBYRj4hdnsAxVze8i7iPfQr8e4uSP3tRv0rpZcbGUDvxfQQcdwHt/e9PrMvGCsa8OqG9X3w==", + "license": "MIT" + }, + "node_modules/oniguruma-to-es": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/oniguruma-to-es/-/oniguruma-to-es-4.3.4.tgz", + "integrity": "sha512-3VhUGN3w2eYxnTzHn+ikMI+fp/96KoRSVK9/kMTcFqj1NRDh2IhQCKvYxDnWePKRXY/AqH+Fuiyb7VHSzBjHfA==", + "license": "MIT", + "dependencies": { + "oniguruma-parser": "^0.12.1", + "regex": "^6.0.1", + "regex-recursion": "^6.0.2" + } + }, + "node_modules/p-limit": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-6.2.0.tgz", + "integrity": "sha512-kuUqqHNUqoIWp/c467RI4X6mmyuojY5jGutNU0wVTmEOOfcuwLqyMVoAi9MKi2Ak+5i9+nhmrK4ufZE8069kHA==", + "license": "MIT", + "dependencies": { + "yocto-queue": "^1.1.1" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-queue": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/p-queue/-/p-queue-8.1.1.tgz", + "integrity": "sha512-aNZ+VfjobsWryoiPnEApGGmf5WmNsCo9xu8dfaYamG5qaLP7ClhLN6NgsFe6SwJ2UbLEBK5dv9x8Mn5+RVhMWQ==", + "license": "MIT", + "dependencies": { + "eventemitter3": "^5.0.1", + "p-timeout": "^6.1.2" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-timeout": { + "version": "6.1.4", + "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-6.1.4.tgz", + "integrity": "sha512-MyIV3ZA/PmyBN/ud8vV9XzwTrNtR4jFrObymZYnZqMmW0zA8Z17vnT0rBgFE/TlohB+YCHqXMgZzb3Csp49vqg==", + "license": "MIT", + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/package-manager-detector": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/package-manager-detector/-/package-manager-detector-1.6.0.tgz", + "integrity": "sha512-61A5ThoTiDG/C8s8UMZwSorAGwMJ0ERVGj2OjoW5pAalsNOg15+iQiPzrLJ4jhZ1HJzmC2PIHT2oEiH3R5fzNA==", + "license": "MIT" + }, + "node_modules/parse-latin": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/parse-latin/-/parse-latin-7.0.0.tgz", + "integrity": "sha512-mhHgobPPua5kZ98EF4HWiH167JWBfl4pvAIXXdbaVohtK7a6YBOy56kvhCqduqyo/f3yrHFWmqmiMg/BkBkYYQ==", + "license": "MIT", + "dependencies": { + "@types/nlcst": "^2.0.0", + "@types/unist": "^3.0.0", + "nlcst-to-string": "^4.0.0", + "unist-util-modify-children": "^4.0.0", + "unist-util-visit-children": "^3.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/parse5": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.3.0.tgz", + "integrity": "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==", + "license": "MIT", + "dependencies": { + "entities": "^6.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/piccolore": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/piccolore/-/piccolore-0.1.3.tgz", + "integrity": "sha512-o8bTeDWjE086iwKrROaDf31K0qC/BENdm15/uH9usSC/uZjJOKb2YGiVHfLY4GhwsERiPI1jmwI2XrA7ACOxVw==", + "license": "ISC" + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/postcss": { + "version": "8.5.6", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz", + "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.11", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/prismjs": { + "version": "1.30.0", + "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.30.0.tgz", + "integrity": "sha512-DEvV2ZF2r2/63V+tK8hQvrR2ZGn10srHbXviTlcv7Kpzw8jWiNTqbVgjO3IY8RxrrOUF8VPMQQFysYYYv0YZxw==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/prompts": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", + "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", + "license": "MIT", + "dependencies": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/property-information": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/property-information/-/property-information-7.1.0.tgz", + "integrity": "sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/radix3": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/radix3/-/radix3-1.1.2.tgz", + "integrity": "sha512-b484I/7b8rDEdSDKckSSBA8knMpcdsXudlE/LNL639wFoHKwLbEkQFZHWEYwDC0wa0FKUcCY+GAF73Z7wxNVFA==", + "license": "MIT" + }, + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "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/regex": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/regex/-/regex-6.1.0.tgz", + "integrity": "sha512-6VwtthbV4o/7+OaAF9I5L5V3llLEsoPyq9P1JVXkedTP33c7MfCG0/5NOPcSJn0TzXcG9YUrR0gQSWioew3LDg==", + "license": "MIT", + "dependencies": { + "regex-utilities": "^2.3.0" + } + }, + "node_modules/regex-recursion": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/regex-recursion/-/regex-recursion-6.0.2.tgz", + "integrity": "sha512-0YCaSCq2VRIebiaUviZNs0cBz1kg5kVS2UKUfNIx8YVs1cN3AV7NTctO5FOKBA+UT2BPJIWZauYHPqJODG50cg==", + "license": "MIT", + "dependencies": { + "regex-utilities": "^2.3.0" + } + }, + "node_modules/regex-utilities": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/regex-utilities/-/regex-utilities-2.3.0.tgz", + "integrity": "sha512-8VhliFJAWRaUiVvREIiW2NXXTmHs4vMNnSzuJVhscgmGav3g9VDxLrQndI3dZZVVdp0ZO/5v0xmX516/7M9cng==", + "license": "MIT" + }, + "node_modules/rehype": { + "version": "13.0.2", + "resolved": "https://registry.npmjs.org/rehype/-/rehype-13.0.2.tgz", + "integrity": "sha512-j31mdaRFrwFRUIlxGeuPXXKWQxet52RBQRvCmzl5eCefn/KGbomK5GMHNMsOJf55fgo3qw5tST5neDuarDYR2A==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "rehype-parse": "^9.0.0", + "rehype-stringify": "^10.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/rehype-parse": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/rehype-parse/-/rehype-parse-9.0.1.tgz", + "integrity": "sha512-ksCzCD0Fgfh7trPDxr2rSylbwq9iYDkSn8TCDmEJ49ljEUBxDVCzCHv7QNzZOfODanX4+bWQ4WZqLCRWYLfhag==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "hast-util-from-html": "^2.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/rehype-raw": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/rehype-raw/-/rehype-raw-7.0.0.tgz", + "integrity": "sha512-/aE8hCfKlQeA8LmyeyQvQF3eBiLRGNlfBJEvWH7ivp9sBqs7TNqBL5X3v157rM4IFETqDnIOO+z5M/biZbo9Ww==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "hast-util-raw": "^9.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/rehype-stringify": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/rehype-stringify/-/rehype-stringify-10.0.1.tgz", + "integrity": "sha512-k9ecfXHmIPuFVI61B9DeLPN0qFHfawM6RsuX48hoqlaKSF61RskNjSm1lI8PhBEM0MRdLxVVm4WmTqJQccH9mA==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "hast-util-to-html": "^9.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-gfm": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/remark-gfm/-/remark-gfm-4.0.1.tgz", + "integrity": "sha512-1quofZ2RQ9EWdeN34S79+KExV1764+wCUGop5CPL1WGdD0ocPpu91lzPGbwWMECpEpd42kJGQwzRfyov9j4yNg==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-gfm": "^3.0.0", + "micromark-extension-gfm": "^3.0.0", + "remark-parse": "^11.0.0", + "remark-stringify": "^11.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-parse": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-11.0.0.tgz", + "integrity": "sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-from-markdown": "^2.0.0", + "micromark-util-types": "^2.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-rehype": { + "version": "11.1.2", + "resolved": "https://registry.npmjs.org/remark-rehype/-/remark-rehype-11.1.2.tgz", + "integrity": "sha512-Dh7l57ianaEoIpzbp0PC9UKAdCSVklD8E5Rpw7ETfbTl3FqcOOgq5q2LVDhgGCkaBv7p24JXikPdvhhmHvKMsw==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "mdast-util-to-hast": "^13.0.0", + "unified": "^11.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-smartypants": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/remark-smartypants/-/remark-smartypants-3.0.2.tgz", + "integrity": "sha512-ILTWeOriIluwEvPjv67v7Blgrcx+LZOkAUVtKI3putuhlZm84FnqDORNXPPm+HY3NdZOMhyDwZ1E+eZB/Df5dA==", + "license": "MIT", + "dependencies": { + "retext": "^9.0.0", + "retext-smartypants": "^6.0.0", + "unified": "^11.0.4", + "unist-util-visit": "^5.0.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/remark-stringify": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/remark-stringify/-/remark-stringify-11.0.0.tgz", + "integrity": "sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-to-markdown": "^2.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/retext": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/retext/-/retext-9.0.0.tgz", + "integrity": "sha512-sbMDcpHCNjvlheSgMfEcVrZko3cDzdbe1x/e7G66dFp0Ff7Mldvi2uv6JkJQzdRcvLYE8CA8Oe8siQx8ZOgTcA==", + "license": "MIT", + "dependencies": { + "@types/nlcst": "^2.0.0", + "retext-latin": "^4.0.0", + "retext-stringify": "^4.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/retext-latin": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/retext-latin/-/retext-latin-4.0.0.tgz", + "integrity": "sha512-hv9woG7Fy0M9IlRQloq/N6atV82NxLGveq+3H2WOi79dtIYWN8OaxogDm77f8YnVXJL2VD3bbqowu5E3EMhBYA==", + "license": "MIT", + "dependencies": { + "@types/nlcst": "^2.0.0", + "parse-latin": "^7.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/retext-smartypants": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/retext-smartypants/-/retext-smartypants-6.2.0.tgz", + "integrity": "sha512-kk0jOU7+zGv//kfjXEBjdIryL1Acl4i9XNkHxtM7Tm5lFiCog576fjNC9hjoR7LTKQ0DsPWy09JummSsH1uqfQ==", + "license": "MIT", + "dependencies": { + "@types/nlcst": "^2.0.0", + "nlcst-to-string": "^4.0.0", + "unist-util-visit": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/retext-stringify": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/retext-stringify/-/retext-stringify-4.0.0.tgz", + "integrity": "sha512-rtfN/0o8kL1e+78+uxPTqu1Klt0yPzKuQ2BfWwwfgIUSayyzxpM1PJzkKt4V8803uB9qSy32MvI7Xep9khTpiA==", + "license": "MIT", + "dependencies": { + "@types/nlcst": "^2.0.0", + "nlcst-to-string": "^4.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/rollup": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.59.0.tgz", + "integrity": "sha512-2oMpl67a3zCH9H79LeMcbDhXW/UmWG/y2zuqnF2jQq5uq9TbM9TVyXvA4+t+ne2IIkBdrLpAaRQAvo7YI/Yyeg==", + "license": "MIT", + "dependencies": { + "@types/estree": "1.0.8" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.59.0", + "@rollup/rollup-android-arm64": "4.59.0", + "@rollup/rollup-darwin-arm64": "4.59.0", + "@rollup/rollup-darwin-x64": "4.59.0", + "@rollup/rollup-freebsd-arm64": "4.59.0", + "@rollup/rollup-freebsd-x64": "4.59.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.59.0", + "@rollup/rollup-linux-arm-musleabihf": "4.59.0", + "@rollup/rollup-linux-arm64-gnu": "4.59.0", + "@rollup/rollup-linux-arm64-musl": "4.59.0", + "@rollup/rollup-linux-loong64-gnu": "4.59.0", + "@rollup/rollup-linux-loong64-musl": "4.59.0", + "@rollup/rollup-linux-ppc64-gnu": "4.59.0", + "@rollup/rollup-linux-ppc64-musl": "4.59.0", + "@rollup/rollup-linux-riscv64-gnu": "4.59.0", + "@rollup/rollup-linux-riscv64-musl": "4.59.0", + "@rollup/rollup-linux-s390x-gnu": "4.59.0", + "@rollup/rollup-linux-x64-gnu": "4.59.0", + "@rollup/rollup-linux-x64-musl": "4.59.0", + "@rollup/rollup-openbsd-x64": "4.59.0", + "@rollup/rollup-openharmony-arm64": "4.59.0", + "@rollup/rollup-win32-arm64-msvc": "4.59.0", + "@rollup/rollup-win32-ia32-msvc": "4.59.0", + "@rollup/rollup-win32-x64-gnu": "4.59.0", + "@rollup/rollup-win32-x64-msvc": "4.59.0", + "fsevents": "~2.3.2" + } + }, + "node_modules/sax": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.5.0.tgz", + "integrity": "sha512-21IYA3Q5cQf089Z6tgaUTr7lDAyzoTPx5HRtbhsME8Udispad8dC/+sziTNugOEx54ilvatQ9YCzl4KQLPcRHA==", + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=11.0.0" + } + }, + "node_modules/semver": { + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", + "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/send": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/send/-/send-1.2.1.tgz", + "integrity": "sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ==", + "license": "MIT", + "dependencies": { + "debug": "^4.4.3", + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "etag": "^1.8.1", + "fresh": "^2.0.0", + "http-errors": "^2.0.1", + "mime-types": "^3.0.2", + "ms": "^2.1.3", + "on-finished": "^2.4.1", + "range-parser": "^1.2.1", + "statuses": "^2.0.2" + }, + "engines": { + "node": ">= 18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/server-destroy": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/server-destroy/-/server-destroy-1.0.1.tgz", + "integrity": "sha512-rb+9B5YBIEzYcD6x2VKidaa+cqYBJQKnU4oe4E3ANwRRN56yk/ua1YCJT1n21NTS8w6CcOclAKNP3PhdCXKYtQ==", + "license": "ISC" + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", + "license": "ISC" + }, + "node_modules/sharp": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.34.5.tgz", + "integrity": "sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg==", + "hasInstallScript": true, + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@img/colour": "^1.0.0", + "detect-libc": "^2.1.2", + "semver": "^7.7.3" + }, + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-darwin-arm64": "0.34.5", + "@img/sharp-darwin-x64": "0.34.5", + "@img/sharp-libvips-darwin-arm64": "1.2.4", + "@img/sharp-libvips-darwin-x64": "1.2.4", + "@img/sharp-libvips-linux-arm": "1.2.4", + "@img/sharp-libvips-linux-arm64": "1.2.4", + "@img/sharp-libvips-linux-ppc64": "1.2.4", + "@img/sharp-libvips-linux-riscv64": "1.2.4", + "@img/sharp-libvips-linux-s390x": "1.2.4", + "@img/sharp-libvips-linux-x64": "1.2.4", + "@img/sharp-libvips-linuxmusl-arm64": "1.2.4", + "@img/sharp-libvips-linuxmusl-x64": "1.2.4", + "@img/sharp-linux-arm": "0.34.5", + "@img/sharp-linux-arm64": "0.34.5", + "@img/sharp-linux-ppc64": "0.34.5", + "@img/sharp-linux-riscv64": "0.34.5", + "@img/sharp-linux-s390x": "0.34.5", + "@img/sharp-linux-x64": "0.34.5", + "@img/sharp-linuxmusl-arm64": "0.34.5", + "@img/sharp-linuxmusl-x64": "0.34.5", + "@img/sharp-wasm32": "0.34.5", + "@img/sharp-win32-arm64": "0.34.5", + "@img/sharp-win32-ia32": "0.34.5", + "@img/sharp-win32-x64": "0.34.5" + } + }, + "node_modules/shiki": { + "version": "3.23.0", + "resolved": "https://registry.npmjs.org/shiki/-/shiki-3.23.0.tgz", + "integrity": "sha512-55Dj73uq9ZXL5zyeRPzHQsK7Nbyt6Y10k5s7OjuFZGMhpp4r/rsLBH0o/0fstIzX1Lep9VxefWljK/SKCzygIA==", + "license": "MIT", + "dependencies": { + "@shikijs/core": "3.23.0", + "@shikijs/engine-javascript": "3.23.0", + "@shikijs/engine-oniguruma": "3.23.0", + "@shikijs/langs": "3.23.0", + "@shikijs/themes": "3.23.0", + "@shikijs/types": "3.23.0", + "@shikijs/vscode-textmate": "^10.0.2", + "@types/hast": "^3.0.4" + } + }, + "node_modules/sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", + "license": "MIT" + }, + "node_modules/smol-toml": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/smol-toml/-/smol-toml-1.6.0.tgz", + "integrity": "sha512-4zemZi0HvTnYwLfrpk/CF9LOd9Lt87kAt50GnqhMpyF9U3poDAP2+iukq2bZsO/ufegbYehBkqINbsWxj4l4cw==", + "license": "BSD-3-Clause", + "engines": { + "node": ">= 18" + }, + "funding": { + "url": "https://github.com/sponsors/cyyynthia" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/space-separated-tokens": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz", + "integrity": "sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/statuses": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz", + "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/string-width": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", + "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", + "license": "MIT", + "dependencies": { + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/stringify-entities": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-4.0.4.tgz", + "integrity": "sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==", + "license": "MIT", + "dependencies": { + "character-entities-html4": "^2.0.0", + "character-entities-legacy": "^3.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/strip-ansi": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz", + "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/svgo": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/svgo/-/svgo-4.0.1.tgz", + "integrity": "sha512-XDpWUOPC6FEibaLzjfe0ucaV0YrOjYotGJO1WpF0Zd+n6ZGEQUsSugaoLq9QkEZtAfQIxT42UChcssDVPP3+/w==", + "license": "MIT", + "dependencies": { + "commander": "^11.1.0", + "css-select": "^5.1.0", + "css-tree": "^3.0.1", + "css-what": "^6.1.0", + "csso": "^5.0.5", + "picocolors": "^1.1.1", + "sax": "^1.5.0" + }, + "bin": { + "svgo": "bin/svgo.js" + }, + "engines": { + "node": ">=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/svgo" + } + }, + "node_modules/tiny-inflate": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tiny-inflate/-/tiny-inflate-1.0.3.tgz", + "integrity": "sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw==", + "license": "MIT" + }, + "node_modules/tinyexec": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.0.2.tgz", + "integrity": "sha512-W/KYk+NFhkmsYpuHq5JykngiOCnxeVL8v8dFnqxSD8qEEdRfXk1SDM6JzNqcERbcGYj9tMrDQBYV9cjgnunFIg==", + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/tinyglobby": { + "version": "0.2.15", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", + "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==", + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.3" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "license": "MIT", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/trim-lines": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/trim-lines/-/trim-lines-3.0.1.tgz", + "integrity": "sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/trough": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/trough/-/trough-2.2.0.tgz", + "integrity": "sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/tsconfck": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/tsconfck/-/tsconfck-3.1.6.tgz", + "integrity": "sha512-ks6Vjr/jEw0P1gmOVwutM3B7fWxoWBL2KRDb1JfqGVawBmO5UsvmWOQFGHBPl5yxYz4eERr19E6L7NMv+Fej4w==", + "license": "MIT", + "bin": { + "tsconfck": "bin/tsconfck.js" + }, + "engines": { + "node": "^18 || >=20" + }, + "peerDependencies": { + "typescript": "^5.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD", + "optional": true + }, + "node_modules/type-fest": { + "version": "4.41.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.41.0.tgz", + "integrity": "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==", + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/typescript": { + "version": "5.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", + "license": "Apache-2.0", + "peer": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/ufo": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.6.3.tgz", + "integrity": "sha512-yDJTmhydvl5lJzBmy/hyOAA0d+aqCBuwl818haVdYCRrWV84o7YyeVm4QlVHStqNrrJSTb6jKuFAVqAFsr+K3Q==", + "license": "MIT" + }, + "node_modules/ultrahtml": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/ultrahtml/-/ultrahtml-1.6.0.tgz", + "integrity": "sha512-R9fBn90VTJrqqLDwyMph+HGne8eqY1iPfYhPzZrvKpIfwkWZbcYlfpsb8B9dTvBfpy1/hqAD7Wi8EKfP9e8zdw==", + "license": "MIT" + }, + "node_modules/uncrypto": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/uncrypto/-/uncrypto-0.1.3.tgz", + "integrity": "sha512-Ql87qFHB3s/De2ClA9e0gsnS6zXG27SkTiSJwjCc9MebbfapQfuPzumMIUMi38ezPZVNFcHI9sUIepeQfw8J8Q==", + "license": "MIT" + }, + "node_modules/undici-types": { + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz", + "integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==", + "license": "MIT", + "optional": true, + "peer": true + }, + "node_modules/unified": { + "version": "11.0.5", + "resolved": "https://registry.npmjs.org/unified/-/unified-11.0.5.tgz", + "integrity": "sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "bail": "^2.0.0", + "devlop": "^1.0.0", + "extend": "^3.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unifont": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/unifont/-/unifont-0.7.4.tgz", + "integrity": "sha512-oHeis4/xl42HUIeHuNZRGEvxj5AaIKR+bHPNegRq5LV1gdc3jundpONbjglKpihmJf+dswygdMJn3eftGIMemg==", + "license": "MIT", + "dependencies": { + "css-tree": "^3.1.0", + "ofetch": "^1.5.1", + "ohash": "^2.0.11" + } + }, + "node_modules/unist-util-find-after": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-find-after/-/unist-util-find-after-5.0.0.tgz", + "integrity": "sha512-amQa0Ep2m6hE2g72AugUItjbuM8X8cGQnFoHk0pGfrFeT9GZhzN5SW8nRsiGKK7Aif4CrACPENkA6P/Lw6fHGQ==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-is": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.1.tgz", + "integrity": "sha512-LsiILbtBETkDz8I9p1dQ0uyRUWuaQzd/cuEeS1hoRSyW5E5XGmTzlwY1OrNzzakGowI9Dr/I8HVaw4hTtnxy8g==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-modify-children": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-modify-children/-/unist-util-modify-children-4.0.0.tgz", + "integrity": "sha512-+tdN5fGNddvsQdIzUF3Xx82CU9sMM+fA0dLgR9vOmT0oPT2jH+P1nd5lSqfCfXAw+93NhcXNY2qqvTUtE4cQkw==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "array-iterate": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-position": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-5.0.0.tgz", + "integrity": "sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-remove-position": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-remove-position/-/unist-util-remove-position-5.0.0.tgz", + "integrity": "sha512-Hp5Kh3wLxv0PHj9m2yZhhLt58KzPtEYKQQ4yxfYFEO7EvHwzyDYnduhHnY1mDxoqr7VUwVuHXk9RXKIiYS1N8Q==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-visit": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-stringify-position": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", + "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-visit": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.0.0.tgz", + "integrity": "sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-visit-children": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit-children/-/unist-util-visit-children-3.0.0.tgz", + "integrity": "sha512-RgmdTfSBOg04sdPcpTSD1jzoNBjt9a80/ZCzp5cI9n1qPzLZWF9YdvWGN2zmTumP1HWhXKdUWexjy/Wy/lJ7tA==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-visit-parents": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.2.tgz", + "integrity": "sha512-goh1s1TBrqSqukSc8wrjwWhL0hiJxgA8m4kFxGlQ+8FYQ3C/m11FcTs4YYem7V664AhHVvgoQLk890Ssdsr2IQ==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unstorage": { + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/unstorage/-/unstorage-1.17.4.tgz", + "integrity": "sha512-fHK0yNg38tBiJKp/Vgsq4j0JEsCmgqH58HAn707S7zGkArbZsVr/CwINoi+nh3h98BRCwKvx1K3Xg9u3VV83sw==", + "license": "MIT", + "dependencies": { + "anymatch": "^3.1.3", + "chokidar": "^5.0.0", + "destr": "^2.0.5", + "h3": "^1.15.5", + "lru-cache": "^11.2.0", + "node-fetch-native": "^1.6.7", + "ofetch": "^1.5.1", + "ufo": "^1.6.3" + }, + "peerDependencies": { + "@azure/app-configuration": "^1.8.0", + "@azure/cosmos": "^4.2.0", + "@azure/data-tables": "^13.3.0", + "@azure/identity": "^4.6.0", + "@azure/keyvault-secrets": "^4.9.0", + "@azure/storage-blob": "^12.26.0", + "@capacitor/preferences": "^6 || ^7 || ^8", + "@deno/kv": ">=0.9.0", + "@netlify/blobs": "^6.5.0 || ^7.0.0 || ^8.1.0 || ^9.0.0 || ^10.0.0", + "@planetscale/database": "^1.19.0", + "@upstash/redis": "^1.34.3", + "@vercel/blob": ">=0.27.1", + "@vercel/functions": "^2.2.12 || ^3.0.0", + "@vercel/kv": "^1 || ^2 || ^3", + "aws4fetch": "^1.0.20", + "db0": ">=0.2.1", + "idb-keyval": "^6.2.1", + "ioredis": "^5.4.2", + "uploadthing": "^7.4.4" + }, + "peerDependenciesMeta": { + "@azure/app-configuration": { + "optional": true + }, + "@azure/cosmos": { + "optional": true + }, + "@azure/data-tables": { + "optional": true + }, + "@azure/identity": { + "optional": true + }, + "@azure/keyvault-secrets": { + "optional": true + }, + "@azure/storage-blob": { + "optional": true + }, + "@capacitor/preferences": { + "optional": true + }, + "@deno/kv": { + "optional": true + }, + "@netlify/blobs": { + "optional": true + }, + "@planetscale/database": { + "optional": true + }, + "@upstash/redis": { + "optional": true + }, + "@vercel/blob": { + "optional": true + }, + "@vercel/functions": { + "optional": true + }, + "@vercel/kv": { + "optional": true + }, + "aws4fetch": { + "optional": true + }, + "db0": { + "optional": true + }, + "idb-keyval": { + "optional": true + }, + "ioredis": { + "optional": true + }, + "uploadthing": { + "optional": true + } + } + }, + "node_modules/vfile": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.3.tgz", + "integrity": "sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vfile-location": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-5.0.3.tgz", + "integrity": "sha512-5yXvWDEgqeiYiBe1lbxYF7UMAIm/IcopxMHrMQDq3nvKcjPKIhZklUKL+AE7J7uApI4kwe2snsK+eI6UTj9EHg==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vfile-message": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.3.tgz", + "integrity": "sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-stringify-position": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vite": { + "version": "6.4.1", + "resolved": "https://registry.npmjs.org/vite/-/vite-6.4.1.tgz", + "integrity": "sha512-+Oxm7q9hDoLMyJOYfUYBuHQo+dkAloi33apOPP56pzj+vsdJDzr+j1NISE5pyaAuKL4A3UD34qd0lx5+kfKp2g==", + "license": "MIT", + "dependencies": { + "esbuild": "^0.25.0", + "fdir": "^6.4.4", + "picomatch": "^4.0.2", + "postcss": "^8.5.3", + "rollup": "^4.34.9", + "tinyglobby": "^0.2.13" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^18.0.0 || ^20.0.0 || >=22.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", + "jiti": ">=1.21.0", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "sass-embedded": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.16.0", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "jiti": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } + } + }, + "node_modules/vitefu": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/vitefu/-/vitefu-1.1.1.tgz", + "integrity": "sha512-B/Fegf3i8zh0yFbpzZ21amWzHmuNlLlmJT6n7bu5e+pCHUKQIfXSYokrqOBGEMMe9UG2sostKQF9mml/vYaWJQ==", + "license": "MIT", + "workspaces": [ + "tests/deps/*", + "tests/projects/*", + "tests/projects/workspace/packages/*" + ], + "peerDependencies": { + "vite": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0-beta.0" + }, + "peerDependenciesMeta": { + "vite": { + "optional": true + } + } + }, + "node_modules/web-namespaces": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/web-namespaces/-/web-namespaces-2.0.1.tgz", + "integrity": "sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/which-pm-runs": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/which-pm-runs/-/which-pm-runs-1.1.0.tgz", + "integrity": "sha512-n1brCuqClxfFfq/Rb0ICg9giSZqCS+pLtccdag6C2HyufBrh3fBOiy9nb6ggRMvWOVH5GrdJskj5iGTZNxd7SA==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/widest-line": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-5.0.0.tgz", + "integrity": "sha512-c9bZp7b5YtRj2wOe6dlj32MK+Bx/M/d+9VB2SHM1OtsUHR0aV0tdP6DWh/iMt0kWi1t5g1Iudu6hQRNd1A4PVA==", + "license": "MIT", + "dependencies": { + "string-width": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/wrap-ansi": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.2.tgz", + "integrity": "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.2.1", + "string-width": "^7.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/xxhash-wasm": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/xxhash-wasm/-/xxhash-wasm-1.1.0.tgz", + "integrity": "sha512-147y/6YNh+tlp6nd/2pWq38i9h6mz/EuQ6njIrmW8D1BS5nCqs0P6DG+m6zTGnNz5I+uhZ0SHxBs9BsPrwcKDA==", + "license": "MIT" + }, + "node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/yocto-queue": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.2.2.tgz", + "integrity": "sha512-4LCcse/U2MHZ63HAJVE+v71o7yOdIe4cZ70Wpf8D/IyjDKYQLV5GD46B+hSTjJsvV5PztjvHoU580EftxjDZFQ==", + "license": "MIT", + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/yocto-spinner": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/yocto-spinner/-/yocto-spinner-0.2.3.tgz", + "integrity": "sha512-sqBChb33loEnkoXte1bLg45bEBsOP9N1kzQh5JZNKj/0rik4zAPTNSAVPj3uQAdc6slYJ0Ksc403G2XgxsJQFQ==", + "license": "MIT", + "dependencies": { + "yoctocolors": "^2.1.1" + }, + "engines": { + "node": ">=18.19" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/yoctocolors": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yoctocolors/-/yoctocolors-2.1.2.tgz", + "integrity": "sha512-CzhO+pFNo8ajLM2d2IW/R93ipy99LWjtwblvC1RsoSUMZgyLbYFr221TnSNT7GjGdYui6P459mw9JH/g/zW2ug==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/zod": { + "version": "3.25.76", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", + "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + }, + "node_modules/zod-to-json-schema": { + "version": "3.25.1", + "resolved": "https://registry.npmjs.org/zod-to-json-schema/-/zod-to-json-schema-3.25.1.tgz", + "integrity": "sha512-pM/SU9d3YAggzi6MtR4h7ruuQlqKtad8e9S0fmxcMi+ueAK5Korys/aWcV9LIIHTVbj01NdzxcnXSN+O74ZIVA==", + "license": "ISC", + "peerDependencies": { + "zod": "^3.25 || ^4" + } + }, + "node_modules/zod-to-ts": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/zod-to-ts/-/zod-to-ts-1.2.0.tgz", + "integrity": "sha512-x30XE43V+InwGpvTySRNz9kB7qFU8DlyEy7BsSTCHPH1R0QasMmHWZDCzYm6bVXtj/9NNJAZF3jW8rzFvH5OFA==", + "peerDependencies": { + "typescript": "^4.9.4 || ^5.0.2", + "zod": "^3" + } + }, + "node_modules/zwitch": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz", + "integrity": "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + } + } +} diff --git a/tests/resources/sites/astro-custom-start-command/package.json b/tests/resources/sites/astro-custom-start-command/package.json new file mode 100644 index 0000000000..bf2475ef57 --- /dev/null +++ b/tests/resources/sites/astro-custom-start-command/package.json @@ -0,0 +1,21 @@ +{ + "name": "astro-custom-start-command", + "type": "module", + "version": "0.0.1", + "scripts": { + "dev": "astro dev", + "build": "astro build && cp custom-server.js dist/custom-server.js && rm -rf node_modules && npm install --production", + "preview": "astro preview", + "astro": "astro" + }, + "dependencies": { + "@astrojs/node": "^9.5.4", + "astro": "^5.2.5" + }, + "devDependencies": { + }, + "overrides": { + "rollup": ">=4.58.1", + "svgo": ">=4.0.1" + } +} diff --git a/tests/resources/sites/astro-custom-start-command/src/pages/index.astro b/tests/resources/sites/astro-custom-start-command/src/pages/index.astro new file mode 100644 index 0000000000..97fc712e50 --- /dev/null +++ b/tests/resources/sites/astro-custom-start-command/src/pages/index.astro @@ -0,0 +1,16 @@ +--- + +--- + + + + + + + + Astro + + +

Homepage OK

+ + diff --git a/tests/resources/sites/astro-custom-start-command/src/pages/ssr.js b/tests/resources/sites/astro-custom-start-command/src/pages/ssr.js new file mode 100644 index 0000000000..98cab6d896 --- /dev/null +++ b/tests/resources/sites/astro-custom-start-command/src/pages/ssr.js @@ -0,0 +1,5 @@ +export const prerender = false; + +export const GET = async () => { + return new Response("SSR OK (" + Date.now() + ")"); +}; diff --git a/tests/resources/sites/astro/package-lock.json b/tests/resources/sites/astro/package-lock.json new file mode 100644 index 0000000000..e9d14e26db --- /dev/null +++ b/tests/resources/sites/astro/package-lock.json @@ -0,0 +1,5646 @@ +{ + "name": "my-astro-app", + "version": "0.0.1", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "my-astro-app", + "version": "0.0.1", + "dependencies": { + "@astrojs/node": "^9.0.2", + "astro": "^5.2.5" + } + }, + "node_modules/@astrojs/compiler": { + "version": "2.13.1", + "resolved": "https://registry.npmjs.org/@astrojs/compiler/-/compiler-2.13.1.tgz", + "integrity": "sha512-f3FN83d2G/v32ipNClRKgYv30onQlMZX1vCeZMjPsMMPl1mDpmbl0+N5BYo4S/ofzqJyS5hvwacEo0CCVDn/Qg==", + "license": "MIT" + }, + "node_modules/@astrojs/internal-helpers": { + "version": "0.7.5", + "resolved": "https://registry.npmjs.org/@astrojs/internal-helpers/-/internal-helpers-0.7.5.tgz", + "integrity": "sha512-vreGnYSSKhAjFJCWAwe/CNhONvoc5lokxtRoZims+0wa3KbHBdPHSSthJsKxPd8d/aic6lWKpRTYGY/hsgK6EA==", + "license": "MIT" + }, + "node_modules/@astrojs/markdown-remark": { + "version": "6.3.10", + "resolved": "https://registry.npmjs.org/@astrojs/markdown-remark/-/markdown-remark-6.3.10.tgz", + "integrity": "sha512-kk4HeYR6AcnzC4QV8iSlOfh+N8TZ3MEStxPyenyCtemqn8IpEATBFMTJcfrNW32dgpt6MY3oCkMM/Tv3/I4G3A==", + "license": "MIT", + "dependencies": { + "@astrojs/internal-helpers": "0.7.5", + "@astrojs/prism": "3.3.0", + "github-slugger": "^2.0.0", + "hast-util-from-html": "^2.0.3", + "hast-util-to-text": "^4.0.2", + "import-meta-resolve": "^4.2.0", + "js-yaml": "^4.1.1", + "mdast-util-definitions": "^6.0.0", + "rehype-raw": "^7.0.0", + "rehype-stringify": "^10.0.1", + "remark-gfm": "^4.0.1", + "remark-parse": "^11.0.0", + "remark-rehype": "^11.1.2", + "remark-smartypants": "^3.0.2", + "shiki": "^3.19.0", + "smol-toml": "^1.5.2", + "unified": "^11.0.5", + "unist-util-remove-position": "^5.0.0", + "unist-util-visit": "^5.0.0", + "unist-util-visit-parents": "^6.0.2", + "vfile": "^6.0.3" + } + }, + "node_modules/@astrojs/node": { + "version": "9.5.4", + "resolved": "https://registry.npmjs.org/@astrojs/node/-/node-9.5.4.tgz", + "integrity": "sha512-AbPSZsMGu8hXPR2XxV79RaKy8h6wijhtoqZGeUf4OXg2w1mxXlx4VnIc1D+QvtsgauSz7P5PLhmvf6w/J41GJg==", + "license": "MIT", + "dependencies": { + "@astrojs/internal-helpers": "0.7.5", + "send": "^1.2.1", + "server-destroy": "^1.0.1" + }, + "peerDependencies": { + "astro": "^5.17.3" + } + }, + "node_modules/@astrojs/prism": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@astrojs/prism/-/prism-3.3.0.tgz", + "integrity": "sha512-q8VwfU/fDZNoDOf+r7jUnMC2//H2l0TuQ6FkGJL8vD8nw/q5KiL3DS1KKBI3QhI9UQhpJ5dc7AtqfbXWuOgLCQ==", + "license": "MIT", + "dependencies": { + "prismjs": "^1.30.0" + }, + "engines": { + "node": "18.20.8 || ^20.3.0 || >=22.0.0" + } + }, + "node_modules/@astrojs/telemetry": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@astrojs/telemetry/-/telemetry-3.3.0.tgz", + "integrity": "sha512-UFBgfeldP06qu6khs/yY+q1cDAaArM2/7AEIqQ9Cuvf7B1hNLq0xDrZkct+QoIGyjq56y8IaE2I3CTvG99mlhQ==", + "license": "MIT", + "dependencies": { + "ci-info": "^4.2.0", + "debug": "^4.4.0", + "dlv": "^1.1.3", + "dset": "^3.1.4", + "is-docker": "^3.0.0", + "is-wsl": "^3.1.0", + "which-pm-runs": "^1.1.0" + }, + "engines": { + "node": "18.20.8 || ^20.3.0 || >=22.0.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", + "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", + "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.0.tgz", + "integrity": "sha512-IyDgFV5GeDUVX4YdF/3CPULtVGSXXMLh1xVIgdCgxApktqnQV0r7/8Nqthg+8YLGaAtdyIlo2qIdZrbCv4+7ww==", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.29.0" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/types": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.0.tgz", + "integrity": "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==", + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.27.1", + "@babel/helper-validator-identifier": "^7.28.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@capsizecss/unpack": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@capsizecss/unpack/-/unpack-4.0.0.tgz", + "integrity": "sha512-VERIM64vtTP1C4mxQ5thVT9fK0apjPFobqybMtA1UdUujWka24ERHbRHFGmpbbhp73MhV+KSsHQH9C6uOTdEQA==", + "license": "MIT", + "dependencies": { + "fontkitten": "^1.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@emnapi/runtime": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.8.1.tgz", + "integrity": "sha512-mehfKSMWjjNol8659Z8KxEMrdSJDDot5SXMq00dM8BN4o+CLNXQ0xH2V7EchNHV4RmbZLmmPdEaXZc5H2FXmDg==", + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.3.tgz", + "integrity": "sha512-9fJMTNFTWZMh5qwrBItuziu834eOCUcEqymSH7pY+zoMVEZg3gcPuBNxH1EvfVYe9h0x/Ptw8KBzv7qxb7l8dg==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.3.tgz", + "integrity": "sha512-i5D1hPY7GIQmXlXhs2w8AWHhenb00+GxjxRncS2ZM7YNVGNfaMxgzSGuO8o8SJzRc/oZwU2bcScvVERk03QhzA==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.3.tgz", + "integrity": "sha512-YdghPYUmj/FX2SYKJ0OZxf+iaKgMsKHVPF1MAq/P8WirnSpCStzKJFjOjzsW0QQ7oIAiccHdcqjbHmJxRb/dmg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.3.tgz", + "integrity": "sha512-IN/0BNTkHtk8lkOM8JWAYFg4ORxBkZQf9zXiEOfERX/CzxW3Vg1ewAhU7QSWQpVIzTW+b8Xy+lGzdYXV6UZObQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.3.tgz", + "integrity": "sha512-Re491k7ByTVRy0t3EKWajdLIr0gz2kKKfzafkth4Q8A5n1xTHrkqZgLLjFEHVD+AXdUGgQMq+Godfq45mGpCKg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.3.tgz", + "integrity": "sha512-vHk/hA7/1AckjGzRqi6wbo+jaShzRowYip6rt6q7VYEDX4LEy1pZfDpdxCBnGtl+A5zq8iXDcyuxwtv3hNtHFg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.3.tgz", + "integrity": "sha512-ipTYM2fjt3kQAYOvo6vcxJx3nBYAzPjgTCk7QEgZG8AUO3ydUhvelmhrbOheMnGOlaSFUoHXB6un+A7q4ygY9w==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.3.tgz", + "integrity": "sha512-dDk0X87T7mI6U3K9VjWtHOXqwAMJBNN2r7bejDsc+j03SEjtD9HrOl8gVFByeM0aJksoUuUVU9TBaZa2rgj0oA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.3.tgz", + "integrity": "sha512-s6nPv2QkSupJwLYyfS+gwdirm0ukyTFNl3KTgZEAiJDd+iHZcbTPPcWCcRYH+WlNbwChgH2QkE9NSlNrMT8Gfw==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.3.tgz", + "integrity": "sha512-sZOuFz/xWnZ4KH3YfFrKCf1WyPZHakVzTiqji3WDc0BCl2kBwiJLCXpzLzUBLgmp4veFZdvN5ChW4Eq/8Fc2Fg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.3.tgz", + "integrity": "sha512-yGlQYjdxtLdh0a3jHjuwOrxQjOZYD/C9PfdbgJJF3TIZWnm/tMd/RcNiLngiu4iwcBAOezdnSLAwQDPqTmtTYg==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.3.tgz", + "integrity": "sha512-WO60Sn8ly3gtzhyjATDgieJNet/KqsDlX5nRC5Y3oTFcS1l0KWba+SEa9Ja1GfDqSF1z6hif/SkpQJbL63cgOA==", + "cpu": [ + "loong64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.3.tgz", + "integrity": "sha512-APsymYA6sGcZ4pD6k+UxbDjOFSvPWyZhjaiPyl/f79xKxwTnrn5QUnXR5prvetuaSMsb4jgeHewIDCIWljrSxw==", + "cpu": [ + "mips64el" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.3.tgz", + "integrity": "sha512-eizBnTeBefojtDb9nSh4vvVQ3V9Qf9Df01PfawPcRzJH4gFSgrObw+LveUyDoKU3kxi5+9RJTCWlj4FjYXVPEA==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.3.tgz", + "integrity": "sha512-3Emwh0r5wmfm3ssTWRQSyVhbOHvqegUDRd0WhmXKX2mkHJe1SFCMJhagUleMq+Uci34wLSipf8Lagt4LlpRFWQ==", + "cpu": [ + "riscv64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.3.tgz", + "integrity": "sha512-pBHUx9LzXWBc7MFIEEL0yD/ZVtNgLytvx60gES28GcWMqil8ElCYR4kvbV2BDqsHOvVDRrOxGySBM9Fcv744hw==", + "cpu": [ + "s390x" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.3.tgz", + "integrity": "sha512-Czi8yzXUWIQYAtL/2y6vogER8pvcsOsk5cpwL4Gk5nJqH5UZiVByIY8Eorm5R13gq+DQKYg0+JyQoytLQas4dA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.3.tgz", + "integrity": "sha512-sDpk0RgmTCR/5HguIZa9n9u+HVKf40fbEUt+iTzSnCaGvY9kFP0YKBWZtJaraonFnqef5SlJ8/TiPAxzyS+UoA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.3.tgz", + "integrity": "sha512-P14lFKJl/DdaE00LItAukUdZO5iqNH7+PjoBm+fLQjtxfcfFE20Xf5CrLsmZdq5LFFZzb5JMZ9grUwvtVYzjiA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.3.tgz", + "integrity": "sha512-AIcMP77AvirGbRl/UZFTq5hjXK+2wC7qFRGoHSDrZ5v5b8DK/GYpXW3CPRL53NkvDqb9D+alBiC/dV0Fb7eJcw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.3.tgz", + "integrity": "sha512-DnW2sRrBzA+YnE70LKqnM3P+z8vehfJWHXECbwBmH/CU51z6FiqTQTHFenPlHmo3a8UgpLyH3PT+87OViOh1AQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.3.tgz", + "integrity": "sha512-NinAEgr/etERPTsZJ7aEZQvvg/A6IsZG/LgZy+81wON2huV7SrK3e63dU0XhyZP4RKGyTm7aOgmQk0bGp0fy2g==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.3.tgz", + "integrity": "sha512-PanZ+nEz+eWoBJ8/f8HKxTTD172SKwdXebZ0ndd953gt1HRBbhMsaNqjTyYLGLPdoWHy4zLU7bDVJztF5f3BHA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.3.tgz", + "integrity": "sha512-B2t59lWWYrbRDw/tjiWOuzSsFh1Y/E95ofKz7rIVYSQkUYBjfSgf6oeYPNWHToFRr2zx52JKApIcAS/D5TUBnA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.3.tgz", + "integrity": "sha512-QLKSFeXNS8+tHW7tZpMtjlNb7HKau0QDpwm49u0vUp9y1WOF+PEzkU84y9GqYaAVW8aH8f3GcBck26jh54cX4Q==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.3.tgz", + "integrity": "sha512-4uJGhsxuptu3OcpVAzli+/gWusVGwZZHTlS63hh++ehExkVT8SgiEf7/uC/PclrPPkLhZqGgCTjd0VWLo6xMqA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@img/colour": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@img/colour/-/colour-1.1.0.tgz", + "integrity": "sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/@img/sharp-darwin-arm64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.34.5.tgz", + "integrity": "sha512-imtQ3WMJXbMY4fxb/Ndp6HBTNVtWCUI0WdobyheGf5+ad6xX8VIDO8u2xE4qc/fr08CKG/7dDseFtn6M6g/r3w==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-arm64": "1.2.4" + } + }, + "node_modules/@img/sharp-darwin-x64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.34.5.tgz", + "integrity": "sha512-YNEFAF/4KQ/PeW0N+r+aVVsoIY0/qxxikF2SWdp+NRkmMB7y9LBZAVqQ4yhGCm/H3H270OSykqmQMKLBhBJDEw==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-x64": "1.2.4" + } + }, + "node_modules/@img/sharp-libvips-darwin-arm64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.2.4.tgz", + "integrity": "sha512-zqjjo7RatFfFoP0MkQ51jfuFZBnVE2pRiaydKJ1G/rHZvnsrHAOcQALIi9sA5co5xenQdTugCvtb1cuf78Vf4g==", + "cpu": [ + "arm64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "darwin" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-darwin-x64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.2.4.tgz", + "integrity": "sha512-1IOd5xfVhlGwX+zXv2N93k0yMONvUlANylbJw1eTah8K/Jtpi15KC+WSiaX/nBmbm2HxRM1gZ0nSdjSsrZbGKg==", + "cpu": [ + "x64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "darwin" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-arm": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.2.4.tgz", + "integrity": "sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A==", + "cpu": [ + "arm" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-arm64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.2.4.tgz", + "integrity": "sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw==", + "cpu": [ + "arm64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-ppc64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-ppc64/-/sharp-libvips-linux-ppc64-1.2.4.tgz", + "integrity": "sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA==", + "cpu": [ + "ppc64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-riscv64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-riscv64/-/sharp-libvips-linux-riscv64-1.2.4.tgz", + "integrity": "sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA==", + "cpu": [ + "riscv64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-s390x": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.2.4.tgz", + "integrity": "sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ==", + "cpu": [ + "s390x" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-x64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.2.4.tgz", + "integrity": "sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw==", + "cpu": [ + "x64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linuxmusl-arm64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.2.4.tgz", + "integrity": "sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw==", + "cpu": [ + "arm64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linuxmusl-x64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.2.4.tgz", + "integrity": "sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg==", + "cpu": [ + "x64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-linux-arm": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.34.5.tgz", + "integrity": "sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw==", + "cpu": [ + "arm" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm": "1.2.4" + } + }, + "node_modules/@img/sharp-linux-arm64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.34.5.tgz", + "integrity": "sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm64": "1.2.4" + } + }, + "node_modules/@img/sharp-linux-ppc64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-ppc64/-/sharp-linux-ppc64-0.34.5.tgz", + "integrity": "sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA==", + "cpu": [ + "ppc64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-ppc64": "1.2.4" + } + }, + "node_modules/@img/sharp-linux-riscv64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-riscv64/-/sharp-linux-riscv64-0.34.5.tgz", + "integrity": "sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw==", + "cpu": [ + "riscv64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-riscv64": "1.2.4" + } + }, + "node_modules/@img/sharp-linux-s390x": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.34.5.tgz", + "integrity": "sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg==", + "cpu": [ + "s390x" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-s390x": "1.2.4" + } + }, + "node_modules/@img/sharp-linux-x64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.34.5.tgz", + "integrity": "sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-x64": "1.2.4" + } + }, + "node_modules/@img/sharp-linuxmusl-arm64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.34.5.tgz", + "integrity": "sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-arm64": "1.2.4" + } + }, + "node_modules/@img/sharp-linuxmusl-x64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.34.5.tgz", + "integrity": "sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-x64": "1.2.4" + } + }, + "node_modules/@img/sharp-wasm32": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.34.5.tgz", + "integrity": "sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw==", + "cpu": [ + "wasm32" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later AND MIT", + "optional": true, + "dependencies": { + "@emnapi/runtime": "^1.7.0" + }, + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-arm64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-arm64/-/sharp-win32-arm64-0.34.5.tgz", + "integrity": "sha512-WQ3AgWCWYSb2yt+IG8mnC6Jdk9Whs7O0gxphblsLvdhSpSTtmu69ZG1Gkb6NuvxsNACwiPV6cNSZNzt0KPsw7g==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-ia32": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.34.5.tgz", + "integrity": "sha512-FV9m/7NmeCmSHDD5j4+4pNI8Cp3aW+JvLoXcTUo0IqyjSfAZJ8dIUmijx1qaJsIiU+Hosw6xM5KijAWRJCSgNg==", + "cpu": [ + "ia32" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-x64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.34.5.tgz", + "integrity": "sha512-+29YMsqY2/9eFEiW93eqWnuLcWcufowXewwSNIT6UwZdUUCrM3oFjMWH/Z6/TMmb4hlFenmfAVbpWeup2jryCw==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "license": "MIT" + }, + "node_modules/@oslojs/encoding": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@oslojs/encoding/-/encoding-1.1.0.tgz", + "integrity": "sha512-70wQhgYmndg4GCPxPPxPGevRKqTIJ2Nh4OkiMWmDAVYsTQ+Ta7Sq+rPevXyXGdzr30/qZBnyOalCszoMxlyldQ==", + "license": "MIT" + }, + "node_modules/@rollup/pluginutils": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.3.0.tgz", + "integrity": "sha512-5EdhGZtnu3V88ces7s53hhfK5KSASnJZv8Lulpc04cWO3REESroJXg73DFsOmgbU2BhwV0E20bu2IDZb3VKW4Q==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "estree-walker": "^2.0.2", + "picomatch": "^4.0.2" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@rollup/pluginutils/node_modules/estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", + "license": "MIT" + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.59.0.tgz", + "integrity": "sha512-upnNBkA6ZH2VKGcBj9Fyl9IGNPULcjXRlg0LLeaioQWueH30p6IXtJEbKAgvyv+mJaMxSm1l6xwDXYjpEMiLMg==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.59.0.tgz", + "integrity": "sha512-hZ+Zxj3SySm4A/DylsDKZAeVg0mvi++0PYVceVyX7hemkw7OreKdCvW2oQ3T1FMZvCaQXqOTHb8qmBShoqk69Q==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.59.0.tgz", + "integrity": "sha512-W2Psnbh1J8ZJw0xKAd8zdNgF9HRLkdWwwdWqubSVk0pUuQkoHnv7rx4GiF9rT4t5DIZGAsConRE3AxCdJ4m8rg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.59.0.tgz", + "integrity": "sha512-ZW2KkwlS4lwTv7ZVsYDiARfFCnSGhzYPdiOU4IM2fDbL+QGlyAbjgSFuqNRbSthybLbIJ915UtZBtmuLrQAT/w==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.59.0.tgz", + "integrity": "sha512-EsKaJ5ytAu9jI3lonzn3BgG8iRBjV4LxZexygcQbpiU0wU0ATxhNVEpXKfUa0pS05gTcSDMKpn3Sx+QB9RlTTA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.59.0.tgz", + "integrity": "sha512-d3DuZi2KzTMjImrxoHIAODUZYoUUMsuUiY4SRRcJy6NJoZ6iIqWnJu9IScV9jXysyGMVuW+KNzZvBLOcpdl3Vg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.59.0.tgz", + "integrity": "sha512-t4ONHboXi/3E0rT6OZl1pKbl2Vgxf9vJfWgmUoCEVQVxhW6Cw/c8I6hbbu7DAvgp82RKiH7TpLwxnJeKv2pbsw==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.59.0.tgz", + "integrity": "sha512-CikFT7aYPA2ufMD086cVORBYGHffBo4K8MQ4uPS/ZnY54GKj36i196u8U+aDVT2LX4eSMbyHtyOh7D7Zvk2VvA==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.59.0.tgz", + "integrity": "sha512-jYgUGk5aLd1nUb1CtQ8E+t5JhLc9x5WdBKew9ZgAXg7DBk0ZHErLHdXM24rfX+bKrFe+Xp5YuJo54I5HFjGDAA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.59.0.tgz", + "integrity": "sha512-peZRVEdnFWZ5Bh2KeumKG9ty7aCXzzEsHShOZEFiCQlDEepP1dpUl/SrUNXNg13UmZl+gzVDPsiCwnV1uI0RUA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-gnu": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.59.0.tgz", + "integrity": "sha512-gbUSW/97f7+r4gHy3Jlup8zDG190AuodsWnNiXErp9mT90iCy9NKKU0Xwx5k8VlRAIV2uU9CsMnEFg/xXaOfXg==", + "cpu": [ + "loong64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-musl": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.59.0.tgz", + "integrity": "sha512-yTRONe79E+o0FWFijasoTjtzG9EBedFXJMl888NBEDCDV9I2wGbFFfJQQe63OijbFCUZqxpHz1GzpbtSFikJ4Q==", + "cpu": [ + "loong64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-gnu": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.59.0.tgz", + "integrity": "sha512-sw1o3tfyk12k3OEpRddF68a1unZ5VCN7zoTNtSn2KndUE+ea3m3ROOKRCZxEpmT9nsGnogpFP9x6mnLTCaoLkA==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-musl": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.59.0.tgz", + "integrity": "sha512-+2kLtQ4xT3AiIxkzFVFXfsmlZiG5FXYW7ZyIIvGA7Bdeuh9Z0aN4hVyXS/G1E9bTP/vqszNIN/pUKCk/BTHsKA==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.59.0.tgz", + "integrity": "sha512-NDYMpsXYJJaj+I7UdwIuHHNxXZ/b/N2hR15NyH3m2qAtb/hHPA4g4SuuvrdxetTdndfj9b1WOmy73kcPRoERUg==", + "cpu": [ + "riscv64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-musl": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.59.0.tgz", + "integrity": "sha512-nLckB8WOqHIf1bhymk+oHxvM9D3tyPndZH8i8+35p/1YiVoVswPid2yLzgX7ZJP0KQvnkhM4H6QZ5m0LzbyIAg==", + "cpu": [ + "riscv64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.59.0.tgz", + "integrity": "sha512-oF87Ie3uAIvORFBpwnCvUzdeYUqi2wY6jRFWJAy1qus/udHFYIkplYRW+wo+GRUP4sKzYdmE1Y3+rY5Gc4ZO+w==", + "cpu": [ + "s390x" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.59.0.tgz", + "integrity": "sha512-3AHmtQq/ppNuUspKAlvA8HtLybkDflkMuLK4DPo77DfthRb71V84/c4MlWJXixZz4uruIH4uaa07IqoAkG64fg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.59.0.tgz", + "integrity": "sha512-2UdiwS/9cTAx7qIUZB/fWtToJwvt0Vbo0zmnYt7ED35KPg13Q0ym1g442THLC7VyI6JfYTP4PiSOWyoMdV2/xg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-openbsd-x64": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.59.0.tgz", + "integrity": "sha512-M3bLRAVk6GOwFlPTIxVBSYKUaqfLrn8l0psKinkCFxl4lQvOSz8ZrKDz2gxcBwHFpci0B6rttydI4IpS4IS/jQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ] + }, + "node_modules/@rollup/rollup-openharmony-arm64": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.59.0.tgz", + "integrity": "sha512-tt9KBJqaqp5i5HUZzoafHZX8b5Q2Fe7UjYERADll83O4fGqJ49O1FsL6LpdzVFQcpwvnyd0i+K/VSwu/o/nWlA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.59.0.tgz", + "integrity": "sha512-V5B6mG7OrGTwnxaNUzZTDTjDS7F75PO1ae6MJYdiMu60sq0CqN5CVeVsbhPxalupvTX8gXVSU9gq+Rx1/hvu6A==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.59.0.tgz", + "integrity": "sha512-UKFMHPuM9R0iBegwzKF4y0C4J9u8C6MEJgFuXTBerMk7EJ92GFVFYBfOZaSGLu6COf7FxpQNqhNS4c4icUPqxA==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-gnu": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.59.0.tgz", + "integrity": "sha512-laBkYlSS1n2L8fSo1thDNGrCTQMmxjYY5G0WFWjFFYZkKPjsMBsgJfGf4TLxXrF6RyhI60L8TMOjBMvXiTcxeA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.59.0.tgz", + "integrity": "sha512-2HRCml6OztYXyJXAvdDXPKcawukWY2GpR5/nxKp4iBgiO3wcoEGkAaqctIbZcNB6KlUQBIqt8VYkNSj2397EfA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@shikijs/core": { + "version": "3.23.0", + "resolved": "https://registry.npmjs.org/@shikijs/core/-/core-3.23.0.tgz", + "integrity": "sha512-NSWQz0riNb67xthdm5br6lAkvpDJRTgB36fxlo37ZzM2yq0PQFFzbd8psqC2XMPgCzo1fW6cVi18+ArJ44wqgA==", + "license": "MIT", + "dependencies": { + "@shikijs/types": "3.23.0", + "@shikijs/vscode-textmate": "^10.0.2", + "@types/hast": "^3.0.4", + "hast-util-to-html": "^9.0.5" + } + }, + "node_modules/@shikijs/engine-javascript": { + "version": "3.23.0", + "resolved": "https://registry.npmjs.org/@shikijs/engine-javascript/-/engine-javascript-3.23.0.tgz", + "integrity": "sha512-aHt9eiGFobmWR5uqJUViySI1bHMqrAgamWE1TYSUoftkAeCCAiGawPMwM+VCadylQtF4V3VNOZ5LmfItH5f3yA==", + "license": "MIT", + "dependencies": { + "@shikijs/types": "3.23.0", + "@shikijs/vscode-textmate": "^10.0.2", + "oniguruma-to-es": "^4.3.4" + } + }, + "node_modules/@shikijs/engine-oniguruma": { + "version": "3.23.0", + "resolved": "https://registry.npmjs.org/@shikijs/engine-oniguruma/-/engine-oniguruma-3.23.0.tgz", + "integrity": "sha512-1nWINwKXxKKLqPibT5f4pAFLej9oZzQTsby8942OTlsJzOBZ0MWKiwzMsd+jhzu8YPCHAswGnnN1YtQfirL35g==", + "license": "MIT", + "dependencies": { + "@shikijs/types": "3.23.0", + "@shikijs/vscode-textmate": "^10.0.2" + } + }, + "node_modules/@shikijs/langs": { + "version": "3.23.0", + "resolved": "https://registry.npmjs.org/@shikijs/langs/-/langs-3.23.0.tgz", + "integrity": "sha512-2Ep4W3Re5aB1/62RSYQInK9mM3HsLeB91cHqznAJMuylqjzNVAVCMnNWRHFtcNHXsoNRayP9z1qj4Sq3nMqYXg==", + "license": "MIT", + "dependencies": { + "@shikijs/types": "3.23.0" + } + }, + "node_modules/@shikijs/themes": { + "version": "3.23.0", + "resolved": "https://registry.npmjs.org/@shikijs/themes/-/themes-3.23.0.tgz", + "integrity": "sha512-5qySYa1ZgAT18HR/ypENL9cUSGOeI2x+4IvYJu4JgVJdizn6kG4ia5Q1jDEOi7gTbN4RbuYtmHh0W3eccOrjMA==", + "license": "MIT", + "dependencies": { + "@shikijs/types": "3.23.0" + } + }, + "node_modules/@shikijs/types": { + "version": "3.23.0", + "resolved": "https://registry.npmjs.org/@shikijs/types/-/types-3.23.0.tgz", + "integrity": "sha512-3JZ5HXOZfYjsYSk0yPwBrkupyYSLpAE26Qc0HLghhZNGTZg/SKxXIIgoxOpmmeQP0RRSDJTk1/vPfw9tbw+jSQ==", + "license": "MIT", + "dependencies": { + "@shikijs/vscode-textmate": "^10.0.2", + "@types/hast": "^3.0.4" + } + }, + "node_modules/@shikijs/vscode-textmate": { + "version": "10.0.2", + "resolved": "https://registry.npmjs.org/@shikijs/vscode-textmate/-/vscode-textmate-10.0.2.tgz", + "integrity": "sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==", + "license": "MIT" + }, + "node_modules/@types/debug": { + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz", + "integrity": "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==", + "license": "MIT", + "dependencies": { + "@types/ms": "*" + } + }, + "node_modules/@types/estree": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", + "license": "MIT" + }, + "node_modules/@types/hast": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz", + "integrity": "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==", + "license": "MIT", + "dependencies": { + "@types/unist": "*" + } + }, + "node_modules/@types/mdast": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz", + "integrity": "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==", + "license": "MIT", + "dependencies": { + "@types/unist": "*" + } + }, + "node_modules/@types/ms": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@types/ms/-/ms-2.1.0.tgz", + "integrity": "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==", + "license": "MIT" + }, + "node_modules/@types/nlcst": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@types/nlcst/-/nlcst-2.0.3.tgz", + "integrity": "sha512-vSYNSDe6Ix3q+6Z7ri9lyWqgGhJTmzRjZRqyq15N0Z/1/UnVsno9G/N40NBijoYx2seFDIl0+B2mgAb9mezUCA==", + "license": "MIT", + "dependencies": { + "@types/unist": "*" + } + }, + "node_modules/@types/unist": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", + "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==", + "license": "MIT" + }, + "node_modules/@ungap/structured-clone": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.0.tgz", + "integrity": "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==", + "license": "ISC" + }, + "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/ansi-align": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.1.tgz", + "integrity": "sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==", + "license": "ISC", + "dependencies": { + "string-width": "^4.1.0" + } + }, + "node_modules/ansi-align/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-align/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "license": "MIT" + }, + "node_modules/ansi-align/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-align/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-regex": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/ansi-styles": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "license": "ISC", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/anymatch/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "license": "Python-2.0" + }, + "node_modules/aria-query": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.2.tgz", + "integrity": "sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==", + "license": "Apache-2.0", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/array-iterate": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/array-iterate/-/array-iterate-2.0.1.tgz", + "integrity": "sha512-I1jXZMjAgCMmxT4qxXfPXa6SthSoE8h6gkSI9BGGNv8mP8G/v0blc+qFnZu6K42vTOiuME596QaLO0TP3Lk0xg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/astro": { + "version": "5.18.0", + "resolved": "https://registry.npmjs.org/astro/-/astro-5.18.0.tgz", + "integrity": "sha512-CHiohwJIS4L0G6/IzE1Fx3dgWqXBCXus/od0eGUfxrZJD2um2pE7ehclMmgL/fXqbU7NfE1Ze2pq34h2QaA6iQ==", + "license": "MIT", + "dependencies": { + "@astrojs/compiler": "^2.13.0", + "@astrojs/internal-helpers": "0.7.5", + "@astrojs/markdown-remark": "6.3.10", + "@astrojs/telemetry": "3.3.0", + "@capsizecss/unpack": "^4.0.0", + "@oslojs/encoding": "^1.1.0", + "@rollup/pluginutils": "^5.3.0", + "acorn": "^8.15.0", + "aria-query": "^5.3.2", + "axobject-query": "^4.1.0", + "boxen": "8.0.1", + "ci-info": "^4.3.1", + "clsx": "^2.1.1", + "common-ancestor-path": "^1.0.1", + "cookie": "^1.1.1", + "cssesc": "^3.0.0", + "debug": "^4.4.3", + "deterministic-object-hash": "^2.0.2", + "devalue": "^5.6.2", + "diff": "^8.0.3", + "dlv": "^1.1.3", + "dset": "^3.1.4", + "es-module-lexer": "^1.7.0", + "esbuild": "^0.27.3", + "estree-walker": "^3.0.3", + "flattie": "^1.1.1", + "fontace": "~0.4.0", + "github-slugger": "^2.0.0", + "html-escaper": "3.0.3", + "http-cache-semantics": "^4.2.0", + "import-meta-resolve": "^4.2.0", + "js-yaml": "^4.1.1", + "magic-string": "^0.30.21", + "magicast": "^0.5.1", + "mrmime": "^2.0.1", + "neotraverse": "^0.6.18", + "p-limit": "^6.2.0", + "p-queue": "^8.1.1", + "package-manager-detector": "^1.6.0", + "piccolore": "^0.1.3", + "picomatch": "^4.0.3", + "prompts": "^2.4.2", + "rehype": "^13.0.2", + "semver": "^7.7.3", + "shiki": "^3.21.0", + "smol-toml": "^1.6.0", + "svgo": "^4.0.0", + "tinyexec": "^1.0.2", + "tinyglobby": "^0.2.15", + "tsconfck": "^3.1.6", + "ultrahtml": "^1.6.0", + "unifont": "~0.7.3", + "unist-util-visit": "^5.0.0", + "unstorage": "^1.17.4", + "vfile": "^6.0.3", + "vite": "^6.4.1", + "vitefu": "^1.1.1", + "xxhash-wasm": "^1.1.0", + "yargs-parser": "^21.1.1", + "yocto-spinner": "^0.2.3", + "zod": "^3.25.76", + "zod-to-json-schema": "^3.25.1", + "zod-to-ts": "^1.2.0" + }, + "bin": { + "astro": "astro.js" + }, + "engines": { + "node": "18.20.8 || ^20.3.0 || >=22.0.0", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/astrodotbuild" + }, + "optionalDependencies": { + "sharp": "^0.34.0" + } + }, + "node_modules/axobject-query": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.1.0.tgz", + "integrity": "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==", + "license": "Apache-2.0", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/bail": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.2.tgz", + "integrity": "sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/base-64": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/base-64/-/base-64-1.0.0.tgz", + "integrity": "sha512-kwDPIFCGx0NZHog36dj+tHiwP4QMzsZ3AgMViUBKI0+V5n4U0ufTCUMhnQ04diaRI8EX/QcPfql7zlhZ7j4zgg==", + "license": "MIT" + }, + "node_modules/boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", + "license": "ISC" + }, + "node_modules/boxen": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/boxen/-/boxen-8.0.1.tgz", + "integrity": "sha512-F3PH5k5juxom4xktynS7MoFY+NUWH5LC4CnH11YB8NPew+HLpmBLCybSAEyb2F+4pRXhuhWqFesoQd6DAyc2hw==", + "license": "MIT", + "dependencies": { + "ansi-align": "^3.0.1", + "camelcase": "^8.0.0", + "chalk": "^5.3.0", + "cli-boxes": "^3.0.0", + "string-width": "^7.2.0", + "type-fest": "^4.21.0", + "widest-line": "^5.0.0", + "wrap-ansi": "^9.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/camelcase": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-8.0.0.tgz", + "integrity": "sha512-8WB3Jcas3swSvjIeA2yvCJ+Miyz5l1ZmB6HFb9R1317dt9LCQoswg/BGrmAmkWVEszSrrg4RwmO46qIm2OEnSA==", + "license": "MIT", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ccount": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/ccount/-/ccount-2.0.1.tgz", + "integrity": "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/chalk": { + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz", + "integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==", + "license": "MIT", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/character-entities": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-2.0.2.tgz", + "integrity": "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-entities-html4": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/character-entities-html4/-/character-entities-html4-2.1.0.tgz", + "integrity": "sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-entities-legacy": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-3.0.0.tgz", + "integrity": "sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "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/ci-info": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.4.0.tgz", + "integrity": "sha512-77PSwercCZU2Fc4sX94eF8k8Pxte6JAwL4/ICZLFjJLqegs7kCuAsqqj/70NQF6TvDpgFjkubQB2FW2ZZddvQg==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/cli-boxes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-3.0.0.tgz", + "integrity": "sha512-/lzGpEWL/8PfI0BmBOPRwp0c/wFNX1RdUML3jK/RcSBA9T8mZDdQpqYBKtCFTOfQbwPqWEOpjqW+Fnayc0969g==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/clsx": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", + "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/comma-separated-tokens": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz", + "integrity": "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/commander": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-11.1.0.tgz", + "integrity": "sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==", + "license": "MIT", + "engines": { + "node": ">=16" + } + }, + "node_modules/common-ancestor-path": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/common-ancestor-path/-/common-ancestor-path-1.0.1.tgz", + "integrity": "sha512-L3sHRo1pXXEqX8VU28kfgUY+YGsk09hPqZiZmLacNib6XNTCM8ubYeT7ryXQw8asB1sKgcU5lkB7ONug08aB8w==", + "license": "ISC" + }, + "node_modules/cookie": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-1.1.1.tgz", + "integrity": "sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/cookie-es": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/cookie-es/-/cookie-es-1.2.2.tgz", + "integrity": "sha512-+W7VmiVINB+ywl1HGXJXmrqkOhpKrIiVZV6tQuV54ZyQC7MMuBt81Vc336GMLoHBq5hV/F9eXgt5Mnx0Rha5Fg==", + "license": "MIT" + }, + "node_modules/crossws": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/crossws/-/crossws-0.3.5.tgz", + "integrity": "sha512-ojKiDvcmByhwa8YYqbQI/hg7MEU0NC03+pSdEq4ZUnZR9xXpwk7E43SMNGkn+JxJGPFtNvQ48+vV2p+P1ml5PA==", + "license": "MIT", + "dependencies": { + "uncrypto": "^0.1.3" + } + }, + "node_modules/css-select": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.2.2.tgz", + "integrity": "sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw==", + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0", + "css-what": "^6.1.0", + "domhandler": "^5.0.2", + "domutils": "^3.0.1", + "nth-check": "^2.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/css-tree": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-3.2.1.tgz", + "integrity": "sha512-X7sjQzceUhu1u7Y/ylrRZFU2FS6LRiFVp6rKLPg23y3x3c3DOKAwuXGDp+PAGjh6CSnCjYeAul8pcT8bAl+lSA==", + "license": "MIT", + "dependencies": { + "mdn-data": "2.27.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0" + } + }, + "node_modules/css-what": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.2.2.tgz", + "integrity": "sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==", + "license": "BSD-2-Clause", + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "license": "MIT", + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/csso": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/csso/-/csso-5.0.5.tgz", + "integrity": "sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==", + "license": "MIT", + "dependencies": { + "css-tree": "~2.2.0" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0", + "npm": ">=7.0.0" + } + }, + "node_modules/csso/node_modules/css-tree": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.2.1.tgz", + "integrity": "sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA==", + "license": "MIT", + "dependencies": { + "mdn-data": "2.0.28", + "source-map-js": "^1.0.1" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0", + "npm": ">=7.0.0" + } + }, + "node_modules/csso/node_modules/mdn-data": { + "version": "2.0.28", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.28.tgz", + "integrity": "sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==", + "license": "CC0-1.0" + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decode-named-character-reference": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.3.0.tgz", + "integrity": "sha512-GtpQYB283KrPp6nRw50q3U9/VfOutZOe103qlN7BPP6Ad27xYnOIWv4lPzo8HCAL+mMZofJ9KEy30fq6MfaK6Q==", + "license": "MIT", + "dependencies": { + "character-entities": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/defu": { + "version": "6.1.4", + "resolved": "https://registry.npmjs.org/defu/-/defu-6.1.4.tgz", + "integrity": "sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==", + "license": "MIT" + }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/dequal": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/destr": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/destr/-/destr-2.0.5.tgz", + "integrity": "sha512-ugFTXCtDZunbzasqBxrK93Ik/DRYsO6S/fedkWEMKqt04xZ4csmnmwGDBAb07QWNaGMAmnTIemsYZCksjATwsA==", + "license": "MIT" + }, + "node_modules/detect-libc": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", + "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", + "license": "Apache-2.0", + "optional": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/deterministic-object-hash": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/deterministic-object-hash/-/deterministic-object-hash-2.0.2.tgz", + "integrity": "sha512-KxektNH63SrbfUyDiwXqRb1rLwKt33AmMv+5Nhsw1kqZ13SJBRTgZHtGbE+hH3a1mVW1cz+4pqSWVPAtLVXTzQ==", + "license": "MIT", + "dependencies": { + "base-64": "^1.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/devalue": { + "version": "5.6.3", + "resolved": "https://registry.npmjs.org/devalue/-/devalue-5.6.3.tgz", + "integrity": "sha512-nc7XjUU/2Lb+SvEFVGcWLiKkzfw8+qHI7zn8WYXKkLMgfGSHbgCEaR6bJpev8Cm6Rmrb19Gfd/tZvGqx9is3wg==", + "license": "MIT" + }, + "node_modules/devlop": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/devlop/-/devlop-1.1.0.tgz", + "integrity": "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==", + "license": "MIT", + "dependencies": { + "dequal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/diff": { + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/diff/-/diff-8.0.3.tgz", + "integrity": "sha512-qejHi7bcSD4hQAZE0tNAawRK1ZtafHDmMTMkrrIGgSLl7hTnQHmKCeB45xAcbfTqK2zowkM3j3bHt/4b/ARbYQ==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/dlv": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", + "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==", + "license": "MIT" + }, + "node_modules/dom-serializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", + "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", + "license": "MIT", + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.2", + "entities": "^4.2.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/dom-serializer/node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/domelementtype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "BSD-2-Clause" + }, + "node_modules/domhandler": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", + "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", + "license": "BSD-2-Clause", + "dependencies": { + "domelementtype": "^2.3.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/domutils": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.2.2.tgz", + "integrity": "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==", + "license": "BSD-2-Clause", + "dependencies": { + "dom-serializer": "^2.0.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, + "node_modules/dset": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/dset/-/dset-3.1.4.tgz", + "integrity": "sha512-2QF/g9/zTaPDc3BjNcVTGoBbXBgYfMTTceLaYcFJ/W9kggFUkhxD/hMEeuLKbugyef9SqAx8cpgwlIP/jinUTA==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", + "license": "MIT" + }, + "node_modules/emoji-regex": { + "version": "10.6.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz", + "integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==", + "license": "MIT" + }, + "node_modules/encodeurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/entities": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz", + "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/es-module-lexer": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.7.0.tgz", + "integrity": "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==", + "license": "MIT" + }, + "node_modules/esbuild": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.3.tgz", + "integrity": "sha512-8VwMnyGCONIs6cWue2IdpHxHnAjzxnw2Zr7MkVxB2vjmQ2ivqGFb4LEG3SMnv0Gb2F/G/2yA8zUaiL1gywDCCg==", + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.27.3", + "@esbuild/android-arm": "0.27.3", + "@esbuild/android-arm64": "0.27.3", + "@esbuild/android-x64": "0.27.3", + "@esbuild/darwin-arm64": "0.27.3", + "@esbuild/darwin-x64": "0.27.3", + "@esbuild/freebsd-arm64": "0.27.3", + "@esbuild/freebsd-x64": "0.27.3", + "@esbuild/linux-arm": "0.27.3", + "@esbuild/linux-arm64": "0.27.3", + "@esbuild/linux-ia32": "0.27.3", + "@esbuild/linux-loong64": "0.27.3", + "@esbuild/linux-mips64el": "0.27.3", + "@esbuild/linux-ppc64": "0.27.3", + "@esbuild/linux-riscv64": "0.27.3", + "@esbuild/linux-s390x": "0.27.3", + "@esbuild/linux-x64": "0.27.3", + "@esbuild/netbsd-arm64": "0.27.3", + "@esbuild/netbsd-x64": "0.27.3", + "@esbuild/openbsd-arm64": "0.27.3", + "@esbuild/openbsd-x64": "0.27.3", + "@esbuild/openharmony-arm64": "0.27.3", + "@esbuild/sunos-x64": "0.27.3", + "@esbuild/win32-arm64": "0.27.3", + "@esbuild/win32-ia32": "0.27.3", + "@esbuild/win32-x64": "0.27.3" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", + "license": "MIT" + }, + "node_modules/escape-string-regexp": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", + "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0" + } + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/eventemitter3": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.4.tgz", + "integrity": "sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw==", + "license": "MIT" + }, + "node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "license": "MIT" + }, + "node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/flattie": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/flattie/-/flattie-1.1.1.tgz", + "integrity": "sha512-9UbaD6XdAL97+k/n+N7JwX46K/M6Zc6KcFYskrYL8wbBV/Uyk0CTAMY0VT+qiK5PM7AIc9aTWYtq65U7T+aCNQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/fontace": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/fontace/-/fontace-0.4.1.tgz", + "integrity": "sha512-lDMvbAzSnHmbYMTEld5qdtvNH2/pWpICOqpean9IgC7vUbUJc3k+k5Dokp85CegamqQpFbXf0rAVkbzpyTA8aw==", + "license": "MIT", + "dependencies": { + "fontkitten": "^1.0.2" + } + }, + "node_modules/fontkitten": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/fontkitten/-/fontkitten-1.0.3.tgz", + "integrity": "sha512-Wp1zXWPVUPBmfoa3Cqc9ctaKuzKAV6uLstRqlR56kSjplf5uAce+qeyYym7F+PHbGTk+tCEdkCW6RD7DX/gBZw==", + "license": "MIT", + "dependencies": { + "tiny-inflate": "^1.0.3" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/fresh": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-2.0.0.tgz", + "integrity": "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/get-east-asian-width": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.5.0.tgz", + "integrity": "sha512-CQ+bEO+Tva/qlmw24dCejulK5pMzVnUOFOijVogd3KQs07HnRIgp8TGipvCCRT06xeYEbpbgwaCxglFyiuIcmA==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/github-slugger": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/github-slugger/-/github-slugger-2.0.0.tgz", + "integrity": "sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw==", + "license": "ISC" + }, + "node_modules/h3": { + "version": "1.15.6", + "resolved": "https://registry.npmjs.org/h3/-/h3-1.15.6.tgz", + "integrity": "sha512-oi15ESLW5LRthZ+qPCi5GNasY/gvynSKUQxgiovrY63bPAtG59wtM+LSrlcwvOHAXzGrXVLnI97brbkdPF9WoQ==", + "license": "MIT", + "dependencies": { + "cookie-es": "^1.2.2", + "crossws": "^0.3.5", + "defu": "^6.1.4", + "destr": "^2.0.5", + "iron-webcrypto": "^1.2.1", + "node-mock-http": "^1.0.4", + "radix3": "^1.1.2", + "ufo": "^1.6.3", + "uncrypto": "^0.1.3" + } + }, + "node_modules/hast-util-from-html": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/hast-util-from-html/-/hast-util-from-html-2.0.3.tgz", + "integrity": "sha512-CUSRHXyKjzHov8yKsQjGOElXy/3EKpyX56ELnkHH34vDVw1N1XSQ1ZcAvTyAPtGqLTuKP/uxM+aLkSPqF/EtMw==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "devlop": "^1.1.0", + "hast-util-from-parse5": "^8.0.0", + "parse5": "^7.0.0", + "vfile": "^6.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-from-parse5": { + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/hast-util-from-parse5/-/hast-util-from-parse5-8.0.3.tgz", + "integrity": "sha512-3kxEVkEKt0zvcZ3hCRYI8rqrgwtlIOFMWkbclACvjlDw8Li9S2hk/d51OI0nr/gIpdMHNepwgOKqZ/sy0Clpyg==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "devlop": "^1.0.0", + "hastscript": "^9.0.0", + "property-information": "^7.0.0", + "vfile": "^6.0.0", + "vfile-location": "^5.0.0", + "web-namespaces": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-is-element": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/hast-util-is-element/-/hast-util-is-element-3.0.0.tgz", + "integrity": "sha512-Val9mnv2IWpLbNPqc/pUem+a7Ipj2aHacCwgNfTiK0vJKl0LF+4Ba4+v1oPHFpf3bLYmreq0/l3Gud9S5OH42g==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-parse-selector": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-4.0.0.tgz", + "integrity": "sha512-wkQCkSYoOGCRKERFWcxMVMOcYE2K1AaNLU8DXS9arxnLOUEWbOXKXiJUNzEpqZ3JOKpnha3jkFrumEjVliDe7A==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-raw": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/hast-util-raw/-/hast-util-raw-9.1.0.tgz", + "integrity": "sha512-Y8/SBAHkZGoNkpzqqfCldijcuUKh7/su31kEBp67cFY09Wy0mTRgtsLYsiIxMJxlu0f6AA5SUTbDR8K0rxnbUw==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "@ungap/structured-clone": "^1.0.0", + "hast-util-from-parse5": "^8.0.0", + "hast-util-to-parse5": "^8.0.0", + "html-void-elements": "^3.0.0", + "mdast-util-to-hast": "^13.0.0", + "parse5": "^7.0.0", + "unist-util-position": "^5.0.0", + "unist-util-visit": "^5.0.0", + "vfile": "^6.0.0", + "web-namespaces": "^2.0.0", + "zwitch": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-to-html": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/hast-util-to-html/-/hast-util-to-html-9.0.5.tgz", + "integrity": "sha512-OguPdidb+fbHQSU4Q4ZiLKnzWo8Wwsf5bZfbvu7//a9oTYoqD/fWpe96NuHkoS9h0ccGOTe0C4NGXdtS0iObOw==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "ccount": "^2.0.0", + "comma-separated-tokens": "^2.0.0", + "hast-util-whitespace": "^3.0.0", + "html-void-elements": "^3.0.0", + "mdast-util-to-hast": "^13.0.0", + "property-information": "^7.0.0", + "space-separated-tokens": "^2.0.0", + "stringify-entities": "^4.0.0", + "zwitch": "^2.0.4" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-to-parse5": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/hast-util-to-parse5/-/hast-util-to-parse5-8.0.1.tgz", + "integrity": "sha512-MlWT6Pjt4CG9lFCjiz4BH7l9wmrMkfkJYCxFwKQic8+RTZgWPuWxwAfjJElsXkex7DJjfSJsQIt931ilUgmwdA==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "comma-separated-tokens": "^2.0.0", + "devlop": "^1.0.0", + "property-information": "^7.0.0", + "space-separated-tokens": "^2.0.0", + "web-namespaces": "^2.0.0", + "zwitch": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-to-text": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/hast-util-to-text/-/hast-util-to-text-4.0.2.tgz", + "integrity": "sha512-KK6y/BN8lbaq654j7JgBydev7wuNMcID54lkRav1P0CaE1e47P72AWWPiGKXTJU271ooYzcvTAn/Zt0REnvc7A==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "hast-util-is-element": "^3.0.0", + "unist-util-find-after": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-whitespace": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-3.0.0.tgz", + "integrity": "sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hastscript": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-9.0.1.tgz", + "integrity": "sha512-g7df9rMFX/SPi34tyGCyUBREQoKkapwdY/T04Qn9TDWfHhAYt4/I0gMVirzK5wEzeUqIjEB+LXC/ypb7Aqno5w==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "comma-separated-tokens": "^2.0.0", + "hast-util-parse-selector": "^4.0.0", + "property-information": "^7.0.0", + "space-separated-tokens": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/html-escaper": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-3.0.3.tgz", + "integrity": "sha512-RuMffC89BOWQoY0WKGpIhn5gX3iI54O6nRA0yC124NYVtzjmFWBIiFd8M0x+ZdX0P9R4lADg1mgP8C7PxGOWuQ==", + "license": "MIT" + }, + "node_modules/html-void-elements": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/html-void-elements/-/html-void-elements-3.0.0.tgz", + "integrity": "sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/http-cache-semantics": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.2.0.tgz", + "integrity": "sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ==", + "license": "BSD-2-Clause" + }, + "node_modules/http-errors": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz", + "integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==", + "license": "MIT", + "dependencies": { + "depd": "~2.0.0", + "inherits": "~2.0.4", + "setprototypeof": "~1.2.0", + "statuses": "~2.0.2", + "toidentifier": "~1.0.1" + }, + "engines": { + "node": ">= 0.8" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/import-meta-resolve": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/import-meta-resolve/-/import-meta-resolve-4.2.0.tgz", + "integrity": "sha512-Iqv2fzaTQN28s/FwZAoFq0ZSs/7hMAHJVX+w8PZl3cY19Pxk6jFFalxQoIfW2826i/fDLXv8IiEZRIT0lDuWcg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "license": "ISC" + }, + "node_modules/iron-webcrypto": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/iron-webcrypto/-/iron-webcrypto-1.2.1.tgz", + "integrity": "sha512-feOM6FaSr6rEABp/eDfVseKyTMDt+KGpeB35SkVn9Tyn0CqvVsY3EwI0v5i8nMHyJnzCIQf7nsy3p41TPkJZhg==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/brc-dd" + } + }, + "node_modules/is-docker": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz", + "integrity": "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==", + "license": "MIT", + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-inside-container": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-inside-container/-/is-inside-container-1.0.0.tgz", + "integrity": "sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==", + "license": "MIT", + "dependencies": { + "is-docker": "^3.0.0" + }, + "bin": { + "is-inside-container": "cli.js" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-plain-obj": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", + "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-wsl": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-3.1.1.tgz", + "integrity": "sha512-e6rvdUCiQCAuumZslxRJWR/Doq4VpPR82kqclvcS0efgt430SlGIk05vdCN58+VrzgtIcfNODjozVielycD4Sw==", + "license": "MIT", + "dependencies": { + "is-inside-container": "^1.0.0" + }, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/js-yaml": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", + "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/longest-streak": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-3.1.0.tgz", + "integrity": "sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/lru-cache": { + "version": "11.2.6", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.6.tgz", + "integrity": "sha512-ESL2CrkS/2wTPfuend7Zhkzo2u0daGJ/A2VucJOgQ/C48S/zB8MMeMHSGKYpXhIjbPxfuezITkaBH1wqv00DDQ==", + "license": "BlueOak-1.0.0", + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/magic-string": { + "version": "0.30.21", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", + "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==", + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.5" + } + }, + "node_modules/magicast": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/magicast/-/magicast-0.5.2.tgz", + "integrity": "sha512-E3ZJh4J3S9KfwdjZhe2afj6R9lGIN5Pher1pF39UGrXRqq/VDaGVIGN13BjHd2u8B61hArAGOnso7nBOouW3TQ==", + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.29.0", + "@babel/types": "^7.29.0", + "source-map-js": "^1.2.1" + } + }, + "node_modules/markdown-table": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-3.0.4.tgz", + "integrity": "sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/mdast-util-definitions": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-definitions/-/mdast-util-definitions-6.0.0.tgz", + "integrity": "sha512-scTllyX6pnYNZH/AIp/0ePz6s4cZtARxImwoPJ7kS42n+MnVsI4XbnG6d4ibehRIldYMWM2LD7ImQblVhUejVQ==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "unist-util-visit": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-find-and-replace": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/mdast-util-find-and-replace/-/mdast-util-find-and-replace-3.0.2.tgz", + "integrity": "sha512-Tmd1Vg/m3Xz43afeNxDIhWRtFZgM2VLyaf4vSTYwudTyeuTneoL3qtWMA5jeLyz/O1vDJmmV4QuScFCA2tBPwg==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "escape-string-regexp": "^5.0.0", + "unist-util-is": "^6.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-from-markdown": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-2.0.3.tgz", + "integrity": "sha512-W4mAWTvSlKvf8L6J+VN9yLSqQ9AOAAvHuoDAmPkz4dHf553m5gVj2ejadHJhoJmcmxEnOv6Pa8XJhpxE93kb8Q==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "mdast-util-to-string": "^4.0.0", + "micromark": "^4.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-decode-string": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "unist-util-stringify-position": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm/-/mdast-util-gfm-3.1.0.tgz", + "integrity": "sha512-0ulfdQOM3ysHhCJ1p06l0b0VKlhU0wuQs3thxZQagjcjPrlFRqY215uZGHHJan9GEAXd9MbfPjFJz+qMkVR6zQ==", + "license": "MIT", + "dependencies": { + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-gfm-autolink-literal": "^2.0.0", + "mdast-util-gfm-footnote": "^2.0.0", + "mdast-util-gfm-strikethrough": "^2.0.0", + "mdast-util-gfm-table": "^2.0.0", + "mdast-util-gfm-task-list-item": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-autolink-literal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-autolink-literal/-/mdast-util-gfm-autolink-literal-2.0.1.tgz", + "integrity": "sha512-5HVP2MKaP6L+G6YaxPNjuL0BPrq9orG3TsrZ9YXbA3vDw/ACI4MEsnoDpn6ZNm7GnZgtAcONJyPhOP8tNJQavQ==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "ccount": "^2.0.0", + "devlop": "^1.0.0", + "mdast-util-find-and-replace": "^3.0.0", + "micromark-util-character": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-footnote": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-footnote/-/mdast-util-gfm-footnote-2.1.0.tgz", + "integrity": "sha512-sqpDWlsHn7Ac9GNZQMeUzPQSMzR6Wv0WKRNvQRg0KqHh02fpTz69Qc1QSseNX29bhz1ROIyNyxExfawVKTm1GQ==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.1.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-strikethrough": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-strikethrough/-/mdast-util-gfm-strikethrough-2.0.0.tgz", + "integrity": "sha512-mKKb915TF+OC5ptj5bJ7WFRPdYtuHv0yTRxK2tJvi+BDqbkiG7h7u/9SI89nRAYcmap2xHQL9D+QG/6wSrTtXg==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-table": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-table/-/mdast-util-gfm-table-2.0.0.tgz", + "integrity": "sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "markdown-table": "^3.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-task-list-item": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-task-list-item/-/mdast-util-gfm-task-list-item-2.0.0.tgz", + "integrity": "sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-phrasing": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-phrasing/-/mdast-util-phrasing-4.1.0.tgz", + "integrity": "sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "unist-util-is": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-hast": { + "version": "13.2.1", + "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-13.2.1.tgz", + "integrity": "sha512-cctsq2wp5vTsLIcaymblUriiTcZd0CwWtCbLvrOzYCDZoWyMNV8sZ7krj09FSnsiJi3WVsHLM4k6Dq/yaPyCXA==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "@ungap/structured-clone": "^1.0.0", + "devlop": "^1.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "trim-lines": "^3.0.0", + "unist-util-position": "^5.0.0", + "unist-util-visit": "^5.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-markdown": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-2.1.2.tgz", + "integrity": "sha512-xj68wMTvGXVOKonmog6LwyJKrYXZPvlwabaryTjLh9LuvovB/KAH+kvi8Gjj+7rJjsFi23nkUxRQv1KqSroMqA==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "longest-streak": "^3.0.0", + "mdast-util-phrasing": "^4.0.0", + "mdast-util-to-string": "^4.0.0", + "micromark-util-classify-character": "^2.0.0", + "micromark-util-decode-string": "^2.0.0", + "unist-util-visit": "^5.0.0", + "zwitch": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-4.0.0.tgz", + "integrity": "sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdn-data": { + "version": "2.27.1", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.27.1.tgz", + "integrity": "sha512-9Yubnt3e8A0OKwxYSXyhLymGW4sCufcLG6VdiDdUGVkPhpqLxlvP5vl1983gQjJl3tqbrM731mjaZaP68AgosQ==", + "license": "CC0-1.0" + }, + "node_modules/micromark": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/micromark/-/micromark-4.0.2.tgz", + "integrity": "sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "@types/debug": "^4.0.0", + "debug": "^4.0.0", + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "micromark-core-commonmark": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-combine-extensions": "^2.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-encode": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-subtokenize": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-core-commonmark": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-2.0.3.tgz", + "integrity": "sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "micromark-factory-destination": "^2.0.0", + "micromark-factory-label": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-factory-title": "^2.0.0", + "micromark-factory-whitespace": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-classify-character": "^2.0.0", + "micromark-util-html-tag-name": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-subtokenize": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-gfm": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm/-/micromark-extension-gfm-3.0.0.tgz", + "integrity": "sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w==", + "license": "MIT", + "dependencies": { + "micromark-extension-gfm-autolink-literal": "^2.0.0", + "micromark-extension-gfm-footnote": "^2.0.0", + "micromark-extension-gfm-strikethrough": "^2.0.0", + "micromark-extension-gfm-table": "^2.0.0", + "micromark-extension-gfm-tagfilter": "^2.0.0", + "micromark-extension-gfm-task-list-item": "^2.0.0", + "micromark-util-combine-extensions": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-autolink-literal": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-autolink-literal/-/micromark-extension-gfm-autolink-literal-2.1.0.tgz", + "integrity": "sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw==", + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-footnote": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-footnote/-/micromark-extension-gfm-footnote-2.1.0.tgz", + "integrity": "sha512-/yPhxI1ntnDNsiHtzLKYnE3vf9JZ6cAisqVDauhp4CEHxlb4uoOTxOCJ+9s51bIB8U1N1FJ1RXOKTIlD5B/gqw==", + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-core-commonmark": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-strikethrough": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-strikethrough/-/micromark-extension-gfm-strikethrough-2.1.0.tgz", + "integrity": "sha512-ADVjpOOkjz1hhkZLlBiYA9cR2Anf8F4HqZUO6e5eDcPQd0Txw5fxLzzxnEkSkfnD0wziSGiv7sYhk/ktvbf1uw==", + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-classify-character": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-table": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-table/-/micromark-extension-gfm-table-2.1.1.tgz", + "integrity": "sha512-t2OU/dXXioARrC6yWfJ4hqB7rct14e8f7m0cbI5hUmDyyIlwv5vEtooptH8INkbLzOatzKuVbQmAYcbWoyz6Dg==", + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-tagfilter": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-tagfilter/-/micromark-extension-gfm-tagfilter-2.0.0.tgz", + "integrity": "sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg==", + "license": "MIT", + "dependencies": { + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-task-list-item": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-task-list-item/-/micromark-extension-gfm-task-list-item-2.1.0.tgz", + "integrity": "sha512-qIBZhqxqI6fjLDYFTBIa4eivDMnP+OZqsNwmQ3xNLE4Cxwc+zfQEfbs6tzAo2Hjq+bh6q5F+Z8/cksrLFYWQQw==", + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-factory-destination": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-2.0.1.tgz", + "integrity": "sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-label": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-2.0.1.tgz", + "integrity": "sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-space": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz", + "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-title": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-2.0.1.tgz", + "integrity": "sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-whitespace": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-2.0.1.tgz", + "integrity": "sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-character": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", + "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-chunked": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-2.0.1.tgz", + "integrity": "sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-classify-character": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-2.0.1.tgz", + "integrity": "sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-combine-extensions": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-2.0.1.tgz", + "integrity": "sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-chunked": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-decode-numeric-character-reference": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-2.0.2.tgz", + "integrity": "sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-decode-string": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-2.0.1.tgz", + "integrity": "sha512-nDV/77Fj6eH1ynwscYTOsbK7rR//Uj0bZXBwJZRfaLEJ1iGBR6kIfNmlNqaqJf649EP0F3NWNdeJi03elllNUQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "decode-named-character-reference": "^1.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-encode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.1.tgz", + "integrity": "sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-html-tag-name": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-2.0.1.tgz", + "integrity": "sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-normalize-identifier": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-2.0.1.tgz", + "integrity": "sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-resolve-all": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-2.0.1.tgz", + "integrity": "sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-sanitize-uri": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.1.tgz", + "integrity": "sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-encode": "^2.0.0", + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-subtokenize": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-2.1.0.tgz", + "integrity": "sha512-XQLu552iSctvnEcgXw6+Sx75GflAPNED1qx7eBJ+wydBb2KCbRZe+NwvIEEMM83uml1+2WSXpBAcp9IUCgCYWA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-symbol": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-types": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.2.tgz", + "integrity": "sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/mime-db": { + "version": "1.54.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", + "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.2.tgz", + "integrity": "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==", + "license": "MIT", + "dependencies": { + "mime-db": "^1.54.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/mrmime": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.1.tgz", + "integrity": "sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==", + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, + "node_modules/nanoid": { + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", + "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/neotraverse": { + "version": "0.6.18", + "resolved": "https://registry.npmjs.org/neotraverse/-/neotraverse-0.6.18.tgz", + "integrity": "sha512-Z4SmBUweYa09+o6pG+eASabEpP6QkQ70yHj351pQoEXIs8uHbaU2DWVmzBANKgflPa47A50PtB2+NgRpQvr7vA==", + "license": "MIT", + "engines": { + "node": ">= 10" + } + }, + "node_modules/nlcst-to-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/nlcst-to-string/-/nlcst-to-string-4.0.0.tgz", + "integrity": "sha512-YKLBCcUYKAg0FNlOBT6aI91qFmSiFKiluk655WzPF+DDMA02qIyy8uiRqI8QXtcFpEvll12LpL5MXqEmAZ+dcA==", + "license": "MIT", + "dependencies": { + "@types/nlcst": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/node-fetch-native": { + "version": "1.6.7", + "resolved": "https://registry.npmjs.org/node-fetch-native/-/node-fetch-native-1.6.7.tgz", + "integrity": "sha512-g9yhqoedzIUm0nTnTqAQvueMPVOuIY16bqgAJJC8XOOubYFNwz6IER9qs0Gq2Xd0+CecCKFjtdDTMA4u4xG06Q==", + "license": "MIT" + }, + "node_modules/node-mock-http": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/node-mock-http/-/node-mock-http-1.0.4.tgz", + "integrity": "sha512-8DY+kFsDkNXy1sJglUfuODx1/opAGJGyrTuFqEoN90oRc2Vk0ZbD4K2qmKXBBEhZQzdKHIVfEJpDU8Ak2NJEvQ==", + "license": "MIT" + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/nth-check": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", + "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0" + }, + "funding": { + "url": "https://github.com/fb55/nth-check?sponsor=1" + } + }, + "node_modules/ofetch": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/ofetch/-/ofetch-1.5.1.tgz", + "integrity": "sha512-2W4oUZlVaqAPAil6FUg/difl6YhqhUR7x2eZY4bQCko22UXg3hptq9KLQdqFClV+Wu85UX7hNtdGTngi/1BxcA==", + "license": "MIT", + "dependencies": { + "destr": "^2.0.5", + "node-fetch-native": "^1.6.7", + "ufo": "^1.6.1" + } + }, + "node_modules/ohash": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/ohash/-/ohash-2.0.11.tgz", + "integrity": "sha512-RdR9FQrFwNBNXAr4GixM8YaRZRJ5PUWbKYbE5eOsrwAjJW0q2REGcf79oYPsLyskQCZG1PLN+S/K1V00joZAoQ==", + "license": "MIT" + }, + "node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "license": "MIT", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/oniguruma-parser": { + "version": "0.12.1", + "resolved": "https://registry.npmjs.org/oniguruma-parser/-/oniguruma-parser-0.12.1.tgz", + "integrity": "sha512-8Unqkvk1RYc6yq2WBYRj4hdnsAxVze8i7iPfQr8e4uSP3tRv0rpZcbGUDvxfQQcdwHt/e9PrMvGCsa8OqG9X3w==", + "license": "MIT" + }, + "node_modules/oniguruma-to-es": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/oniguruma-to-es/-/oniguruma-to-es-4.3.4.tgz", + "integrity": "sha512-3VhUGN3w2eYxnTzHn+ikMI+fp/96KoRSVK9/kMTcFqj1NRDh2IhQCKvYxDnWePKRXY/AqH+Fuiyb7VHSzBjHfA==", + "license": "MIT", + "dependencies": { + "oniguruma-parser": "^0.12.1", + "regex": "^6.0.1", + "regex-recursion": "^6.0.2" + } + }, + "node_modules/p-limit": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-6.2.0.tgz", + "integrity": "sha512-kuUqqHNUqoIWp/c467RI4X6mmyuojY5jGutNU0wVTmEOOfcuwLqyMVoAi9MKi2Ak+5i9+nhmrK4ufZE8069kHA==", + "license": "MIT", + "dependencies": { + "yocto-queue": "^1.1.1" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-queue": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/p-queue/-/p-queue-8.1.1.tgz", + "integrity": "sha512-aNZ+VfjobsWryoiPnEApGGmf5WmNsCo9xu8dfaYamG5qaLP7ClhLN6NgsFe6SwJ2UbLEBK5dv9x8Mn5+RVhMWQ==", + "license": "MIT", + "dependencies": { + "eventemitter3": "^5.0.1", + "p-timeout": "^6.1.2" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-timeout": { + "version": "6.1.4", + "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-6.1.4.tgz", + "integrity": "sha512-MyIV3ZA/PmyBN/ud8vV9XzwTrNtR4jFrObymZYnZqMmW0zA8Z17vnT0rBgFE/TlohB+YCHqXMgZzb3Csp49vqg==", + "license": "MIT", + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/package-manager-detector": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/package-manager-detector/-/package-manager-detector-1.6.0.tgz", + "integrity": "sha512-61A5ThoTiDG/C8s8UMZwSorAGwMJ0ERVGj2OjoW5pAalsNOg15+iQiPzrLJ4jhZ1HJzmC2PIHT2oEiH3R5fzNA==", + "license": "MIT" + }, + "node_modules/parse-latin": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/parse-latin/-/parse-latin-7.0.0.tgz", + "integrity": "sha512-mhHgobPPua5kZ98EF4HWiH167JWBfl4pvAIXXdbaVohtK7a6YBOy56kvhCqduqyo/f3yrHFWmqmiMg/BkBkYYQ==", + "license": "MIT", + "dependencies": { + "@types/nlcst": "^2.0.0", + "@types/unist": "^3.0.0", + "nlcst-to-string": "^4.0.0", + "unist-util-modify-children": "^4.0.0", + "unist-util-visit-children": "^3.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/parse5": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.3.0.tgz", + "integrity": "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==", + "license": "MIT", + "dependencies": { + "entities": "^6.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/piccolore": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/piccolore/-/piccolore-0.1.3.tgz", + "integrity": "sha512-o8bTeDWjE086iwKrROaDf31K0qC/BENdm15/uH9usSC/uZjJOKb2YGiVHfLY4GhwsERiPI1jmwI2XrA7ACOxVw==", + "license": "ISC" + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/postcss": { + "version": "8.5.8", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.8.tgz", + "integrity": "sha512-OW/rX8O/jXnm82Ey1k44pObPtdblfiuWnrd8X7GJ7emImCOstunGbXUpp7HdBrFQX6rJzn3sPT397Wp5aCwCHg==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.11", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/prismjs": { + "version": "1.30.0", + "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.30.0.tgz", + "integrity": "sha512-DEvV2ZF2r2/63V+tK8hQvrR2ZGn10srHbXviTlcv7Kpzw8jWiNTqbVgjO3IY8RxrrOUF8VPMQQFysYYYv0YZxw==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/prompts": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", + "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", + "license": "MIT", + "dependencies": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/property-information": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/property-information/-/property-information-7.1.0.tgz", + "integrity": "sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/radix3": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/radix3/-/radix3-1.1.2.tgz", + "integrity": "sha512-b484I/7b8rDEdSDKckSSBA8knMpcdsXudlE/LNL639wFoHKwLbEkQFZHWEYwDC0wa0FKUcCY+GAF73Z7wxNVFA==", + "license": "MIT" + }, + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "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/regex": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/regex/-/regex-6.1.0.tgz", + "integrity": "sha512-6VwtthbV4o/7+OaAF9I5L5V3llLEsoPyq9P1JVXkedTP33c7MfCG0/5NOPcSJn0TzXcG9YUrR0gQSWioew3LDg==", + "license": "MIT", + "dependencies": { + "regex-utilities": "^2.3.0" + } + }, + "node_modules/regex-recursion": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/regex-recursion/-/regex-recursion-6.0.2.tgz", + "integrity": "sha512-0YCaSCq2VRIebiaUviZNs0cBz1kg5kVS2UKUfNIx8YVs1cN3AV7NTctO5FOKBA+UT2BPJIWZauYHPqJODG50cg==", + "license": "MIT", + "dependencies": { + "regex-utilities": "^2.3.0" + } + }, + "node_modules/regex-utilities": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/regex-utilities/-/regex-utilities-2.3.0.tgz", + "integrity": "sha512-8VhliFJAWRaUiVvREIiW2NXXTmHs4vMNnSzuJVhscgmGav3g9VDxLrQndI3dZZVVdp0ZO/5v0xmX516/7M9cng==", + "license": "MIT" + }, + "node_modules/rehype": { + "version": "13.0.2", + "resolved": "https://registry.npmjs.org/rehype/-/rehype-13.0.2.tgz", + "integrity": "sha512-j31mdaRFrwFRUIlxGeuPXXKWQxet52RBQRvCmzl5eCefn/KGbomK5GMHNMsOJf55fgo3qw5tST5neDuarDYR2A==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "rehype-parse": "^9.0.0", + "rehype-stringify": "^10.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/rehype-parse": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/rehype-parse/-/rehype-parse-9.0.1.tgz", + "integrity": "sha512-ksCzCD0Fgfh7trPDxr2rSylbwq9iYDkSn8TCDmEJ49ljEUBxDVCzCHv7QNzZOfODanX4+bWQ4WZqLCRWYLfhag==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "hast-util-from-html": "^2.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/rehype-raw": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/rehype-raw/-/rehype-raw-7.0.0.tgz", + "integrity": "sha512-/aE8hCfKlQeA8LmyeyQvQF3eBiLRGNlfBJEvWH7ivp9sBqs7TNqBL5X3v157rM4IFETqDnIOO+z5M/biZbo9Ww==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "hast-util-raw": "^9.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/rehype-stringify": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/rehype-stringify/-/rehype-stringify-10.0.1.tgz", + "integrity": "sha512-k9ecfXHmIPuFVI61B9DeLPN0qFHfawM6RsuX48hoqlaKSF61RskNjSm1lI8PhBEM0MRdLxVVm4WmTqJQccH9mA==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "hast-util-to-html": "^9.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-gfm": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/remark-gfm/-/remark-gfm-4.0.1.tgz", + "integrity": "sha512-1quofZ2RQ9EWdeN34S79+KExV1764+wCUGop5CPL1WGdD0ocPpu91lzPGbwWMECpEpd42kJGQwzRfyov9j4yNg==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-gfm": "^3.0.0", + "micromark-extension-gfm": "^3.0.0", + "remark-parse": "^11.0.0", + "remark-stringify": "^11.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-parse": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-11.0.0.tgz", + "integrity": "sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-from-markdown": "^2.0.0", + "micromark-util-types": "^2.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-rehype": { + "version": "11.1.2", + "resolved": "https://registry.npmjs.org/remark-rehype/-/remark-rehype-11.1.2.tgz", + "integrity": "sha512-Dh7l57ianaEoIpzbp0PC9UKAdCSVklD8E5Rpw7ETfbTl3FqcOOgq5q2LVDhgGCkaBv7p24JXikPdvhhmHvKMsw==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "mdast-util-to-hast": "^13.0.0", + "unified": "^11.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-smartypants": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/remark-smartypants/-/remark-smartypants-3.0.2.tgz", + "integrity": "sha512-ILTWeOriIluwEvPjv67v7Blgrcx+LZOkAUVtKI3putuhlZm84FnqDORNXPPm+HY3NdZOMhyDwZ1E+eZB/Df5dA==", + "license": "MIT", + "dependencies": { + "retext": "^9.0.0", + "retext-smartypants": "^6.0.0", + "unified": "^11.0.4", + "unist-util-visit": "^5.0.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/remark-stringify": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/remark-stringify/-/remark-stringify-11.0.0.tgz", + "integrity": "sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-to-markdown": "^2.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/retext": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/retext/-/retext-9.0.0.tgz", + "integrity": "sha512-sbMDcpHCNjvlheSgMfEcVrZko3cDzdbe1x/e7G66dFp0Ff7Mldvi2uv6JkJQzdRcvLYE8CA8Oe8siQx8ZOgTcA==", + "license": "MIT", + "dependencies": { + "@types/nlcst": "^2.0.0", + "retext-latin": "^4.0.0", + "retext-stringify": "^4.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/retext-latin": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/retext-latin/-/retext-latin-4.0.0.tgz", + "integrity": "sha512-hv9woG7Fy0M9IlRQloq/N6atV82NxLGveq+3H2WOi79dtIYWN8OaxogDm77f8YnVXJL2VD3bbqowu5E3EMhBYA==", + "license": "MIT", + "dependencies": { + "@types/nlcst": "^2.0.0", + "parse-latin": "^7.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/retext-smartypants": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/retext-smartypants/-/retext-smartypants-6.2.0.tgz", + "integrity": "sha512-kk0jOU7+zGv//kfjXEBjdIryL1Acl4i9XNkHxtM7Tm5lFiCog576fjNC9hjoR7LTKQ0DsPWy09JummSsH1uqfQ==", + "license": "MIT", + "dependencies": { + "@types/nlcst": "^2.0.0", + "nlcst-to-string": "^4.0.0", + "unist-util-visit": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/retext-stringify": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/retext-stringify/-/retext-stringify-4.0.0.tgz", + "integrity": "sha512-rtfN/0o8kL1e+78+uxPTqu1Klt0yPzKuQ2BfWwwfgIUSayyzxpM1PJzkKt4V8803uB9qSy32MvI7Xep9khTpiA==", + "license": "MIT", + "dependencies": { + "@types/nlcst": "^2.0.0", + "nlcst-to-string": "^4.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/rollup": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.59.0.tgz", + "integrity": "sha512-2oMpl67a3zCH9H79LeMcbDhXW/UmWG/y2zuqnF2jQq5uq9TbM9TVyXvA4+t+ne2IIkBdrLpAaRQAvo7YI/Yyeg==", + "license": "MIT", + "dependencies": { + "@types/estree": "1.0.8" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.59.0", + "@rollup/rollup-android-arm64": "4.59.0", + "@rollup/rollup-darwin-arm64": "4.59.0", + "@rollup/rollup-darwin-x64": "4.59.0", + "@rollup/rollup-freebsd-arm64": "4.59.0", + "@rollup/rollup-freebsd-x64": "4.59.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.59.0", + "@rollup/rollup-linux-arm-musleabihf": "4.59.0", + "@rollup/rollup-linux-arm64-gnu": "4.59.0", + "@rollup/rollup-linux-arm64-musl": "4.59.0", + "@rollup/rollup-linux-loong64-gnu": "4.59.0", + "@rollup/rollup-linux-loong64-musl": "4.59.0", + "@rollup/rollup-linux-ppc64-gnu": "4.59.0", + "@rollup/rollup-linux-ppc64-musl": "4.59.0", + "@rollup/rollup-linux-riscv64-gnu": "4.59.0", + "@rollup/rollup-linux-riscv64-musl": "4.59.0", + "@rollup/rollup-linux-s390x-gnu": "4.59.0", + "@rollup/rollup-linux-x64-gnu": "4.59.0", + "@rollup/rollup-linux-x64-musl": "4.59.0", + "@rollup/rollup-openbsd-x64": "4.59.0", + "@rollup/rollup-openharmony-arm64": "4.59.0", + "@rollup/rollup-win32-arm64-msvc": "4.59.0", + "@rollup/rollup-win32-ia32-msvc": "4.59.0", + "@rollup/rollup-win32-x64-gnu": "4.59.0", + "@rollup/rollup-win32-x64-msvc": "4.59.0", + "fsevents": "~2.3.2" + } + }, + "node_modules/sax": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.5.0.tgz", + "integrity": "sha512-21IYA3Q5cQf089Z6tgaUTr7lDAyzoTPx5HRtbhsME8Udispad8dC/+sziTNugOEx54ilvatQ9YCzl4KQLPcRHA==", + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=11.0.0" + } + }, + "node_modules/semver": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/send": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/send/-/send-1.2.1.tgz", + "integrity": "sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ==", + "license": "MIT", + "dependencies": { + "debug": "^4.4.3", + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "etag": "^1.8.1", + "fresh": "^2.0.0", + "http-errors": "^2.0.1", + "mime-types": "^3.0.2", + "ms": "^2.1.3", + "on-finished": "^2.4.1", + "range-parser": "^1.2.1", + "statuses": "^2.0.2" + }, + "engines": { + "node": ">= 18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/server-destroy": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/server-destroy/-/server-destroy-1.0.1.tgz", + "integrity": "sha512-rb+9B5YBIEzYcD6x2VKidaa+cqYBJQKnU4oe4E3ANwRRN56yk/ua1YCJT1n21NTS8w6CcOclAKNP3PhdCXKYtQ==", + "license": "ISC" + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", + "license": "ISC" + }, + "node_modules/sharp": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.34.5.tgz", + "integrity": "sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg==", + "hasInstallScript": true, + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@img/colour": "^1.0.0", + "detect-libc": "^2.1.2", + "semver": "^7.7.3" + }, + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-darwin-arm64": "0.34.5", + "@img/sharp-darwin-x64": "0.34.5", + "@img/sharp-libvips-darwin-arm64": "1.2.4", + "@img/sharp-libvips-darwin-x64": "1.2.4", + "@img/sharp-libvips-linux-arm": "1.2.4", + "@img/sharp-libvips-linux-arm64": "1.2.4", + "@img/sharp-libvips-linux-ppc64": "1.2.4", + "@img/sharp-libvips-linux-riscv64": "1.2.4", + "@img/sharp-libvips-linux-s390x": "1.2.4", + "@img/sharp-libvips-linux-x64": "1.2.4", + "@img/sharp-libvips-linuxmusl-arm64": "1.2.4", + "@img/sharp-libvips-linuxmusl-x64": "1.2.4", + "@img/sharp-linux-arm": "0.34.5", + "@img/sharp-linux-arm64": "0.34.5", + "@img/sharp-linux-ppc64": "0.34.5", + "@img/sharp-linux-riscv64": "0.34.5", + "@img/sharp-linux-s390x": "0.34.5", + "@img/sharp-linux-x64": "0.34.5", + "@img/sharp-linuxmusl-arm64": "0.34.5", + "@img/sharp-linuxmusl-x64": "0.34.5", + "@img/sharp-wasm32": "0.34.5", + "@img/sharp-win32-arm64": "0.34.5", + "@img/sharp-win32-ia32": "0.34.5", + "@img/sharp-win32-x64": "0.34.5" + } + }, + "node_modules/shiki": { + "version": "3.23.0", + "resolved": "https://registry.npmjs.org/shiki/-/shiki-3.23.0.tgz", + "integrity": "sha512-55Dj73uq9ZXL5zyeRPzHQsK7Nbyt6Y10k5s7OjuFZGMhpp4r/rsLBH0o/0fstIzX1Lep9VxefWljK/SKCzygIA==", + "license": "MIT", + "dependencies": { + "@shikijs/core": "3.23.0", + "@shikijs/engine-javascript": "3.23.0", + "@shikijs/engine-oniguruma": "3.23.0", + "@shikijs/langs": "3.23.0", + "@shikijs/themes": "3.23.0", + "@shikijs/types": "3.23.0", + "@shikijs/vscode-textmate": "^10.0.2", + "@types/hast": "^3.0.4" + } + }, + "node_modules/sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", + "license": "MIT" + }, + "node_modules/smol-toml": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/smol-toml/-/smol-toml-1.6.0.tgz", + "integrity": "sha512-4zemZi0HvTnYwLfrpk/CF9LOd9Lt87kAt50GnqhMpyF9U3poDAP2+iukq2bZsO/ufegbYehBkqINbsWxj4l4cw==", + "license": "BSD-3-Clause", + "engines": { + "node": ">= 18" + }, + "funding": { + "url": "https://github.com/sponsors/cyyynthia" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/space-separated-tokens": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz", + "integrity": "sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/statuses": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz", + "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/string-width": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", + "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", + "license": "MIT", + "dependencies": { + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/stringify-entities": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-4.0.4.tgz", + "integrity": "sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==", + "license": "MIT", + "dependencies": { + "character-entities-html4": "^2.0.0", + "character-entities-legacy": "^3.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/strip-ansi": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz", + "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.2.2" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/svgo": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/svgo/-/svgo-4.0.1.tgz", + "integrity": "sha512-XDpWUOPC6FEibaLzjfe0ucaV0YrOjYotGJO1WpF0Zd+n6ZGEQUsSugaoLq9QkEZtAfQIxT42UChcssDVPP3+/w==", + "license": "MIT", + "dependencies": { + "commander": "^11.1.0", + "css-select": "^5.1.0", + "css-tree": "^3.0.1", + "css-what": "^6.1.0", + "csso": "^5.0.5", + "picocolors": "^1.1.1", + "sax": "^1.5.0" + }, + "bin": { + "svgo": "bin/svgo.js" + }, + "engines": { + "node": ">=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/svgo" + } + }, + "node_modules/tiny-inflate": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tiny-inflate/-/tiny-inflate-1.0.3.tgz", + "integrity": "sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw==", + "license": "MIT" + }, + "node_modules/tinyexec": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.0.2.tgz", + "integrity": "sha512-W/KYk+NFhkmsYpuHq5JykngiOCnxeVL8v8dFnqxSD8qEEdRfXk1SDM6JzNqcERbcGYj9tMrDQBYV9cjgnunFIg==", + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/tinyglobby": { + "version": "0.2.15", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", + "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==", + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.3" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "license": "MIT", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/trim-lines": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/trim-lines/-/trim-lines-3.0.1.tgz", + "integrity": "sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/trough": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/trough/-/trough-2.2.0.tgz", + "integrity": "sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/tsconfck": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/tsconfck/-/tsconfck-3.1.6.tgz", + "integrity": "sha512-ks6Vjr/jEw0P1gmOVwutM3B7fWxoWBL2KRDb1JfqGVawBmO5UsvmWOQFGHBPl5yxYz4eERr19E6L7NMv+Fej4w==", + "license": "MIT", + "bin": { + "tsconfck": "bin/tsconfck.js" + }, + "engines": { + "node": "^18 || >=20" + }, + "peerDependencies": { + "typescript": "^5.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD", + "optional": true + }, + "node_modules/type-fest": { + "version": "4.41.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.41.0.tgz", + "integrity": "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==", + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/typescript": { + "version": "5.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", + "license": "Apache-2.0", + "peer": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/ufo": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.6.3.tgz", + "integrity": "sha512-yDJTmhydvl5lJzBmy/hyOAA0d+aqCBuwl818haVdYCRrWV84o7YyeVm4QlVHStqNrrJSTb6jKuFAVqAFsr+K3Q==", + "license": "MIT" + }, + "node_modules/ultrahtml": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/ultrahtml/-/ultrahtml-1.6.0.tgz", + "integrity": "sha512-R9fBn90VTJrqqLDwyMph+HGne8eqY1iPfYhPzZrvKpIfwkWZbcYlfpsb8B9dTvBfpy1/hqAD7Wi8EKfP9e8zdw==", + "license": "MIT" + }, + "node_modules/uncrypto": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/uncrypto/-/uncrypto-0.1.3.tgz", + "integrity": "sha512-Ql87qFHB3s/De2ClA9e0gsnS6zXG27SkTiSJwjCc9MebbfapQfuPzumMIUMi38ezPZVNFcHI9sUIepeQfw8J8Q==", + "license": "MIT" + }, + "node_modules/unified": { + "version": "11.0.5", + "resolved": "https://registry.npmjs.org/unified/-/unified-11.0.5.tgz", + "integrity": "sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "bail": "^2.0.0", + "devlop": "^1.0.0", + "extend": "^3.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unifont": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/unifont/-/unifont-0.7.4.tgz", + "integrity": "sha512-oHeis4/xl42HUIeHuNZRGEvxj5AaIKR+bHPNegRq5LV1gdc3jundpONbjglKpihmJf+dswygdMJn3eftGIMemg==", + "license": "MIT", + "dependencies": { + "css-tree": "^3.1.0", + "ofetch": "^1.5.1", + "ohash": "^2.0.11" + } + }, + "node_modules/unist-util-find-after": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-find-after/-/unist-util-find-after-5.0.0.tgz", + "integrity": "sha512-amQa0Ep2m6hE2g72AugUItjbuM8X8cGQnFoHk0pGfrFeT9GZhzN5SW8nRsiGKK7Aif4CrACPENkA6P/Lw6fHGQ==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-is": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.1.tgz", + "integrity": "sha512-LsiILbtBETkDz8I9p1dQ0uyRUWuaQzd/cuEeS1hoRSyW5E5XGmTzlwY1OrNzzakGowI9Dr/I8HVaw4hTtnxy8g==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-modify-children": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-modify-children/-/unist-util-modify-children-4.0.0.tgz", + "integrity": "sha512-+tdN5fGNddvsQdIzUF3Xx82CU9sMM+fA0dLgR9vOmT0oPT2jH+P1nd5lSqfCfXAw+93NhcXNY2qqvTUtE4cQkw==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "array-iterate": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-position": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-5.0.0.tgz", + "integrity": "sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-remove-position": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-remove-position/-/unist-util-remove-position-5.0.0.tgz", + "integrity": "sha512-Hp5Kh3wLxv0PHj9m2yZhhLt58KzPtEYKQQ4yxfYFEO7EvHwzyDYnduhHnY1mDxoqr7VUwVuHXk9RXKIiYS1N8Q==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-visit": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-stringify-position": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", + "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-visit": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.1.0.tgz", + "integrity": "sha512-m+vIdyeCOpdr/QeQCu2EzxX/ohgS8KbnPDgFni4dQsfSCtpz8UqDyY5GjRru8PDKuYn7Fq19j1CQ+nJSsGKOzg==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-visit-children": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit-children/-/unist-util-visit-children-3.0.0.tgz", + "integrity": "sha512-RgmdTfSBOg04sdPcpTSD1jzoNBjt9a80/ZCzp5cI9n1qPzLZWF9YdvWGN2zmTumP1HWhXKdUWexjy/Wy/lJ7tA==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-visit-parents": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.2.tgz", + "integrity": "sha512-goh1s1TBrqSqukSc8wrjwWhL0hiJxgA8m4kFxGlQ+8FYQ3C/m11FcTs4YYem7V664AhHVvgoQLk890Ssdsr2IQ==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unstorage": { + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/unstorage/-/unstorage-1.17.4.tgz", + "integrity": "sha512-fHK0yNg38tBiJKp/Vgsq4j0JEsCmgqH58HAn707S7zGkArbZsVr/CwINoi+nh3h98BRCwKvx1K3Xg9u3VV83sw==", + "license": "MIT", + "dependencies": { + "anymatch": "^3.1.3", + "chokidar": "^5.0.0", + "destr": "^2.0.5", + "h3": "^1.15.5", + "lru-cache": "^11.2.0", + "node-fetch-native": "^1.6.7", + "ofetch": "^1.5.1", + "ufo": "^1.6.3" + }, + "peerDependencies": { + "@azure/app-configuration": "^1.8.0", + "@azure/cosmos": "^4.2.0", + "@azure/data-tables": "^13.3.0", + "@azure/identity": "^4.6.0", + "@azure/keyvault-secrets": "^4.9.0", + "@azure/storage-blob": "^12.26.0", + "@capacitor/preferences": "^6 || ^7 || ^8", + "@deno/kv": ">=0.9.0", + "@netlify/blobs": "^6.5.0 || ^7.0.0 || ^8.1.0 || ^9.0.0 || ^10.0.0", + "@planetscale/database": "^1.19.0", + "@upstash/redis": "^1.34.3", + "@vercel/blob": ">=0.27.1", + "@vercel/functions": "^2.2.12 || ^3.0.0", + "@vercel/kv": "^1 || ^2 || ^3", + "aws4fetch": "^1.0.20", + "db0": ">=0.2.1", + "idb-keyval": "^6.2.1", + "ioredis": "^5.4.2", + "uploadthing": "^7.4.4" + }, + "peerDependenciesMeta": { + "@azure/app-configuration": { + "optional": true + }, + "@azure/cosmos": { + "optional": true + }, + "@azure/data-tables": { + "optional": true + }, + "@azure/identity": { + "optional": true + }, + "@azure/keyvault-secrets": { + "optional": true + }, + "@azure/storage-blob": { + "optional": true + }, + "@capacitor/preferences": { + "optional": true + }, + "@deno/kv": { + "optional": true + }, + "@netlify/blobs": { + "optional": true + }, + "@planetscale/database": { + "optional": true + }, + "@upstash/redis": { + "optional": true + }, + "@vercel/blob": { + "optional": true + }, + "@vercel/functions": { + "optional": true + }, + "@vercel/kv": { + "optional": true + }, + "aws4fetch": { + "optional": true + }, + "db0": { + "optional": true + }, + "idb-keyval": { + "optional": true + }, + "ioredis": { + "optional": true + }, + "uploadthing": { + "optional": true + } + } + }, + "node_modules/vfile": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.3.tgz", + "integrity": "sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vfile-location": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-5.0.3.tgz", + "integrity": "sha512-5yXvWDEgqeiYiBe1lbxYF7UMAIm/IcopxMHrMQDq3nvKcjPKIhZklUKL+AE7J7uApI4kwe2snsK+eI6UTj9EHg==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vfile-message": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.3.tgz", + "integrity": "sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-stringify-position": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vite": { + "version": "6.4.1", + "resolved": "https://registry.npmjs.org/vite/-/vite-6.4.1.tgz", + "integrity": "sha512-+Oxm7q9hDoLMyJOYfUYBuHQo+dkAloi33apOPP56pzj+vsdJDzr+j1NISE5pyaAuKL4A3UD34qd0lx5+kfKp2g==", + "license": "MIT", + "dependencies": { + "esbuild": "^0.25.0", + "fdir": "^6.4.4", + "picomatch": "^4.0.2", + "postcss": "^8.5.3", + "rollup": "^4.34.9", + "tinyglobby": "^0.2.13" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^18.0.0 || ^20.0.0 || >=22.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", + "jiti": ">=1.21.0", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "sass-embedded": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.16.0", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "jiti": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } + } + }, + "node_modules/vite/node_modules/@esbuild/aix-ppc64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.12.tgz", + "integrity": "sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/android-arm": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.12.tgz", + "integrity": "sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/android-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.12.tgz", + "integrity": "sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/android-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.12.tgz", + "integrity": "sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/darwin-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.12.tgz", + "integrity": "sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/darwin-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.12.tgz", + "integrity": "sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/freebsd-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.12.tgz", + "integrity": "sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/freebsd-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.12.tgz", + "integrity": "sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-arm": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.12.tgz", + "integrity": "sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.12.tgz", + "integrity": "sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-ia32": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.12.tgz", + "integrity": "sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-loong64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.12.tgz", + "integrity": "sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==", + "cpu": [ + "loong64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-mips64el": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.12.tgz", + "integrity": "sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==", + "cpu": [ + "mips64el" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-ppc64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.12.tgz", + "integrity": "sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-riscv64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.12.tgz", + "integrity": "sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==", + "cpu": [ + "riscv64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-s390x": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.12.tgz", + "integrity": "sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==", + "cpu": [ + "s390x" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.12.tgz", + "integrity": "sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/netbsd-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.12.tgz", + "integrity": "sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/netbsd-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.12.tgz", + "integrity": "sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/openbsd-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.12.tgz", + "integrity": "sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/openbsd-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.12.tgz", + "integrity": "sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/openharmony-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.12.tgz", + "integrity": "sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/sunos-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.12.tgz", + "integrity": "sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/win32-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.12.tgz", + "integrity": "sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/win32-ia32": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.12.tgz", + "integrity": "sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/win32-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.12.tgz", + "integrity": "sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/esbuild": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.12.tgz", + "integrity": "sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==", + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.25.12", + "@esbuild/android-arm": "0.25.12", + "@esbuild/android-arm64": "0.25.12", + "@esbuild/android-x64": "0.25.12", + "@esbuild/darwin-arm64": "0.25.12", + "@esbuild/darwin-x64": "0.25.12", + "@esbuild/freebsd-arm64": "0.25.12", + "@esbuild/freebsd-x64": "0.25.12", + "@esbuild/linux-arm": "0.25.12", + "@esbuild/linux-arm64": "0.25.12", + "@esbuild/linux-ia32": "0.25.12", + "@esbuild/linux-loong64": "0.25.12", + "@esbuild/linux-mips64el": "0.25.12", + "@esbuild/linux-ppc64": "0.25.12", + "@esbuild/linux-riscv64": "0.25.12", + "@esbuild/linux-s390x": "0.25.12", + "@esbuild/linux-x64": "0.25.12", + "@esbuild/netbsd-arm64": "0.25.12", + "@esbuild/netbsd-x64": "0.25.12", + "@esbuild/openbsd-arm64": "0.25.12", + "@esbuild/openbsd-x64": "0.25.12", + "@esbuild/openharmony-arm64": "0.25.12", + "@esbuild/sunos-x64": "0.25.12", + "@esbuild/win32-arm64": "0.25.12", + "@esbuild/win32-ia32": "0.25.12", + "@esbuild/win32-x64": "0.25.12" + } + }, + "node_modules/vitefu": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vitefu/-/vitefu-1.1.2.tgz", + "integrity": "sha512-zpKATdUbzbsycPFBN71nS2uzBUQiVnFoOrr2rvqv34S1lcAgMKKkjWleLGeiJlZ8lwCXvtWaRn7R3ZC16SYRuw==", + "license": "MIT", + "workspaces": [ + "tests/deps/*", + "tests/projects/*", + "tests/projects/workspace/packages/*" + ], + "peerDependencies": { + "vite": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-beta.0" + }, + "peerDependenciesMeta": { + "vite": { + "optional": true + } + } + }, + "node_modules/web-namespaces": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/web-namespaces/-/web-namespaces-2.0.1.tgz", + "integrity": "sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/which-pm-runs": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/which-pm-runs/-/which-pm-runs-1.1.0.tgz", + "integrity": "sha512-n1brCuqClxfFfq/Rb0ICg9giSZqCS+pLtccdag6C2HyufBrh3fBOiy9nb6ggRMvWOVH5GrdJskj5iGTZNxd7SA==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/widest-line": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-5.0.0.tgz", + "integrity": "sha512-c9bZp7b5YtRj2wOe6dlj32MK+Bx/M/d+9VB2SHM1OtsUHR0aV0tdP6DWh/iMt0kWi1t5g1Iudu6hQRNd1A4PVA==", + "license": "MIT", + "dependencies": { + "string-width": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/wrap-ansi": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.2.tgz", + "integrity": "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.2.1", + "string-width": "^7.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/xxhash-wasm": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/xxhash-wasm/-/xxhash-wasm-1.1.0.tgz", + "integrity": "sha512-147y/6YNh+tlp6nd/2pWq38i9h6mz/EuQ6njIrmW8D1BS5nCqs0P6DG+m6zTGnNz5I+uhZ0SHxBs9BsPrwcKDA==", + "license": "MIT" + }, + "node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/yocto-queue": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.2.2.tgz", + "integrity": "sha512-4LCcse/U2MHZ63HAJVE+v71o7yOdIe4cZ70Wpf8D/IyjDKYQLV5GD46B+hSTjJsvV5PztjvHoU580EftxjDZFQ==", + "license": "MIT", + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/yocto-spinner": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/yocto-spinner/-/yocto-spinner-0.2.3.tgz", + "integrity": "sha512-sqBChb33loEnkoXte1bLg45bEBsOP9N1kzQh5JZNKj/0rik4zAPTNSAVPj3uQAdc6slYJ0Ksc403G2XgxsJQFQ==", + "license": "MIT", + "dependencies": { + "yoctocolors": "^2.1.1" + }, + "engines": { + "node": ">=18.19" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/yoctocolors": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yoctocolors/-/yoctocolors-2.1.2.tgz", + "integrity": "sha512-CzhO+pFNo8ajLM2d2IW/R93ipy99LWjtwblvC1RsoSUMZgyLbYFr221TnSNT7GjGdYui6P459mw9JH/g/zW2ug==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/zod": { + "version": "3.25.76", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", + "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + }, + "node_modules/zod-to-json-schema": { + "version": "3.25.1", + "resolved": "https://registry.npmjs.org/zod-to-json-schema/-/zod-to-json-schema-3.25.1.tgz", + "integrity": "sha512-pM/SU9d3YAggzi6MtR4h7ruuQlqKtad8e9S0fmxcMi+ueAK5Korys/aWcV9LIIHTVbj01NdzxcnXSN+O74ZIVA==", + "license": "ISC", + "peerDependencies": { + "zod": "^3.25 || ^4" + } + }, + "node_modules/zod-to-ts": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/zod-to-ts/-/zod-to-ts-1.2.0.tgz", + "integrity": "sha512-x30XE43V+InwGpvTySRNz9kB7qFU8DlyEy7BsSTCHPH1R0QasMmHWZDCzYm6bVXtj/9NNJAZF3jW8rzFvH5OFA==", + "peerDependencies": { + "typescript": "^4.9.4 || ^5.0.2", + "zod": "^3" + } + }, + "node_modules/zwitch": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz", + "integrity": "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + } + } +} diff --git a/tests/resources/sites/astro/src/pages/specs.js b/tests/resources/sites/astro/src/pages/specs.js new file mode 100644 index 0000000000..adc2d6768f --- /dev/null +++ b/tests/resources/sites/astro/src/pages/specs.js @@ -0,0 +1,13 @@ +export async function GET(_context) { + return new Response( + JSON.stringify({ + APPWRITE_SITE_MEMORY: process.env.APPWRITE_SITE_MEMORY, + APPWRITE_SITE_CPUS: process.env.APPWRITE_SITE_CPUS, + }), + { + headers: { + "Content-Type": "application/json", + }, + }, + ); +}