diff --git a/api-1.yaml b/api-1.yaml new file mode 100644 index 0000000..40f3933 --- /dev/null +++ b/api-1.yaml @@ -0,0 +1,7032 @@ +openapi: 3.0.0 +info: + title: Hostinger API + description: >- + # Overview + + The Hostinger API provides a comprehensive set of endpoints that allow + developers + + to interact with Hostinger's services programmatically. + + This API enables you to manage various aspects of your Hostinger account. + + + The Hostinger API is a (mostly) RESTful API that uses standard HTTP methods + and status codes. + + # Authentication + + The Hostinger API uses tokens for authentication. To authenticate your + requests, + + you need to include a valid bearer token in the Authorization header of your + HTTP requests: + + ```yaml + + Authorization: Bearer YOUR_API_TOKEN + + ``` + + API tokens for individual users can be created and managed from + + the [Account page](https://hpanel.hostinger.com/profile/api) of the + Hostinger Panel. + + Tokens will have same permissions as the owning user. + + Optionally, tokens can be set to expire after a certain period of time. + + # Rate Limiting + + To ensure fair usage and prevent abuse, + + the API enforces rate limits on the number of requests that can be made + within a certain time period. + + If you exceed the rate limit, you will receive a 429 Too Many Requests + response. + + Rate limit headers are included in the response to help you manage your + requests. + + Your IP address might get temporarily blocked if you exceed the rate limit + multiple times. + + # Parameters + + All requests sent to API must have the content type `application/json`. + + `POST`, `PUT`, `PATCH` methods may include a JSON object in the request + body. + + Documentation provides required structure and examples of the object. + + Some endpoints require path parameters. + + These parameters are included in the URL path and are marked with curly + braces. + + # Pagination + + Some endpoints return a large number of items. + + To make these responses more manageable, the API uses pagination. + + By default, the API returns50 items per page. + + The page number can be specified using the `page` query parameter, + for example: `/api/vps/v1/public-keys?page=2` + # Errors + + The Hostinger API uses standard HTTP status codes to indicate the success or + failure of a request. + + In case of an error, the API will return a JSON response with an `error` + field, + + containing a human-readable error message. + + Error responses also contain a `correlation_id` field + + which can be used to identify the request in case you need to contact + support. + + # SDKs & Tools + + To help you get started with the Hostinger API,we provide SDKs and tools in + various programming languages. + + The usage & documentation for each SDK can be found in the respective + repositories: + + - Ansible - https://github.com/hostinger/ansible-collection-hostinger + + - CLI - https://github.com/hostinger/api-cli + + - n8n node - https://github.com/hostinger/api-n8n-node + + - MCP server - https://github.com/hostinger/api-mcp-server + + - PHP - https://github.com/hostinger/api-php-sdk + + - Python - https://github.com/hostinger/api-python-sdk + + - Terraform - https://github.com/hostinger/terraform-provider-hostinger + + - Node / TypeScript - https://github.com/hostinger/api-typescript-sdk + + - Postman collection - https://www.postman.com/hostinger-api + + - WHMCS module - https://github.com/hostinger/api-whmcs-plugin + + # Change log + + For information on the latest changes to the API, + + please refer to the [change + log](https://github.com/hostinger/api/blob/main/CHANGELOG.md). + + # Support + + If you have any questions, feedback or feature requests, + + please create an [issue](https://github.com/hostinger/api/issues) + + or [discussion](https://github.com/hostinger/api/discussions) on the + repository. + + + For any support take a look at our [Github + Repository](https://github.com/hostinger/api/), + + dedicated to the Hostinger API. + contact: + name: Hostinger + url: https://developers.hostinger.com + email: devs@hostinger.com + version: 0.11.7 + x-scalar-sdk-installation: + - lang: Shell + description: Install official CLI tool. Examples and usage instructions can be + found in our [Github repository](https://github.com/hostinger/api-cli). + source: hapi vps vm list + - lang: PHP + description: Install official PHP SDK. Examples and usage instructions can be + found in our [Github + repository](https://github.com/hostinger/api-php-sdk). + source: composer require hostinger/api-php-sdk + - lang: Python + description: Install official Python SDK. Examples and usage instructions can be + found in our [Github + repository](https://github.com/hostinger/api-python-sdk). + source: pip install hostinger_api + - lang: Node + description: Install official Node / Typescript SDK. Examples and usage + instructions can be found in our [Github + repository](https://github.com/hostinger/api-typescript-sdk). + source: npm install hostinger-api-sdk +servers: + - url: https://developers.hostinger.com + description: Production API Server +paths: + /api/billing/v1/catalog: + get: + tags: + - "Billing: Catalog" + summary: Get catalog item list + description: >- + Retrieve catalog items available for order. + + + Prices in catalog items is displayed as cents (without floating point), + + e.g: float `17.99` is displayed as integer `1799`. + + + Use this endpoint to view available services and pricing before placing + orders. + operationId: billing_getCatalogItemListV1 + parameters: + - $ref: "#/components/parameters/category" + - $ref: "#/components/parameters/name" + responses: + "200": + description: Success response + content: + application/json: + schema: + $ref: "#/components/schemas/Billing.V1.Catalog.CatalogItemCollection" + "401": + $ref: "#/components/responses/Common.Response.UnauthorizedResponse" + "500": + $ref: "#/components/responses/Common.Response.ErrorResponse" + /api/billing/v1/payment-methods/{paymentMethodId}: + post: + tags: + - "Billing: Payment methods" + summary: Set default payment method + description: >- + Set the default payment method for your account. + + + Use this endpoint to configure the primary payment method for future + orders. + operationId: billing_setDefaultPaymentMethodV1 + parameters: + - $ref: "#/components/parameters/paymentMethodId" + responses: + "200": + description: Success empty response + content: + application/json: + schema: + $ref: "#/components/schemas/Common.SuccessEmptyResource" + "401": + $ref: "#/components/responses/Common.Response.UnauthorizedResponse" + "500": + $ref: "#/components/responses/Common.Response.ErrorResponse" + delete: + tags: + - "Billing: Payment methods" + summary: Delete payment method + description: |- + Delete a payment method from your account. + + Use this endpoint to remove unused payment methods from user accounts. + operationId: billing_deletePaymentMethodV1 + parameters: + - $ref: "#/components/parameters/paymentMethodId" + responses: + "200": + description: Success empty response + content: + application/json: + schema: + $ref: "#/components/schemas/Common.SuccessEmptyResource" + "401": + $ref: "#/components/responses/Common.Response.UnauthorizedResponse" + "500": + $ref: "#/components/responses/Common.Response.ErrorResponse" + /api/billing/v1/payment-methods: + get: + tags: + - "Billing: Payment methods" + summary: Get payment method list + description: >- + Retrieve available payment methods that can be used for placing new + orders. + + + If you want to add new payment method, + + please use + [hPanel](https://hpanel.hostinger.com/billing/payment-methods). + + + Use this endpoint to view available payment options before creating + orders. + operationId: billing_getPaymentMethodListV1 + responses: + "200": + description: Success response + content: + application/json: + schema: + $ref: "#/components/schemas/Billing.V1.PaymentMethod.PaymentMethodCollection" + "401": + $ref: "#/components/responses/Common.Response.UnauthorizedResponse" + "500": + $ref: "#/components/responses/Common.Response.ErrorResponse" + /api/billing/v1/subscriptions: + get: + tags: + - "Billing: Subscriptions" + summary: Get subscription list + description: |- + Retrieve a list of all subscriptions associated with your account. + + Use this endpoint to monitor active services and billing status. + operationId: billing_getSubscriptionListV1 + responses: + "200": + description: Success response + content: + application/json: + schema: + $ref: "#/components/schemas/Billing.V1.Subscription.SubscriptionCollection" + "401": + $ref: "#/components/responses/Common.Response.UnauthorizedResponse" + "500": + $ref: "#/components/responses/Common.Response.ErrorResponse" + /api/billing/v1/subscriptions/{subscriptionId}/auto-renewal/disable: + delete: + tags: + - "Billing: Subscriptions" + summary: Disable auto-renewal + description: |- + Disable auto-renewal for a subscription. + + Use this endpoint when disable auto-renewal for a subscription. + operationId: billing_disableAutoRenewalV1 + parameters: + - $ref: "#/components/parameters/subscriptionId" + responses: + "200": + description: Success response + content: + application/json: + schema: + $ref: "#/components/schemas/Billing.V1.Subscription.SubscriptionResource" + "401": + $ref: "#/components/responses/Common.Response.UnauthorizedResponse" + "500": + $ref: "#/components/responses/Common.Response.ErrorResponse" + /api/billing/v1/subscriptions/{subscriptionId}/auto-renewal/enable: + patch: + tags: + - "Billing: Subscriptions" + summary: Enable auto-renewal + description: |- + Enable auto-renewal for a subscription. + + Use this endpoint when enable auto-renewal for a subscription. + operationId: billing_enableAutoRenewalV1 + parameters: + - $ref: "#/components/parameters/subscriptionId" + responses: + "200": + description: Success response + content: + application/json: + schema: + $ref: "#/components/schemas/Billing.V1.Subscription.SubscriptionResource" + "401": + $ref: "#/components/responses/Common.Response.UnauthorizedResponse" + "500": + $ref: "#/components/responses/Common.Response.ErrorResponse" + /api/dns/v1/snapshots/{domain}/{snapshotId}: + get: + tags: + - "DNS: Snapshot" + summary: Get DNS snapshot + description: |- + Retrieve particular DNS snapshot with contents of DNS zone records. + + Use this endpoint to view historical DNS configurations for domains. + operationId: DNS_getDNSSnapshotV1 + parameters: + - $ref: "#/components/parameters/domain" + - $ref: "#/components/parameters/snapshotId" + responses: + "200": + description: Success response + content: + application/json: + schema: + $ref: "#/components/schemas/DNS.V1.Snapshot.SnapshotWithContentResource" + "401": + $ref: "#/components/responses/Common.Response.UnauthorizedResponse" + "500": + $ref: "#/components/responses/Common.Response.ErrorResponse" + /api/dns/v1/snapshots/{domain}: + get: + tags: + - "DNS: Snapshot" + summary: Get DNS snapshot list + description: |- + Retrieve DNS snapshots for a domain. + + Use this endpoint to view available DNS backup points for restoration. + operationId: DNS_getDNSSnapshotListV1 + parameters: + - $ref: "#/components/parameters/domain" + responses: + "200": + description: Success response + content: + application/json: + schema: + $ref: "#/components/schemas/DNS.V1.Snapshot.SnapshotCollection" + "401": + $ref: "#/components/responses/Common.Response.UnauthorizedResponse" + "500": + $ref: "#/components/responses/Common.Response.ErrorResponse" + /api/dns/v1/snapshots/{domain}/{snapshotId}/restore: + post: + tags: + - "DNS: Snapshot" + summary: Restore DNS snapshot + description: |- + Restore DNS zone to the selected snapshot. + + Use this endpoint to revert domain DNS to a previous configuration. + operationId: DNS_restoreDNSSnapshotV1 + parameters: + - $ref: "#/components/parameters/domain" + - $ref: "#/components/parameters/snapshotId" + responses: + "200": + description: Success response + content: + application/json: + schema: + $ref: "#/components/schemas/Common.SuccessEmptyResource" + "401": + $ref: "#/components/responses/Common.Response.UnauthorizedResponse" + "500": + $ref: "#/components/responses/Common.Response.ErrorResponse" + /api/dns/v1/zones/{domain}: + get: + tags: + - "DNS: Zone" + summary: Get DNS records + description: >- + Retrieve DNS zone records for a specific domain. + + + Use this endpoint to view current DNS configuration for domain + management. + operationId: DNS_getDNSRecordsV1 + parameters: + - $ref: "#/components/parameters/domain" + responses: + "200": + description: Success response + content: + application/json: + schema: + $ref: "#/components/schemas/DNS.V1.Zone.RecordCollection" + "401": + $ref: "#/components/responses/Common.Response.UnauthorizedResponse" + "500": + $ref: "#/components/responses/Common.Response.ErrorResponse" + put: + tags: + - "DNS: Zone" + summary: Update DNS records + description: >- + Update DNS records for the selected domain. + + + Using `overwrite = true` will replace existing records with the provided + ones. + + Otherwise existing records will be updated and new records will be + added. + + + Use this endpoint to modify domain DNS configuration. + operationId: DNS_updateDNSRecordsV1 + parameters: + - $ref: "#/components/parameters/domain" + requestBody: + required: true + content: + application/json: + schema: + $ref: "#/components/schemas/DNS.V1.Zone.UpdateRequest" + responses: + "200": + description: Success response + content: + application/json: + schema: + $ref: "#/components/schemas/Common.SuccessEmptyResource" + "401": + $ref: "#/components/responses/Common.Response.UnauthorizedResponse" + "422": + $ref: "#/components/responses/Common.Response.UnprocessableContentResponse" + "500": + $ref: "#/components/responses/Common.Response.ErrorResponse" + delete: + tags: + - "DNS: Zone" + summary: Delete DNS records + description: >- + Delete DNS records for the selected domain. + + + To filter which records to delete, add the `name` of the record and + `type` to the filter. + + Multiple filters can be provided with single request. + + + If you have multiple records with the same name and type, and you want + to delete only part of them, + + refer to the `Update zone records` endpoint. + + + Use this endpoint to remove specific DNS records from domains. + operationId: DNS_deleteDNSRecordsV1 + parameters: + - $ref: "#/components/parameters/domain" + requestBody: + required: true + content: + application/json: + schema: + $ref: "#/components/schemas/DNS.V1.Zone.DestroyRequest" + responses: + "200": + description: Success response + content: + application/json: + schema: + $ref: "#/components/schemas/Common.SuccessEmptyResource" + "401": + $ref: "#/components/responses/Common.Response.UnauthorizedResponse" + "422": + $ref: "#/components/responses/Common.Response.UnprocessableContentResponse" + "500": + $ref: "#/components/responses/Common.Response.ErrorResponse" + /api/dns/v1/zones/{domain}/reset: + post: + tags: + - "DNS: Zone" + summary: Reset DNS records + description: |- + Reset DNS zone to the default records. + + Use this endpoint to restore domain DNS to original configuration. + operationId: DNS_resetDNSRecordsV1 + parameters: + - $ref: "#/components/parameters/domain" + requestBody: + required: true + content: + application/json: + schema: + $ref: "#/components/schemas/DNS.V1.Zone.ResetRequest" + responses: + "200": + description: Success response + content: + application/json: + schema: + $ref: "#/components/schemas/Common.SuccessEmptyResource" + "401": + $ref: "#/components/responses/Common.Response.UnauthorizedResponse" + "422": + $ref: "#/components/responses/Common.Response.UnprocessableContentResponse" + "500": + $ref: "#/components/responses/Common.Response.ErrorResponse" + /api/dns/v1/zones/{domain}/validate: + post: + tags: + - "DNS: Zone" + summary: Validate DNS records + description: >- + Validate DNS records prior to update for the selected domain. + + + If the validation is successful, the response will contain `200 Success` + code. + + If there is validation error, the response will fail with `422 + Validation error` code. + + + Use this endpoint to verify DNS record validity before applying changes. + operationId: DNS_validateDNSRecordsV1 + parameters: + - $ref: "#/components/parameters/domain" + requestBody: + required: true + content: + application/json: + schema: + $ref: "#/components/schemas/DNS.V1.Zone.UpdateRequest" + responses: + "200": + description: Success response + content: + application/json: + schema: + $ref: "#/components/schemas/Common.SuccessEmptyResource" + "401": + $ref: "#/components/responses/Common.Response.UnauthorizedResponse" + "422": + $ref: "#/components/responses/Common.Response.UnprocessableContentResponse" + "500": + $ref: "#/components/responses/Common.Response.ErrorResponse" + /api/v2/direct/verifications/active: + get: + tags: + - "Domain Access Verifier: Verifications" + summary: Get domain verifications + description: Retrieve a list of pending and completed domain verifications. + operationId: v2_getDomainVerificationsDIRECT + requestBody: + required: true + content: + application/json: + schema: + $ref: "#/components/schemas/DomainAccessVerifier.V2.Verifications.ListRequest" + responses: + "200": + description: Success response + content: + application/json: + schema: + $ref: "#/components/schemas/DomainAccessVerifier.V2.Verifications.ActiveVerific\ + ationsCollection" + "401": + $ref: "#/components/responses/Common.Response.UnauthorizedResponse" + "422": + $ref: "#/components/responses/Common.Response.UnprocessableContentResponse" + "500": + $ref: "#/components/responses/Common.Response.ErrorResponse" + /api/domains/v1/availability: + post: + tags: + - "Domains: Availability" + summary: Check domain availability + description: >- + Check availability of domain names across multiple TLDs. + + + Multiple TLDs can be checked at once. + + If you want alternative domains with response, provide only one TLD and + set `with_alternatives` to `true`. + + TLDs should be provided without leading dot (e.g. `com`, `net`, `org`). + + + Endpoint has rate limit of 10 requests per minute. + + + Use this endpoint to verify domain availability before purchase. + operationId: domains_checkDomainAvailabilityV1 + requestBody: + required: true + content: + application/json: + schema: + $ref: "#/components/schemas/Domains.V1.Availability.AvailabilityRequest" + responses: + "200": + description: Success response + content: + application/json: + schema: + $ref: "#/components/schemas/Domains.V1.Availability.AvailabilityCollection" + "401": + $ref: "#/components/responses/Common.Response.UnauthorizedResponse" + "422": + $ref: "#/components/responses/Common.Response.UnprocessableContentResponse" + "500": + $ref: "#/components/responses/Common.Response.ErrorResponse" + /api/domains/v1/forwarding/{domain}: + get: + tags: + - "Domains: Forwarding" + summary: Get domain forwarding + description: |- + Retrieve domain forwarding data. + + Use this endpoint to view current redirect configuration for domains. + operationId: domains_getDomainForwardingV1 + parameters: + - $ref: "#/components/parameters/domain" + responses: + "200": + description: Success response + content: + application/json: + schema: + $ref: "#/components/schemas/Domains.V1.Forwarding.ForwardingResource" + "401": + $ref: "#/components/responses/Common.Response.UnauthorizedResponse" + "500": + $ref: "#/components/responses/Common.Response.ErrorResponse" + delete: + tags: + - "Domains: Forwarding" + summary: Delete domain forwarding + description: |- + Delete domain forwarding data. + + Use this endpoint to remove redirect configuration from domains. + operationId: domains_deleteDomainForwardingV1 + parameters: + - $ref: "#/components/parameters/domain" + responses: + "200": + description: Success response + content: + application/json: + schema: + $ref: "#/components/schemas/Common.SuccessEmptyResource" + "401": + $ref: "#/components/responses/Common.Response.UnauthorizedResponse" + "500": + $ref: "#/components/responses/Common.Response.ErrorResponse" + /api/domains/v1/forwarding: + post: + tags: + - "Domains: Forwarding" + summary: Create domain forwarding + description: |- + Create domain forwarding configuration. + + Use this endpoint to set up domain redirects to other URLs. + operationId: domains_createDomainForwardingV1 + requestBody: + required: true + content: + application/json: + schema: + $ref: "#/components/schemas/Domains.V1.Forwarding.StoreRequest" + responses: + "200": + description: Success response + content: + application/json: + schema: + $ref: "#/components/schemas/Domains.V1.Forwarding.ForwardingResource" + "401": + $ref: "#/components/responses/Common.Response.UnauthorizedResponse" + "422": + $ref: "#/components/responses/Common.Response.UnprocessableContentResponse" + "500": + $ref: "#/components/responses/Common.Response.ErrorResponse" + /api/domains/v1/portfolio/{domain}/domain-lock: + put: + tags: + - "Domains: Portfolio" + summary: Enable domain lock + description: >- + Enable domain lock for the domain. + + + When domain lock is enabled, + + the domain cannot be transferred to another registrar without first + disabling the lock. + + + Use this endpoint to secure domains against unauthorized transfers. + operationId: domains_enableDomainLockV1 + parameters: + - $ref: "#/components/parameters/domain" + responses: + "200": + description: Success empty response + content: + application/json: + schema: + $ref: "#/components/schemas/Common.SuccessEmptyResource" + "401": + $ref: "#/components/responses/Common.Response.UnauthorizedResponse" + "500": + $ref: "#/components/responses/Common.Response.ErrorResponse" + delete: + tags: + - "Domains: Portfolio" + summary: Disable domain lock + description: >- + Disable domain lock for the domain. + + + Domain lock needs to be disabled before transferring the domain to + another registrar. + + + Use this endpoint to prepare domains for transfer to other registrars. + operationId: domains_disableDomainLockV1 + parameters: + - $ref: "#/components/parameters/domain" + responses: + "200": + description: Success empty response + content: + application/json: + schema: + $ref: "#/components/schemas/Common.SuccessEmptyResource" + "401": + $ref: "#/components/responses/Common.Response.UnauthorizedResponse" + "500": + $ref: "#/components/responses/Common.Response.ErrorResponse" + /api/domains/v1/portfolio/{domain}: + get: + tags: + - "Domains: Portfolio" + summary: Get domain details + description: |- + Retrieve detailed information for specified domain. + + Use this endpoint to view comprehensive domain configuration and status. + operationId: domains_getDomainDetailsV1 + parameters: + - $ref: "#/components/parameters/domain" + responses: + "200": + description: Success response + content: + application/json: + schema: + $ref: "#/components/schemas/Domains.V1.Domain.DomainExtendedResource" + "401": + $ref: "#/components/responses/Common.Response.UnauthorizedResponse" + "500": + $ref: "#/components/responses/Common.Response.ErrorResponse" + /api/domains/v1/portfolio: + get: + tags: + - "Domains: Portfolio" + summary: Get domain list + description: |- + Retrieve all domains associated with your account. + + Use this endpoint to view user's domain portfolio. + operationId: domains_getDomainListV1 + responses: + "200": + description: Success response + content: + application/json: + schema: + $ref: "#/components/schemas/Domains.V1.Domain.DomainCollection" + "401": + $ref: "#/components/responses/Common.Response.UnauthorizedResponse" + "500": + $ref: "#/components/responses/Common.Response.ErrorResponse" + post: + tags: + - "Domains: Portfolio" + summary: Purchase new domain + description: >- + Purchase and register a new domain name. + + + If registration fails, login to [hPanel](https://hpanel.hostinger.com/) + and check domain registration status. + + + If no payment method is provided, your default payment method will be + used automatically. + + + If no WHOIS information is provided, default contact information for + that TLD will be used. + + Before making request, ensure WHOIS information for desired TLD exists + in your account. + + + Some TLDs require `additional_details` to be provided and these will be + validated before completing purchase. + + + Use this endpoint to register new domains for users. + operationId: domains_purchaseNewDomainV1 + requestBody: + required: true + content: + application/json: + schema: + $ref: "#/components/schemas/Domains.V1.Portfolio.PurchaseRequest" + responses: + "200": + description: Success response + content: + application/json: + schema: + $ref: "#/components/schemas/Billing.V1.Order.OrderResource" + "401": + $ref: "#/components/responses/Common.Response.UnauthorizedResponse" + "422": + $ref: "#/components/responses/Common.Response.UnprocessableContentResponse" + "500": + $ref: "#/components/responses/Common.Response.ErrorResponse" + /api/domains/v1/portfolio/{domain}/privacy-protection: + put: + tags: + - "Domains: Portfolio" + summary: Enable privacy protection + description: >- + Enable privacy protection for the domain. + + + When privacy protection is enabled, domain owner's personal information + is hidden from public WHOIS database. + + + Use this endpoint to protect domain owner's personal information from + public view. + operationId: domains_enablePrivacyProtectionV1 + parameters: + - $ref: "#/components/parameters/domain" + responses: + "200": + description: Success empty response + content: + application/json: + schema: + $ref: "#/components/schemas/Common.SuccessEmptyResource" + "401": + $ref: "#/components/responses/Common.Response.UnauthorizedResponse" + "500": + $ref: "#/components/responses/Common.Response.ErrorResponse" + delete: + tags: + - "Domains: Portfolio" + summary: Disable privacy protection + description: >- + Disable privacy protection for the domain. + + + When privacy protection is disabled, domain owner's personal information + is visible in public WHOIS database. + + + Use this endpoint to make domain owner's information publicly visible. + operationId: domains_disablePrivacyProtectionV1 + parameters: + - $ref: "#/components/parameters/domain" + responses: + "200": + description: Success empty response + content: + application/json: + schema: + $ref: "#/components/schemas/Common.SuccessEmptyResource" + "401": + $ref: "#/components/responses/Common.Response.UnauthorizedResponse" + "500": + $ref: "#/components/responses/Common.Response.ErrorResponse" + /api/domains/v1/portfolio/{domain}/nameservers: + put: + tags: + - "Domains: Portfolio" + summary: Update domain nameservers + description: >- + Set nameservers for a specified domain. + + + Be aware, that improper nameserver configuration can lead to the domain + being unresolvable or unavailable. + + + Use this endpoint to configure custom DNS hosting for domains. + operationId: domains_updateDomainNameserversV1 + parameters: + - $ref: "#/components/parameters/domain" + requestBody: + required: true + content: + application/json: + schema: + $ref: "#/components/schemas/Domains.V1.Portfolio.UpdateNameserversRequest" + responses: + "200": + description: Success empty response + content: + application/json: + schema: + $ref: "#/components/schemas/Common.SuccessEmptyResource" + "401": + $ref: "#/components/responses/Common.Response.UnauthorizedResponse" + "422": + $ref: "#/components/responses/Common.Response.UnprocessableContentResponse" + "500": + $ref: "#/components/responses/Common.Response.ErrorResponse" + /api/domains/v1/whois/{whoisId}: + get: + tags: + - "Domains: WHOIS" + summary: Get WHOIS profile + description: |- + Retrieve a WHOIS contact profile. + + Use this endpoint to view domain registration contact information. + operationId: domains_getWHOISProfileV1 + parameters: + - $ref: "#/components/parameters/whoisId" + responses: + "200": + description: Success response + content: + application/json: + schema: + $ref: "#/components/schemas/Domains.V1.WHOIS.ProfileResource" + "401": + $ref: "#/components/responses/Common.Response.UnauthorizedResponse" + "500": + $ref: "#/components/responses/Common.Response.ErrorResponse" + delete: + tags: + - "Domains: WHOIS" + summary: Delete WHOIS profile + description: |- + Delete WHOIS contact profile. + + Use this endpoint to remove unused contact profiles from account. + operationId: domains_deleteWHOISProfileV1 + parameters: + - $ref: "#/components/parameters/whoisId" + responses: + "200": + description: Success response + content: + application/json: + schema: + $ref: "#/components/schemas/Common.SuccessEmptyResource" + "401": + $ref: "#/components/responses/Common.Response.UnauthorizedResponse" + "500": + $ref: "#/components/responses/Common.Response.ErrorResponse" + /api/domains/v1/whois: + get: + tags: + - "Domains: WHOIS" + summary: Get WHOIS profile list + description: >- + Retrieve WHOIS contact profiles. + + + Use this endpoint to view available contact profiles for domain + registration. + operationId: domains_getWHOISProfileListV1 + parameters: + - $ref: "#/components/parameters/tld" + responses: + "200": + description: Success response + content: + application/json: + schema: + $ref: "#/components/schemas/Domains.V1.WHOIS.ProfileCollection" + "401": + $ref: "#/components/responses/Common.Response.UnauthorizedResponse" + "500": + $ref: "#/components/responses/Common.Response.ErrorResponse" + post: + tags: + - "Domains: WHOIS" + summary: Create WHOIS profile + description: >- + Create WHOIS contact profile. + + + Use this endpoint to add new contact information for domain + registration. + operationId: domains_createWHOISProfileV1 + requestBody: + required: true + content: + application/json: + schema: + $ref: "#/components/schemas/Domains.V1.WHOIS.StoreRequest" + responses: + "200": + description: Success response + content: + application/json: + schema: + $ref: "#/components/schemas/Domains.V1.WHOIS.ProfileResource" + "401": + $ref: "#/components/responses/Common.Response.UnauthorizedResponse" + "422": + $ref: "#/components/responses/Common.Response.UnprocessableContentResponse" + "500": + $ref: "#/components/responses/Common.Response.ErrorResponse" + /api/domains/v1/whois/{whoisId}/usage: + get: + tags: + - "Domains: WHOIS" + summary: Get WHOIS profile usage + description: |- + Retrieve domain list where provided WHOIS contact profile is used. + + Use this endpoint to view which domains use specific contact profiles. + operationId: domains_getWHOISProfileUsageV1 + parameters: + - $ref: "#/components/parameters/whoisId" + responses: + "200": + description: Success response + content: + application/json: + schema: + $ref: "#/components/schemas/Domains.V1.WHOIS.ProfileUsageResource" + "401": + $ref: "#/components/responses/Common.Response.UnauthorizedResponse" + "500": + $ref: "#/components/responses/Common.Response.ErrorResponse" + /api/hosting/v1/datacenters: + get: + tags: + - "Hosting: Datacenters" + summary: List available datacenters + description: |- + Retrieve a list of datacenters available for setting up hosting plans + based on available datacenter capacity and hosting plan of your order. + The first item in the list is the best match for your specific order + requirements. + operationId: hosting_listAvailableDatacentersV1 + parameters: + - $ref: "#/components/parameters/order_id_required" + responses: + "200": + description: Success response + content: + application/json: + schema: + $ref: "#/components/schemas/Hosting.V1.Datacenter.DatacenterCollection" + "401": + $ref: "#/components/responses/Common.Response.UnauthorizedResponse" + "500": + $ref: "#/components/responses/Common.Response.ErrorResponse" + /api/hosting/v1/domains/free-subdomains: + post: + tags: + - "Hosting: Domains" + summary: Generate a free subdomain + description: >- + Generate a unique free subdomain that can be used for hosting services + without purchasing custom domains. + + Free subdomains allow you to start using hosting services immediately + + and you can always connect a custom domain to your site later. + operationId: hosting_generateAFreeSubdomainV1 + responses: + "200": + description: Success response + content: + application/json: + schema: + $ref: "#/components/schemas/Hosting.V1.Domains.FreeSubdomainResource" + "401": + $ref: "#/components/responses/Common.Response.UnauthorizedResponse" + "500": + $ref: "#/components/responses/Common.Response.ErrorResponse" + /api/hosting/v1/domains/verify-ownership: + post: + tags: + - "Hosting: Domains" + summary: Verify domain ownership + description: >- + Verify ownership of a single domain and return the verification status. + + + Use this endpoint to check if a domain is accessible for you before + using it for new websites. + + If the domain is accessible, the response will have `is_accessible: + true`. + + If not, add the given TXT record to your domain's DNS records and try + verifying again. + + Keep in mind that it may take up to 10 minutes for new TXT DNS records + to propagate. + + + Skip this verification when using Hostinger's free subdomains + (*.hostingersite.com). + operationId: hosting_verifyDomainOwnershipV1 + requestBody: + required: true + content: + application/json: + schema: + $ref: "#/components/schemas/Hosting.V1.Domains.VerifyOwnershipRequest" + responses: + "200": + description: Success response + content: + application/json: + schema: + $ref: "#/components/schemas/Hosting.V1.Domains.DomainAccessResource" + "401": + $ref: "#/components/responses/Common.Response.UnauthorizedResponse" + "422": + $ref: "#/components/responses/Common.Response.UnprocessableContentResponse" + "500": + $ref: "#/components/responses/Common.Response.ErrorResponse" + /api/hosting/v1/orders: + get: + tags: + - "Hosting: Orders" + summary: List orders + description: >- + Retrieve a paginated list of orders accessible to the authenticated + client. + + + This endpoint returns orders of your hosting accounts as well as orders + + of other client hosting accounts that have shared access with you. + + + Use the available query parameters to filter results by order statuses + + or specific order IDs for more targeted results. + operationId: hosting_listOrdersV1 + parameters: + - $ref: "#/components/parameters/page" + - $ref: "#/components/parameters/per_page" + - $ref: "#/components/parameters/statuses" + - $ref: "#/components/parameters/order_ids" + responses: + "200": + description: Success response + content: + application/json: + schema: + properties: + data: + $ref: "#/components/schemas/Hosting.V1.Orders.OrderCollection" + meta: + $ref: "#/components/schemas/Common.Schema.PaginationMetaSchema" + type: object + "401": + $ref: "#/components/responses/Common.Response.UnauthorizedResponse" + "500": + $ref: "#/components/responses/Common.Response.ErrorResponse" + /api/hosting/v1/websites: + get: + tags: + - "Hosting: Websites" + summary: List websites + description: >- + Retrieve a paginated list of websites (main and addon types) accessible + to the authenticated client. + + + This endpoint returns websites from your hosting accounts as well as + + websites from other client hosting accounts that have shared access + + with you. + + + Use the available query parameters to filter results by username, + + order ID, enabled status, or domain name for more targeted results. + operationId: hosting_listWebsitesV1 + parameters: + - $ref: "#/components/parameters/page" + - $ref: "#/components/parameters/per_page" + - $ref: "#/components/parameters/username" + - $ref: "#/components/parameters/order_id" + - $ref: "#/components/parameters/is_enabled" + - $ref: "#/components/parameters/domain_filter" + responses: + "200": + description: Success response + content: + application/json: + schema: + properties: + data: + $ref: "#/components/schemas/Hosting.V1.Websites.WebsiteCollection" + meta: + $ref: "#/components/schemas/Common.Schema.PaginationMetaSchema" + type: object + "401": + $ref: "#/components/responses/Common.Response.UnauthorizedResponse" + "500": + $ref: "#/components/responses/Common.Response.ErrorResponse" + post: + tags: + - "Hosting: Websites" + summary: Create website + description: >- + Create a new website for the authenticated client. + + + Provide the domain name and associated order ID to create a new website. + + The datacenter_code parameter is required when creating the first + website + + on a new hosting plan - this will set up and configure new hosting + account + + in the selected datacenter. + + + Subsequent websites will be hosted on the same datacenter automatically. + + + Website creation takes up to a few minutes to complete. Check the + + websites list endpoint to see when your new website becomes available. + operationId: hosting_createWebsiteV1 + requestBody: + required: true + content: + application/json: + schema: + $ref: "#/components/schemas/Hosting.V1.Websites.CreateWebsiteRequest" + responses: + "200": + description: Success empty response + content: + application/json: + schema: + $ref: "#/components/schemas/Common.SuccessEmptyResource" + "401": + $ref: "#/components/responses/Common.Response.UnauthorizedResponse" + "422": + $ref: "#/components/responses/Common.Response.UnprocessableContentResponse" + "500": + $ref: "#/components/responses/Common.Response.ErrorResponse" + /api/reach/v1/contacts/{uuid}: + delete: + tags: + - "Reach: Contacts" + summary: Delete a contact + description: >- + Delete a contact with the specified UUID. + + + This endpoint permanently removes a contact from the email marketing + system. + operationId: reach_deleteAContactV1 + parameters: + - $ref: "#/components/parameters/uuid" + responses: + "200": + description: Success response + content: + application/json: + schema: + $ref: "#/components/schemas/Common.SuccessEmptyResource" + "401": + $ref: "#/components/responses/Common.Response.UnauthorizedResponse" + "500": + $ref: "#/components/responses/Common.Response.ErrorResponse" + /api/reach/v1/contacts/groups: + get: + tags: + - "Reach: Contacts" + summary: List contact groups + description: >- + Get a list of all contact groups. + + + This endpoint returns a list of contact groups that can be used to + organize contacts. + operationId: reach_listContactGroupsV1 + responses: + "200": + description: Success response + content: + application/json: + schema: + $ref: "#/components/schemas/Reach.V1.Contacts.Groups.ContactGroupCollection" + "401": + $ref: "#/components/responses/Common.Response.UnauthorizedResponse" + "500": + $ref: "#/components/responses/Common.Response.ErrorResponse" + deprecated: true + x-scalar-ignore: true + /api/reach/v1/contacts: + get: + tags: + - "Reach: Contacts" + summary: List contacts + description: >- + Get a list of contacts, optionally filtered by group and subscription + status. + + + This endpoint returns a paginated list of contacts with their basic + information. + + You can filter contacts by group UUID and subscription status. + operationId: reach_listContactsV1 + parameters: + - $ref: "#/components/parameters/group_uuid" + - $ref: "#/components/parameters/subscription_status" + - $ref: "#/components/parameters/page" + responses: + "200": + description: Success response + content: + application/json: + schema: + properties: + data: + $ref: "#/components/schemas/Reach.V1.Contacts.ContactCollection" + meta: + $ref: "#/components/schemas/Common.Schema.PaginationMetaSchema" + type: object + "401": + $ref: "#/components/responses/Common.Response.UnauthorizedResponse" + "500": + $ref: "#/components/responses/Common.Response.ErrorResponse" + post: + tags: + - "Reach: Contacts" + summary: Create a new contact + description: >- + Create a new contact in the email marketing system. + + + This endpoint allows you to create a new contact with basic information + like name, email, and surname. + + + If double opt-in is enabled, + + the contact will be created with a pending status and a confirmation + email will be sent. + operationId: reach_createANewContactV1 + requestBody: + required: true + content: + application/json: + schema: + $ref: "#/components/schemas/Reach.V1.Contacts.StoreRequest" + responses: + "200": + description: Success empty response + content: + application/json: + schema: + $ref: "#/components/schemas/Common.SuccessEmptyResource" + "401": + $ref: "#/components/responses/Common.Response.UnauthorizedResponse" + "422": + $ref: "#/components/responses/Common.Response.UnprocessableContentResponse" + "500": + $ref: "#/components/responses/Common.Response.ErrorResponse" + deprecated: true + x-scalar-ignore: true + /api/reach/v1/segmentation/segments: + get: + tags: + - "Reach: Segments" + summary: List segments + description: >- + Get a list of all contact segments. + + + This endpoint returns a list of contact segments that can be used to + organize contacts. + operationId: reach_listSegmentsV1 + responses: + "200": + description: Success response + content: + application/json: + schema: + $ref: "#/components/schemas/Reach.V1.Contacts.Segments.ContactSegmentCollection" + "401": + $ref: "#/components/responses/Common.Response.UnauthorizedResponse" + "500": + $ref: "#/components/responses/Common.Response.ErrorResponse" + post: + tags: + - "Reach: Segments" + summary: Create a new contact segment + description: >- + Create a new contact segment. + + + This endpoint allows creating a new contact segment that can be used to + organize contacts. + + The segment can be configured with specific criteria like email, name, + subscription status, etc. + operationId: reach_createANewContactSegmentV1 + requestBody: + required: true + content: + application/json: + schema: + $ref: "#/components/schemas/Reach.V1.Contacts.Segments.StoreRequest" + responses: + "200": + description: Success response + content: + application/json: + schema: + $ref: "#/components/schemas/Reach.V1.Contacts.Segments.SegmentResource" + "401": + $ref: "#/components/responses/Common.Response.UnauthorizedResponse" + "422": + $ref: "#/components/responses/Common.Response.UnprocessableContentResponse" + "500": + $ref: "#/components/responses/Common.Response.ErrorResponse" + /api/reach/v1/segmentation/segments/{segmentUuid}/contacts: + get: + tags: + - "Reach: Segments" + summary: List segment contacts + description: >- + Retrieve contacts associated with a specific segment. + + + This endpoint allows you to fetch and filter contacts that belong to a + particular segment, + + identified by its UUID. + operationId: reach_listSegmentContactsV1 + parameters: + - $ref: "#/components/parameters/segmentUuid" + - $ref: "#/components/parameters/page" + - $ref: "#/components/parameters/per_page" + responses: + "200": + description: Success response + content: + application/json: + schema: + properties: + data: + $ref: "#/components/schemas/Reach.V1.Contacts.Segments.SegmentationContactColle\ + ction" + meta: + $ref: "#/components/schemas/Common.Schema.PaginationMetaSchema" + type: object + "401": + $ref: "#/components/responses/Common.Response.UnauthorizedResponse" + "500": + $ref: "#/components/responses/Common.Response.ErrorResponse" + /api/reach/v1/segmentation/segments/{segmentUuid}: + get: + tags: + - "Reach: Segments" + summary: Get segment details + description: >- + Get details of a specific segment. + + + This endpoint retrieves information about a single segment identified by + UUID. + + Segments are used to organize and group contacts based on specific + criteria. + operationId: reach_getSegmentDetailsV1 + parameters: + - $ref: "#/components/parameters/segmentUuid" + responses: + "200": + description: Success response + content: + application/json: + schema: + $ref: "#/components/schemas/Reach.V1.Contacts.Segments.SegmentResource" + "401": + $ref: "#/components/responses/Common.Response.UnauthorizedResponse" + "500": + $ref: "#/components/responses/Common.Response.ErrorResponse" + /api/reach/v1/profiles/{profileUuid}/contacts: + post: + tags: + - "Reach: Contacts" + summary: Create new contacts + description: >- + Create a new contact in the email marketing system. + + + This endpoint allows you to create a new contact with basic information + like name, email, and surname. + + + If double opt-in is enabled, the contact will be created with a pending + status + + and a confirmation email will be sent. + operationId: reach_createNewContactsV1 + parameters: + - $ref: "#/components/parameters/profileUuid" + requestBody: + required: true + content: + application/json: + schema: + $ref: "#/components/schemas/Reach.V1.Contacts.StoreRequest" + responses: + "200": + description: Success empty response + content: + application/json: + schema: + $ref: "#/components/schemas/Common.SuccessEmptyResource" + "401": + $ref: "#/components/responses/Common.Response.UnauthorizedResponse" + "422": + $ref: "#/components/responses/Common.Response.UnprocessableContentResponse" + "500": + $ref: "#/components/responses/Common.Response.ErrorResponse" + /api/reach/v1/profiles: + get: + tags: + - "Reach: Profiles" + summary: List Profiles + description: This endpoint returns all profiles available to the client, + including their basic information. + operationId: reach_listProfilesV1 + responses: + "200": + description: Success response + content: + application/json: + schema: + $ref: "#/components/schemas/Reach.V1.Profiles.ProfileCollection" + "401": + $ref: "#/components/responses/Common.Response.UnauthorizedResponse" + "500": + $ref: "#/components/responses/Common.Response.ErrorResponse" + /api/vps/v1/data-centers: + get: + tags: + - "VPS: Data centers" + summary: Get data center list + description: >- + Retrieve all available data centers. + + + Use this endpoint to view location options before deploying VPS + instances. + operationId: VPS_getDataCenterListV1 + responses: + "200": + description: Success response + content: + application/json: + schema: + $ref: "#/components/schemas/VPS.V1.DataCenter.DataCenterCollection" + "401": + $ref: "#/components/responses/Common.Response.UnauthorizedResponse" + "500": + $ref: "#/components/responses/Common.Response.ErrorResponse" + /api/vps/v1/virtual-machines/{virtualMachineId}/docker/{projectName}/containers: + get: + tags: + - "VPS: Docker Manager" + summary: Get project containers + description: >- + Retrieves a list of all containers belonging to a specific Docker + Compose project on the virtual machine. + + + This endpoint returns detailed information about each container + including + + their current status, port mappings, and runtime configuration. + + + Use this to monitor the health and state of all services within your + Docker Compose project. + operationId: VPS_getProjectContainersV1 + parameters: + - $ref: "#/components/parameters/virtualMachineId" + - $ref: "#/components/parameters/projectName" + responses: + "200": + description: Success response + content: + application/json: + schema: + $ref: "#/components/schemas/VPS.V1.DockerManager.ContainerCollection" + "401": + $ref: "#/components/responses/Common.Response.UnauthorizedResponse" + "422": + $ref: "#/components/responses/Common.Response.UnprocessableContentResponse" + "500": + $ref: "#/components/responses/Common.Response.ErrorResponse" + x-scalar-stability: experimental + /api/vps/v1/virtual-machines/{virtualMachineId}/docker/{projectName}: + get: + tags: + - "VPS: Docker Manager" + summary: Get project contents + description: >- + Retrieves the complete project information including the + docker-compose.yml + + file contents, project metadata, and current deployment status. + + + This endpoint provides the full configuration and state details of a + specific Docker Compose project. + + + Use this to inspect project settings, review the compose file, or check + the overall project health. + operationId: VPS_getProjectContentsV1 + parameters: + - $ref: "#/components/parameters/virtualMachineId" + - $ref: "#/components/parameters/projectName" + responses: + "200": + description: Success response + content: + application/json: + schema: + $ref: "#/components/schemas/VPS.V1.DockerManager.ContentResource" + "401": + $ref: "#/components/responses/Common.Response.UnauthorizedResponse" + "422": + $ref: "#/components/responses/Common.Response.UnprocessableContentResponse" + "500": + $ref: "#/components/responses/Common.Response.ErrorResponse" + x-scalar-stability: experimental + /api/vps/v1/virtual-machines/{virtualMachineId}/docker/{projectName}/down: + delete: + tags: + - "VPS: Docker Manager" + summary: Delete project + description: >- + Completely removes a Docker Compose project from the virtual machine, + stopping all containers and cleaning up + + associated resources including networks, volumes, and images. + + + This operation is irreversible and will delete all project data. + + + Use this when you want to permanently remove a project and free up + system resources. + operationId: VPS_deleteProjectV1 + parameters: + - $ref: "#/components/parameters/virtualMachineId" + - $ref: "#/components/parameters/projectName" + responses: + "200": + description: Success response + content: + application/json: + schema: + $ref: "#/components/schemas/VPS.V1.Action.ActionResource" + "401": + $ref: "#/components/responses/Common.Response.UnauthorizedResponse" + "422": + $ref: "#/components/responses/Common.Response.UnprocessableContentResponse" + "500": + $ref: "#/components/responses/Common.Response.ErrorResponse" + x-scalar-stability: experimental + /api/vps/v1/virtual-machines/{virtualMachineId}/docker: + get: + tags: + - "VPS: Docker Manager" + summary: Get project list + description: >- + Retrieves a list of all Docker Compose projects currently deployed on + the virtual machine. + + + This endpoint returns basic information about each project including + name, + + status, file path and list of containers with details about their names, + + image, status, health and ports. Container stats are omitted in this + + endpoint. If you need to get detailed information about container with + + stats included, use the `Get project containers` endpoint. + + + Use this to get an overview of all Docker projects on your VPS instance. + operationId: VPS_getProjectListV1 + parameters: + - $ref: "#/components/parameters/virtualMachineId" + responses: + "200": + description: Success response + content: + application/json: + schema: + $ref: "#/components/schemas/VPS.V1.DockerManager.ProjectCollection" + "401": + $ref: "#/components/responses/Common.Response.UnauthorizedResponse" + "422": + $ref: "#/components/responses/Common.Response.UnprocessableContentResponse" + "500": + $ref: "#/components/responses/Common.Response.ErrorResponse" + x-scalar-stability: experimental + post: + tags: + - "VPS: Docker Manager" + summary: Create new project + description: >- + Deploy new project from docker-compose.yaml contents or download + contents from URL. + + + URL can be Github repository url in format + https://github.com/[user]/[repo] + + and it will be automatically resolved to docker-compose.yaml file in + + master branch. Any other URL provided must return docker-compose.yaml + + file contents. + + + If project with the same name already exists, existing project will be + replaced. + operationId: VPS_createNewProjectV1 + parameters: + - $ref: "#/components/parameters/virtualMachineId" + requestBody: + required: true + content: + application/json: + schema: + $ref: "#/components/schemas/VPS.V1.VirtualMachine.DockerManager.UpRequest" + responses: + "200": + description: Success response + content: + application/json: + schema: + $ref: "#/components/schemas/VPS.V1.Action.ActionResource" + "401": + $ref: "#/components/responses/Common.Response.UnauthorizedResponse" + "422": + $ref: "#/components/responses/Common.Response.UnprocessableContentResponse" + "500": + $ref: "#/components/responses/Common.Response.ErrorResponse" + x-scalar-stability: experimental + /api/vps/v1/virtual-machines/{virtualMachineId}/docker/{projectName}/logs: + get: + tags: + - "VPS: Docker Manager" + summary: Get project logs + description: >- + Retrieves aggregated log entries from all services within a Docker + Compose project. + + + This endpoint returns recent log output from each container, organized + by service name with timestamps. + + The response contains the last 300 log entries across all services. + + + Use this for debugging, monitoring application behavior, and + + troubleshooting issues across your entire project stack. + operationId: VPS_getProjectLogsV1 + parameters: + - $ref: "#/components/parameters/virtualMachineId" + - $ref: "#/components/parameters/projectName" + responses: + "200": + description: Success response + content: + application/json: + schema: + $ref: "#/components/schemas/VPS.V1.DockerManager.LogsCollection" + "401": + $ref: "#/components/responses/Common.Response.UnauthorizedResponse" + "422": + $ref: "#/components/responses/Common.Response.UnprocessableContentResponse" + "500": + $ref: "#/components/responses/Common.Response.ErrorResponse" + x-scalar-stability: experimental + /api/vps/v1/virtual-machines/{virtualMachineId}/docker/{projectName}/restart: + post: + tags: + - "VPS: Docker Manager" + summary: Restart project + description: >- + Restarts all services in a Docker Compose project by stopping and + starting + + containers in the correct dependency order. + + + This operation preserves data volumes and network configurations while + refreshing the running containers. + + + Use this to apply configuration changes or recover from service + failures. + operationId: VPS_restartProjectV1 + parameters: + - $ref: "#/components/parameters/virtualMachineId" + - $ref: "#/components/parameters/projectName" + responses: + "200": + description: Success response + content: + application/json: + schema: + $ref: "#/components/schemas/VPS.V1.Action.ActionResource" + "401": + $ref: "#/components/responses/Common.Response.UnauthorizedResponse" + "422": + $ref: "#/components/responses/Common.Response.UnprocessableContentResponse" + "500": + $ref: "#/components/responses/Common.Response.ErrorResponse" + x-scalar-stability: experimental + /api/vps/v1/virtual-machines/{virtualMachineId}/docker/{projectName}/start: + post: + tags: + - "VPS: Docker Manager" + summary: Start project + description: >- + Starts all services in a Docker Compose project that are currently + stopped. + + + This operation brings up containers in the correct dependency order as + defined in the compose file. + + + Use this to resume a project that was previously stopped or to start + services after a system reboot. + operationId: VPS_startProjectV1 + parameters: + - $ref: "#/components/parameters/virtualMachineId" + - $ref: "#/components/parameters/projectName" + responses: + "200": + description: Success response + content: + application/json: + schema: + $ref: "#/components/schemas/VPS.V1.Action.ActionResource" + "401": + $ref: "#/components/responses/Common.Response.UnauthorizedResponse" + "422": + $ref: "#/components/responses/Common.Response.UnprocessableContentResponse" + "500": + $ref: "#/components/responses/Common.Response.ErrorResponse" + x-scalar-stability: experimental + /api/vps/v1/virtual-machines/{virtualMachineId}/docker/{projectName}/stop: + post: + tags: + - "VPS: Docker Manager" + summary: Stop project + description: >- + Stops all running services in a Docker Compose project while preserving + + container configurations and data volumes. + + + This operation gracefully shuts down containers in reverse dependency + order. + + + Use this to temporarily halt a project without removing data or + configurations. + operationId: VPS_stopProjectV1 + parameters: + - $ref: "#/components/parameters/virtualMachineId" + - $ref: "#/components/parameters/projectName" + responses: + "200": + description: Success response + content: + application/json: + schema: + $ref: "#/components/schemas/VPS.V1.Action.ActionResource" + "401": + $ref: "#/components/responses/Common.Response.UnauthorizedResponse" + "422": + $ref: "#/components/responses/Common.Response.UnprocessableContentResponse" + "500": + $ref: "#/components/responses/Common.Response.ErrorResponse" + x-scalar-stability: experimental + /api/vps/v1/virtual-machines/{virtualMachineId}/docker/{projectName}/update: + post: + tags: + - "VPS: Docker Manager" + summary: Update project + description: >- + Updates a Docker Compose project by pulling the latest image versions + and + + recreating containers with new configurations. + + + This operation preserves data volumes while applying changes from the + compose file. + + + Use this to deploy application updates, apply configuration changes, or + + refresh container images to their latest versions. + operationId: VPS_updateProjectV1 + parameters: + - $ref: "#/components/parameters/virtualMachineId" + - $ref: "#/components/parameters/projectName" + responses: + "200": + description: Success response + content: + application/json: + schema: + $ref: "#/components/schemas/VPS.V1.Action.ActionResource" + "401": + $ref: "#/components/responses/Common.Response.UnauthorizedResponse" + "422": + $ref: "#/components/responses/Common.Response.UnprocessableContentResponse" + "500": + $ref: "#/components/responses/Common.Response.ErrorResponse" + x-scalar-stability: experimental + /api/vps/v1/firewall/{firewallId}/activate/{virtualMachineId}: + post: + tags: + - "VPS: Firewall" + summary: Activate firewall + description: |- + Activate a firewall for a specified virtual machine. + + Only one firewall can be active for a virtual machine at a time. + + Use this endpoint to apply firewall rules to VPS instances. + operationId: VPS_activateFirewallV1 + parameters: + - $ref: "#/components/parameters/firewallId" + - $ref: "#/components/parameters/virtualMachineId" + responses: + "200": + description: Success response + content: + application/json: + schema: + $ref: "#/components/schemas/VPS.V1.Action.ActionResource" + "401": + $ref: "#/components/responses/Common.Response.UnauthorizedResponse" + "422": + $ref: "#/components/responses/Common.Response.UnprocessableContentResponse" + "500": + $ref: "#/components/responses/Common.Response.ErrorResponse" + /api/vps/v1/firewall/{firewallId}/deactivate/{virtualMachineId}: + post: + tags: + - "VPS: Firewall" + summary: Deactivate firewall + description: |- + Deactivate a firewall for a specified virtual machine. + + Use this endpoint to remove firewall protection from VPS instances. + operationId: VPS_deactivateFirewallV1 + parameters: + - $ref: "#/components/parameters/firewallId" + - $ref: "#/components/parameters/virtualMachineId" + responses: + "200": + description: Success response + content: + application/json: + schema: + $ref: "#/components/schemas/VPS.V1.Action.ActionResource" + "401": + $ref: "#/components/responses/Common.Response.UnauthorizedResponse" + "422": + $ref: "#/components/responses/Common.Response.UnprocessableContentResponse" + "500": + $ref: "#/components/responses/Common.Response.ErrorResponse" + /api/vps/v1/firewall/{firewallId}: + get: + tags: + - "VPS: Firewall" + summary: Get firewall details + description: |- + Retrieve firewall by its ID and rules associated with it. + + Use this endpoint to view specific firewall configuration and rules. + operationId: VPS_getFirewallDetailsV1 + parameters: + - $ref: "#/components/parameters/firewallId" + responses: + "200": + description: Success response + content: + application/json: + schema: + $ref: "#/components/schemas/VPS.V1.Firewall.FirewallResource" + "401": + $ref: "#/components/responses/Common.Response.UnauthorizedResponse" + "500": + $ref: "#/components/responses/Common.Response.ErrorResponse" + delete: + tags: + - "VPS: Firewall" + summary: Delete firewall + description: >- + Delete a specified firewall. + + + Any virtual machine that has this firewall activated will automatically + have it deactivated. + + + Use this endpoint to remove unused firewall configurations. + operationId: VPS_deleteFirewallV1 + parameters: + - $ref: "#/components/parameters/firewallId" + responses: + "200": + description: Success empty response + content: + application/json: + schema: + $ref: "#/components/schemas/Common.SuccessEmptyResource" + "401": + $ref: "#/components/responses/Common.Response.UnauthorizedResponse" + "500": + $ref: "#/components/responses/Common.Response.ErrorResponse" + /api/vps/v1/firewall: + get: + tags: + - "VPS: Firewall" + summary: Get firewall list + description: |- + Retrieve all available firewalls. + + Use this endpoint to view existing firewall configurations. + operationId: VPS_getFirewallListV1 + parameters: + - $ref: "#/components/parameters/page" + responses: + "200": + description: Success response + content: + application/json: + schema: + properties: + data: + $ref: "#/components/schemas/VPS.V1.Firewall.FirewallCollection" + meta: + $ref: "#/components/schemas/Common.Schema.PaginationMetaSchema" + type: object + "401": + $ref: "#/components/responses/Common.Response.UnauthorizedResponse" + "500": + $ref: "#/components/responses/Common.Response.ErrorResponse" + post: + tags: + - "VPS: Firewall" + summary: Create new firewall + description: >- + Create a new firewall. + + + Use this endpoint to set up new firewall configurations for VPS + security. + operationId: VPS_createNewFirewallV1 + requestBody: + required: true + content: + application/json: + schema: + $ref: "#/components/schemas/VPS.V1.Firewall.StoreRequest" + responses: + "200": + description: Success response + content: + application/json: + schema: + $ref: "#/components/schemas/VPS.V1.Firewall.FirewallResource" + "401": + $ref: "#/components/responses/Common.Response.UnauthorizedResponse" + "422": + $ref: "#/components/responses/Common.Response.UnprocessableContentResponse" + "500": + $ref: "#/components/responses/Common.Response.ErrorResponse" + /api/vps/v1/firewall/{firewallId}/rules/{ruleId}: + put: + tags: + - "VPS: Firewall" + summary: Update firewall rule + description: >- + Update a specific firewall rule from a specified firewall. + + + Any virtual machine that has this firewall activated will lose sync with + the firewall + + and will have to be synced again manually. + + + Use this endpoint to modify existing firewall rules. + operationId: VPS_updateFirewallRuleV1 + parameters: + - $ref: "#/components/parameters/firewallId" + - $ref: "#/components/parameters/ruleId" + requestBody: + required: true + content: + application/json: + schema: + $ref: "#/components/schemas/VPS.V1.Firewall.Rules.StoreRequest" + responses: + "200": + description: Success response + content: + application/json: + schema: + $ref: "#/components/schemas/VPS.V1.Firewall.FirewallRuleResource" + "401": + $ref: "#/components/responses/Common.Response.UnauthorizedResponse" + "422": + $ref: "#/components/responses/Common.Response.UnprocessableContentResponse" + "500": + $ref: "#/components/responses/Common.Response.ErrorResponse" + delete: + tags: + - "VPS: Firewall" + summary: Delete firewall rule + description: >- + Delete a specific firewall rule from a specified firewall. + + + Any virtual machine that has this firewall activated will lose sync with + the firewall + + and will have to be synced again manually. + + + Use this endpoint to remove specific firewall rules. + operationId: VPS_deleteFirewallRuleV1 + parameters: + - $ref: "#/components/parameters/firewallId" + - $ref: "#/components/parameters/ruleId" + responses: + "200": + description: Success empty response + content: + application/json: + schema: + $ref: "#/components/schemas/Common.SuccessEmptyResource" + "401": + $ref: "#/components/responses/Common.Response.UnauthorizedResponse" + "500": + $ref: "#/components/responses/Common.Response.ErrorResponse" + /api/vps/v1/firewall/{firewallId}/rules: + post: + tags: + - "VPS: Firewall" + summary: Create firewall rule + description: >- + Create new firewall rule for a specified firewall. + + + By default, the firewall drops all incoming traffic, + + which means you must add accept rules for all ports you want to use. + + + Any virtual machine that has this firewall activated will lose sync with + the firewall + + and will have to be synced again manually. + + + Use this endpoint to add new security rules to firewalls. + operationId: VPS_createFirewallRuleV1 + parameters: + - $ref: "#/components/parameters/firewallId" + requestBody: + required: true + content: + application/json: + schema: + $ref: "#/components/schemas/VPS.V1.Firewall.Rules.StoreRequest" + responses: + "200": + description: Success response + content: + application/json: + schema: + $ref: "#/components/schemas/VPS.V1.Firewall.FirewallRuleResource" + "401": + $ref: "#/components/responses/Common.Response.UnauthorizedResponse" + "422": + $ref: "#/components/responses/Common.Response.UnprocessableContentResponse" + "500": + $ref: "#/components/responses/Common.Response.ErrorResponse" + /api/vps/v1/firewall/{firewallId}/sync/{virtualMachineId}: + post: + tags: + - "VPS: Firewall" + summary: Sync firewall + description: >- + Sync a firewall for a specified virtual machine. + + + Firewall can lose sync with virtual machine if the firewall has new + rules added, removed or updated. + + + Use this endpoint to apply updated firewall rules to VPS instances. + operationId: VPS_syncFirewallV1 + parameters: + - $ref: "#/components/parameters/firewallId" + - $ref: "#/components/parameters/virtualMachineId" + responses: + "200": + description: Success response + content: + application/json: + schema: + $ref: "#/components/schemas/VPS.V1.Action.ActionResource" + "401": + $ref: "#/components/responses/Common.Response.UnauthorizedResponse" + "422": + $ref: "#/components/responses/Common.Response.UnprocessableContentResponse" + "500": + $ref: "#/components/responses/Common.Response.ErrorResponse" + /api/vps/v1/post-install-scripts/{postInstallScriptId}: + get: + tags: + - "VPS: Post-install scripts" + summary: Get post-install script + description: |- + Retrieve post-install script by its ID. + + Use this endpoint to view specific automation script details. + operationId: VPS_getPostInstallScriptV1 + parameters: + - $ref: "#/components/parameters/postInstallScriptId" + responses: + "200": + description: Success response + content: + application/json: + schema: + $ref: "#/components/schemas/VPS.V1.PostInstallScript.PostInstallScriptResource" + "401": + $ref: "#/components/responses/Common.Response.UnauthorizedResponse" + "500": + $ref: "#/components/responses/Common.Response.ErrorResponse" + put: + tags: + - "VPS: Post-install scripts" + summary: Update post-install script + description: |- + Update a specific post-install script. + + Use this endpoint to modify existing automation scripts. + operationId: VPS_updatePostInstallScriptV1 + parameters: + - $ref: "#/components/parameters/postInstallScriptId" + requestBody: + required: true + content: + application/json: + schema: + $ref: "#/components/schemas/VPS.V1.PostInstallScript.StoreRequest" + responses: + "200": + description: Success response + content: + application/json: + schema: + $ref: "#/components/schemas/VPS.V1.PostInstallScript.PostInstallScriptResource" + "401": + $ref: "#/components/responses/Common.Response.UnauthorizedResponse" + "422": + $ref: "#/components/responses/Common.Response.UnprocessableContentResponse" + "500": + $ref: "#/components/responses/Common.Response.ErrorResponse" + delete: + tags: + - "VPS: Post-install scripts" + summary: Delete post-install script + description: |- + Delete a post-install script from your account. + + Use this endpoint to remove unused automation scripts. + operationId: VPS_deletePostInstallScriptV1 + parameters: + - $ref: "#/components/parameters/postInstallScriptId" + responses: + "200": + description: Success empty response + content: + application/json: + schema: + $ref: "#/components/schemas/Common.SuccessEmptyResource" + "401": + $ref: "#/components/responses/Common.Response.UnauthorizedResponse" + "500": + $ref: "#/components/responses/Common.Response.ErrorResponse" + /api/vps/v1/post-install-scripts: + get: + tags: + - "VPS: Post-install scripts" + summary: Get post-install scripts + description: >- + Retrieve post-install scripts associated with your account. + + + Use this endpoint to view available automation scripts for VPS + deployment. + operationId: VPS_getPostInstallScriptsV1 + parameters: + - $ref: "#/components/parameters/page" + responses: + "200": + description: Success response + content: + application/json: + schema: + properties: + data: + $ref: "#/components/schemas/VPS.V1.PostInstallScript.PostInstallScriptCollectio\ + n" + meta: + $ref: "#/components/schemas/Common.Schema.PaginationMetaSchema" + type: object + "401": + $ref: "#/components/responses/Common.Response.UnauthorizedResponse" + "500": + $ref: "#/components/responses/Common.Response.ErrorResponse" + post: + tags: + - "VPS: Post-install scripts" + summary: Create post-install script + description: >- + Add a new post-install script to your account, which can then be used + after virtual machine installation. + + + The script contents will be saved to the file `/post_install` with + executable attribute set + + and will be executed once virtual machine is installed. + + The output of the script will be redirected to `/post_install.log`. + Maximum script size is 48KB. + + + Use this endpoint to create automation scripts for VPS setup tasks. + operationId: VPS_createPostInstallScriptV1 + requestBody: + required: true + content: + application/json: + schema: + $ref: "#/components/schemas/VPS.V1.PostInstallScript.StoreRequest" + responses: + "200": + description: Success response + content: + application/json: + schema: + $ref: "#/components/schemas/VPS.V1.PostInstallScript.PostInstallScriptResource" + "401": + $ref: "#/components/responses/Common.Response.UnauthorizedResponse" + "422": + $ref: "#/components/responses/Common.Response.UnprocessableContentResponse" + "500": + $ref: "#/components/responses/Common.Response.ErrorResponse" + /api/vps/v1/public-keys/attach/{virtualMachineId}: + post: + tags: + - "VPS: Public Keys" + summary: Attach public key + description: >- + Attach existing public keys from your account to a specified virtual + machine. + + + Multiple keys can be attached to a single virtual machine. + + + Use this endpoint to enable SSH key authentication for VPS instances. + operationId: VPS_attachPublicKeyV1 + parameters: + - $ref: "#/components/parameters/virtualMachineId" + requestBody: + required: true + content: + application/json: + schema: + $ref: "#/components/schemas/VPS.V1.PublicKey.AttachRequest" + responses: + "200": + description: Success response + content: + application/json: + schema: + $ref: "#/components/schemas/VPS.V1.Action.ActionResource" + "401": + $ref: "#/components/responses/Common.Response.UnauthorizedResponse" + "422": + $ref: "#/components/responses/Common.Response.UnprocessableContentResponse" + "500": + $ref: "#/components/responses/Common.Response.ErrorResponse" + /api/vps/v1/public-keys/{publicKeyId}: + delete: + tags: + - "VPS: Public Keys" + summary: Delete public key + description: >- + Delete a public key from your account. + + + **Deleting public key from account does not remove it from virtual + machine** + + Use this endpoint to remove unused SSH keys from account. + operationId: VPS_deletePublicKeyV1 + parameters: + - $ref: "#/components/parameters/publicKeyId" + responses: + "200": + description: Success empty response + content: + application/json: + schema: + $ref: "#/components/schemas/Common.SuccessEmptyResource" + "401": + $ref: "#/components/responses/Common.Response.UnauthorizedResponse" + "500": + $ref: "#/components/responses/Common.Response.ErrorResponse" + /api/vps/v1/public-keys: + get: + tags: + - "VPS: Public Keys" + summary: Get public keys + description: |- + Retrieve public keys associated with your account. + + Use this endpoint to view available SSH keys for VPS authentication. + operationId: VPS_getPublicKeysV1 + parameters: + - $ref: "#/components/parameters/page" + responses: + "200": + description: Success response + content: + application/json: + schema: + properties: + data: + $ref: "#/components/schemas/VPS.V1.PublicKey.PublicKeyCollection" + meta: + $ref: "#/components/schemas/Common.Schema.PaginationMetaSchema" + type: object + "401": + $ref: "#/components/responses/Common.Response.UnauthorizedResponse" + "500": + $ref: "#/components/responses/Common.Response.ErrorResponse" + post: + tags: + - "VPS: Public Keys" + summary: Create public key + description: |- + Add a new public key to your account. + + Use this endpoint to register SSH keys for VPS authentication. + operationId: VPS_createPublicKeyV1 + requestBody: + required: true + content: + application/json: + schema: + $ref: "#/components/schemas/VPS.V1.PublicKey.StoreRequest" + responses: + "200": + description: Success response + content: + application/json: + schema: + $ref: "#/components/schemas/VPS.V1.PublicKey.PublicKeyResource" + "401": + $ref: "#/components/responses/Common.Response.UnauthorizedResponse" + "422": + $ref: "#/components/responses/Common.Response.UnprocessableContentResponse" + "500": + $ref: "#/components/responses/Common.Response.ErrorResponse" + /api/vps/v1/templates/{templateId}: + get: + tags: + - "VPS: OS Templates" + summary: Get template details + description: >- + Retrieve detailed information about a specific OS template for virtual + machines. + + + Use this endpoint to view specific template specifications before + deployment. + operationId: VPS_getTemplateDetailsV1 + parameters: + - $ref: "#/components/parameters/templateId" + responses: + "200": + description: Success response + content: + application/json: + schema: + $ref: "#/components/schemas/VPS.V1.Template.TemplateResource" + "401": + $ref: "#/components/responses/Common.Response.UnauthorizedResponse" + "500": + $ref: "#/components/responses/Common.Response.ErrorResponse" + /api/vps/v1/templates: + get: + tags: + - "VPS: OS Templates" + summary: Get templates + description: >- + Retrieve available OS templates for virtual machines. + + + Use this endpoint to view operating system options before creating or + recreating VPS instances. + operationId: VPS_getTemplatesV1 + responses: + "200": + description: Success response + content: + application/json: + schema: + $ref: "#/components/schemas/VPS.V1.Template.TemplateCollection" + "401": + $ref: "#/components/responses/Common.Response.UnauthorizedResponse" + "500": + $ref: "#/components/responses/Common.Response.ErrorResponse" + /api/vps/v1/virtual-machines/{virtualMachineId}/actions/{actionId}: + get: + tags: + - "VPS: Actions" + summary: Get action details + description: >- + Retrieve detailed information about a specific action performed on a + specified virtual machine. + + + Use this endpoint to monitor specific VPS operation status and details. + operationId: VPS_getActionDetailsV1 + parameters: + - $ref: "#/components/parameters/virtualMachineId" + - $ref: "#/components/parameters/actionId" + responses: + "200": + description: Success response + content: + application/json: + schema: + $ref: "#/components/schemas/VPS.V1.Action.ActionResource" + "401": + $ref: "#/components/responses/Common.Response.UnauthorizedResponse" + "500": + $ref: "#/components/responses/Common.Response.ErrorResponse" + /api/vps/v1/virtual-machines/{virtualMachineId}/actions: + get: + tags: + - "VPS: Actions" + summary: Get actions + description: >- + Retrieve actions performed on a specified virtual machine. + + + Actions are operations or events that have been executed on the virtual + + machine, such as starting, stopping, or modifying the machine. This + endpoint + + allows you to view the history of these actions, providing details about + + each action, such as the action name, timestamp, and status. + + + Use this endpoint to view VPS operation history and troubleshoot issues. + operationId: VPS_getActionsV1 + parameters: + - $ref: "#/components/parameters/virtualMachineId" + - $ref: "#/components/parameters/page" + responses: + "200": + description: Success response + content: + application/json: + schema: + properties: + data: + $ref: "#/components/schemas/VPS.V1.Action.ActionCollection" + meta: + $ref: "#/components/schemas/Common.Schema.PaginationMetaSchema" + type: object + "401": + $ref: "#/components/responses/Common.Response.UnauthorizedResponse" + "500": + $ref: "#/components/responses/Common.Response.ErrorResponse" + /api/vps/v1/virtual-machines/{virtualMachineId}/public-keys: + get: + tags: + - "VPS: Virtual machine" + summary: Get attached public keys + description: >- + Retrieve public keys attached to a specified virtual machine. + + + Use this endpoint to view SSH keys configured for specific VPS + instances. + operationId: VPS_getAttachedPublicKeysV1 + parameters: + - $ref: "#/components/parameters/virtualMachineId" + - $ref: "#/components/parameters/page" + responses: + "200": + description: Success response + content: + application/json: + schema: + properties: + data: + $ref: "#/components/schemas/VPS.V1.PublicKey.PublicKeyCollection" + meta: + $ref: "#/components/schemas/Common.Schema.PaginationMetaSchema" + type: object + "401": + $ref: "#/components/responses/Common.Response.UnauthorizedResponse" + "500": + $ref: "#/components/responses/Common.Response.ErrorResponse" + /api/vps/v1/virtual-machines/{virtualMachineId}/backups: + get: + tags: + - "VPS: Backups" + summary: Get backups + description: |- + Retrieve backups for a specified virtual machine. + + Use this endpoint to view available backup points for VPS data recovery. + operationId: VPS_getBackupsV1 + parameters: + - $ref: "#/components/parameters/virtualMachineId" + - $ref: "#/components/parameters/page" + responses: + "200": + description: Success response + content: + application/json: + schema: + properties: + data: + $ref: "#/components/schemas/VPS.V1.Backup.BackupCollection" + meta: + $ref: "#/components/schemas/Common.Schema.PaginationMetaSchema" + type: object + "401": + $ref: "#/components/responses/Common.Response.UnauthorizedResponse" + "500": + $ref: "#/components/responses/Common.Response.ErrorResponse" + /api/vps/v1/virtual-machines/{virtualMachineId}/backups/{backupId}/restore: + post: + tags: + - "VPS: Backups" + summary: Restore backup + description: >- + Restore a backup for a specified virtual machine. + + + The system will then initiate the restore process, which may take some + time depending on the size of the backup. + + + **All data on the virtual machine will be overwritten with the data from + the backup.** + + + Use this endpoint to recover VPS data from backup points. + operationId: VPS_restoreBackupV1 + parameters: + - $ref: "#/components/parameters/virtualMachineId" + - $ref: "#/components/parameters/backupId" + responses: + "200": + description: Success response + content: + application/json: + schema: + $ref: "#/components/schemas/VPS.V1.Action.ActionResource" + "401": + $ref: "#/components/responses/Common.Response.UnauthorizedResponse" + "500": + $ref: "#/components/responses/Common.Response.ErrorResponse" + /api/vps/v1/virtual-machines/{virtualMachineId}/hostname: + put: + tags: + - "VPS: Virtual machine" + summary: Set hostname + description: >- + Set hostname for a specified virtual machine. + + + Changing hostname does not update PTR record automatically. + + If you want your virtual machine to be reachable by a hostname, + + you need to point your domain A/AAAA records to virtual machine IP as + well. + + + Use this endpoint to configure custom hostnames for VPS instances. + operationId: VPS_setHostnameV1 + parameters: + - $ref: "#/components/parameters/virtualMachineId" + requestBody: + required: true + content: + application/json: + schema: + $ref: "#/components/schemas/VPS.V1.VirtualMachine.HostnameUpdateRequest" + responses: + "200": + description: Success response + content: + application/json: + schema: + $ref: "#/components/schemas/VPS.V1.Action.ActionResource" + "401": + $ref: "#/components/responses/Common.Response.UnauthorizedResponse" + "422": + $ref: "#/components/responses/Common.Response.UnprocessableContentResponse" + "500": + $ref: "#/components/responses/Common.Response.ErrorResponse" + delete: + tags: + - "VPS: Virtual machine" + summary: Reset hostname + description: >- + Reset hostname and PTR record of a specified virtual machine to default + value. + + + Use this endpoint to restore default hostname configuration for VPS + instances. + operationId: VPS_resetHostnameV1 + parameters: + - $ref: "#/components/parameters/virtualMachineId" + responses: + "200": + description: Success response + content: + application/json: + schema: + $ref: "#/components/schemas/VPS.V1.Action.ActionResource" + "401": + $ref: "#/components/responses/Common.Response.UnauthorizedResponse" + "500": + $ref: "#/components/responses/Common.Response.ErrorResponse" + /api/vps/v1/virtual-machines/{virtualMachineId}: + get: + tags: + - "VPS: Virtual machine" + summary: Get virtual machine details + description: |- + Retrieve detailed information about a specified virtual machine. + + Use this endpoint to view comprehensive VPS configuration and status. + operationId: VPS_getVirtualMachineDetailsV1 + parameters: + - $ref: "#/components/parameters/virtualMachineId" + responses: + "200": + description: Success response + content: + application/json: + schema: + $ref: "#/components/schemas/VPS.V1.VirtualMachine.VirtualMachineResource" + "401": + $ref: "#/components/responses/Common.Response.UnauthorizedResponse" + "500": + $ref: "#/components/responses/Common.Response.ErrorResponse" + /api/vps/v1/virtual-machines: + get: + tags: + - "VPS: Virtual machine" + summary: Get virtual machines + description: |- + Retrieve all available virtual machines. + + Use this endpoint to view available VPS instances. + operationId: VPS_getVirtualMachinesV1 + responses: + "200": + description: Success response + content: + application/json: + schema: + $ref: "#/components/schemas/VPS.V1.VirtualMachine.VirtualMachineCollection" + "401": + $ref: "#/components/responses/Common.Response.UnauthorizedResponse" + "500": + $ref: "#/components/responses/Common.Response.ErrorResponse" + post: + tags: + - "VPS: Virtual machine" + summary: Purchase new virtual machine + description: >- + Purchase and setup a new virtual machine. + + + If virtual machine setup fails for any reason, login to + + [hPanel](https://hpanel.hostinger.com/) and complete the setup manually. + + + If no payment method is provided, your default payment method will be + used automatically. + + + Use this endpoint to create new VPS instances. + operationId: VPS_purchaseNewVirtualMachineV1 + requestBody: + required: true + content: + application/json: + schema: + $ref: "#/components/schemas/VPS.V1.VirtualMachine.PurchaseRequest" + responses: + "200": + description: Success response + content: + application/json: + schema: + $ref: "#/components/schemas/Billing.V1.Order.VirtualMachineOrderResource" + "401": + $ref: "#/components/responses/Common.Response.UnauthorizedResponse" + "422": + $ref: "#/components/responses/Common.Response.UnprocessableContentResponse" + "500": + $ref: "#/components/responses/Common.Response.ErrorResponse" + /api/vps/v1/virtual-machines/{virtualMachineId}/monarx: + get: + tags: + - "VPS: Malware scanner" + summary: Get scan metrics + description: >- + Retrieve scan metrics for the [Monarx](https://www.monarx.com/) malware + scanner + + installed on a specified virtual machine. + + + The scan metrics provide detailed information about malware scans + performed + + by Monarx, including number of scans, detected threats, and other + relevant + + statistics. This information is useful for monitoring security status of + the + + virtual machine and assessing effectiveness of the malware scanner. + + + Use this endpoint to monitor VPS security scan results and threat + detection. + operationId: VPS_getScanMetricsV1 + parameters: + - $ref: "#/components/parameters/virtualMachineId" + responses: + "200": + description: Success response + content: + application/json: + schema: + $ref: "#/components/schemas/VPS.V1.Malware.MetricsResource" + "401": + $ref: "#/components/responses/Common.Response.UnauthorizedResponse" + "422": + $ref: "#/components/responses/Common.Response.UnprocessableContentResponse" + "500": + $ref: "#/components/responses/Common.Response.ErrorResponse" + post: + tags: + - "VPS: Malware scanner" + summary: Install Monarx + description: >- + Install the Monarx malware scanner on a specified virtual machine. + + + [Monarx](https://www.monarx.com/) is a security tool designed to detect + and + + prevent malware infections on virtual machines. By installing Monarx, + users + + can enhance the security of their virtual machines, ensuring that they + are + + protected against malicious software. + + + Use this endpoint to enable malware protection on VPS instances. + operationId: VPS_installMonarxV1 + parameters: + - $ref: "#/components/parameters/virtualMachineId" + responses: + "200": + description: Success response + content: + application/json: + schema: + $ref: "#/components/schemas/VPS.V1.Action.ActionResource" + "401": + $ref: "#/components/responses/Common.Response.UnauthorizedResponse" + "422": + $ref: "#/components/responses/Common.Response.UnprocessableContentResponse" + "500": + $ref: "#/components/responses/Common.Response.ErrorResponse" + delete: + tags: + - "VPS: Malware scanner" + summary: Uninstall Monarx + description: >- + Uninstall the Monarx malware scanner on a specified virtual machine. + + + If Monarx is not installed, the request will still be processed without + any effect. + + + Use this endpoint to remove malware scanner from VPS instances. + operationId: VPS_uninstallMonarxV1 + parameters: + - $ref: "#/components/parameters/virtualMachineId" + responses: + "200": + description: Success response + content: + application/json: + schema: + $ref: "#/components/schemas/VPS.V1.Action.ActionResource" + "401": + $ref: "#/components/responses/Common.Response.UnauthorizedResponse" + "422": + $ref: "#/components/responses/Common.Response.UnprocessableContentResponse" + "500": + $ref: "#/components/responses/Common.Response.ErrorResponse" + /api/vps/v1/virtual-machines/{virtualMachineId}/metrics: + get: + tags: + - "VPS: Virtual machine" + summary: Get metrics + description: >- + Retrieve historical metrics for a specified virtual machine. + + + It includes the following metrics: + + - CPU usage + + - Memory usage + + - Disk usage + + - Network usage + + - Uptime + + + Use this endpoint to monitor VPS performance and resource utilization + over time. + operationId: VPS_getMetricsV1 + parameters: + - $ref: "#/components/parameters/virtualMachineId" + - name: date_from + in: query + required: true + schema: + type: string + format: date-time + default: null + example: 2025-05-01T00:00:00Z + - name: date_to + in: query + required: true + schema: + type: string + format: date-time + default: null + example: 2025-06-01T00:00:00Z + responses: + "200": + description: Success response + content: + application/json: + schema: + $ref: "#/components/schemas/VPS.V1.Metrics.MetricsCollection" + "401": + $ref: "#/components/responses/Common.Response.UnauthorizedResponse" + "422": + $ref: "#/components/responses/Common.Response.UnprocessableContentResponse" + "500": + $ref: "#/components/responses/Common.Response.ErrorResponse" + x-optic-ignore-example: true + /api/vps/v1/virtual-machines/{virtualMachineId}/nameservers: + put: + tags: + - "VPS: Virtual machine" + summary: Set nameservers + description: |- + Set nameservers for a specified virtual machine. + + Be aware, that improper nameserver configuration can lead to the virtual + machine being unable to resolve domain names. + + Use this endpoint to configure custom DNS resolvers for VPS instances. + operationId: VPS_setNameserversV1 + parameters: + - $ref: "#/components/parameters/virtualMachineId" + requestBody: + required: true + content: + application/json: + schema: + $ref: "#/components/schemas/VPS.V1.VirtualMachine.NameserversUpdateRequest" + responses: + "200": + description: Success response + content: + application/json: + schema: + $ref: "#/components/schemas/VPS.V1.Action.ActionResource" + "401": + $ref: "#/components/responses/Common.Response.UnauthorizedResponse" + "422": + $ref: "#/components/responses/Common.Response.UnprocessableContentResponse" + "500": + $ref: "#/components/responses/Common.Response.ErrorResponse" + /api/vps/v1/virtual-machines/{virtualMachineId}/ptr/{ipAddressId}: + post: + tags: + - "VPS: PTR records" + summary: Create PTR record + description: |- + Create or update a PTR (Pointer) record for a specified virtual machine. + + Use this endpoint to configure reverse DNS lookup for VPS IP addresses. + operationId: VPS_createPTRRecordV1 + parameters: + - $ref: "#/components/parameters/virtualMachineId" + - $ref: "#/components/parameters/ipAddressId" + requestBody: + required: true + content: + application/json: + schema: + $ref: "#/components/schemas/VPS.V1.VirtualMachine.PTR.StoreRequest" + responses: + "200": + description: Success response + content: + application/json: + schema: + $ref: "#/components/schemas/VPS.V1.Action.ActionResource" + "401": + $ref: "#/components/responses/Common.Response.UnauthorizedResponse" + "422": + $ref: "#/components/responses/Common.Response.UnprocessableContentResponse" + "500": + $ref: "#/components/responses/Common.Response.ErrorResponse" + delete: + tags: + - "VPS: PTR records" + summary: Delete PTR record + description: >- + Delete a PTR (Pointer) record for a specified virtual machine. + + + Once deleted, reverse DNS lookups to the virtual machine's IP address + will + + no longer return the previously configured hostname. + + + Use this endpoint to remove reverse DNS configuration from VPS + instances. + operationId: VPS_deletePTRRecordV1 + parameters: + - $ref: "#/components/parameters/virtualMachineId" + - $ref: "#/components/parameters/ipAddressId" + responses: + "200": + description: Success response + content: + application/json: + schema: + $ref: "#/components/schemas/VPS.V1.Action.ActionResource" + "401": + $ref: "#/components/responses/Common.Response.UnauthorizedResponse" + "500": + $ref: "#/components/responses/Common.Response.ErrorResponse" + /api/vps/v1/virtual-machines/{virtualMachineId}/panel-password: + put: + tags: + - "VPS: Virtual machine" + summary: Set panel password + description: |- + Set panel password for a specified virtual machine. + + If virtual machine does not use panel OS, the request will still be processed without any effect. + Requirements for password are same as in the [recreate virtual machine + endpoint](/#tag/vps-virtual-machine/POST/api/vps/v1/virtual-machines/{virtualMachineId}/recreate). + + Use this endpoint to configure control panel access credentials for VPS instances. + operationId: VPS_setPanelPasswordV1 + parameters: + - $ref: "#/components/parameters/virtualMachineId" + requestBody: + required: true + content: + application/json: + schema: + $ref: "#/components/schemas/VPS.V1.VirtualMachine.PanelPasswordUpdateRequest" + responses: + "200": + description: Success response + content: + application/json: + schema: + $ref: "#/components/schemas/VPS.V1.Action.ActionResource" + "401": + $ref: "#/components/responses/Common.Response.UnauthorizedResponse" + "422": + $ref: "#/components/responses/Common.Response.UnprocessableContentResponse" + "500": + $ref: "#/components/responses/Common.Response.ErrorResponse" + /api/vps/v1/virtual-machines/{virtualMachineId}/recovery: + post: + tags: + - "VPS: Recovery" + summary: Start recovery mode + description: >- + Initiate recovery mode for a specified virtual machine. + + + Recovery mode is a special state that allows users to perform system + rescue operations, + + such as repairing file systems, recovering data, or troubleshooting + issues that prevent the virtual machine + + from booting normally. + + + Virtual machine will boot recovery disk image and original disk image + will be mounted in `/mnt` directory. + + + Use this endpoint to enable system rescue operations on VPS instances. + operationId: VPS_startRecoveryModeV1 + parameters: + - $ref: "#/components/parameters/virtualMachineId" + requestBody: + required: true + content: + application/json: + schema: + $ref: "#/components/schemas/VPS.V1.VirtualMachine.Recovery.StartRequest" + responses: + "200": + description: Success response + content: + application/json: + schema: + $ref: "#/components/schemas/VPS.V1.Action.ActionResource" + "401": + $ref: "#/components/responses/Common.Response.UnauthorizedResponse" + "422": + $ref: "#/components/responses/Common.Response.UnprocessableContentResponse" + "500": + $ref: "#/components/responses/Common.Response.ErrorResponse" + delete: + tags: + - "VPS: Recovery" + summary: Stop recovery mode + description: >- + Stop recovery mode for a specified virtual machine. + + + If virtual machine is not in recovery mode, this operation will fail. + + + Use this endpoint to exit system rescue mode and return VPS to normal + operation. + operationId: VPS_stopRecoveryModeV1 + parameters: + - $ref: "#/components/parameters/virtualMachineId" + responses: + "200": + description: Success response + content: + application/json: + schema: + $ref: "#/components/schemas/VPS.V1.Action.ActionResource" + "401": + $ref: "#/components/responses/Common.Response.UnauthorizedResponse" + "500": + $ref: "#/components/responses/Common.Response.ErrorResponse" + /api/vps/v1/virtual-machines/{virtualMachineId}/recreate: + post: + tags: + - "VPS: Virtual machine" + summary: Recreate virtual machine + description: >- + Recreate a virtual machine from scratch. + + + The recreation process involves reinstalling the operating system and + + resetting the virtual machine to its initial state. + + Snapshots, if there are any, will be deleted. + + + ## Password Requirements + + Password will be checked against leaked password databases. + + Requirements for the password are: + + - At least 12 characters long + + - At least one uppercase letter + + - At least one lowercase letter + + - At least one number + + - Is not leaked publicly + + + **This operation is irreversible and will result in the loss of all data + stored on the virtual machine!** + + + Use this endpoint to completely rebuild VPS instances with fresh OS + installation. + operationId: VPS_recreateVirtualMachineV1 + parameters: + - $ref: "#/components/parameters/virtualMachineId" + requestBody: + required: true + content: + application/json: + schema: + $ref: "#/components/schemas/VPS.V1.VirtualMachine.RecreateRequest" + responses: + "200": + description: Success response + content: + application/json: + schema: + $ref: "#/components/schemas/VPS.V1.Action.ActionResource" + "401": + $ref: "#/components/responses/Common.Response.UnauthorizedResponse" + "422": + $ref: "#/components/responses/Common.Response.UnprocessableContentResponse" + "500": + $ref: "#/components/responses/Common.Response.ErrorResponse" + /api/vps/v1/virtual-machines/{virtualMachineId}/restart: + post: + tags: + - "VPS: Virtual machine" + summary: Restart virtual machine + description: |- + Restart a specified virtual machine by fully stopping and starting it. + + If the virtual machine was stopped, it will be started. + + Use this endpoint to reboot VPS instances. + operationId: VPS_restartVirtualMachineV1 + parameters: + - $ref: "#/components/parameters/virtualMachineId" + responses: + "200": + description: Success response + content: + application/json: + schema: + $ref: "#/components/schemas/VPS.V1.Action.ActionResource" + "401": + $ref: "#/components/responses/Common.Response.UnauthorizedResponse" + "500": + $ref: "#/components/responses/Common.Response.ErrorResponse" + /api/vps/v1/virtual-machines/{virtualMachineId}/root-password: + put: + tags: + - "VPS: Virtual machine" + summary: Set root password + description: |- + Set root password for a specified virtual machine. + + Requirements for password are same as in the [recreate virtual machine + endpoint](/#tag/vps-virtual-machine/POST/api/vps/v1/virtual-machines/{virtualMachineId}/recreate). + + Use this endpoint to update administrator credentials for VPS instances. + operationId: VPS_setRootPasswordV1 + parameters: + - $ref: "#/components/parameters/virtualMachineId" + requestBody: + required: true + content: + application/json: + schema: + $ref: "#/components/schemas/VPS.V1.VirtualMachine.RootPasswordUpdateRequest" + responses: + "200": + description: Success response + content: + application/json: + schema: + $ref: "#/components/schemas/VPS.V1.Action.ActionResource" + "401": + $ref: "#/components/responses/Common.Response.UnauthorizedResponse" + "422": + $ref: "#/components/responses/Common.Response.UnprocessableContentResponse" + "500": + $ref: "#/components/responses/Common.Response.ErrorResponse" + /api/vps/v1/virtual-machines/{virtualMachineId}/setup: + post: + tags: + - "VPS: Virtual machine" + summary: Setup purchased virtual machine + description: |- + Setup newly purchased virtual machine with `initial` state. + + Use this endpoint to configure and initialize purchased VPS instances. + operationId: VPS_setupPurchasedVirtualMachineV1 + parameters: + - $ref: "#/components/parameters/virtualMachineId" + requestBody: + required: true + content: + application/json: + schema: + $ref: "#/components/schemas/VPS.V1.VirtualMachine.SetupRequest" + responses: + "200": + description: Success response + content: + application/json: + schema: + $ref: "#/components/schemas/VPS.V1.VirtualMachine.VirtualMachineResource" + "401": + $ref: "#/components/responses/Common.Response.UnauthorizedResponse" + "422": + $ref: "#/components/responses/Common.Response.UnprocessableContentResponse" + "500": + $ref: "#/components/responses/Common.Response.ErrorResponse" + /api/vps/v1/virtual-machines/{virtualMachineId}/snapshot: + get: + tags: + - "VPS: Snapshots" + summary: Get snapshot + description: |- + Retrieve snapshot for a specified virtual machine. + + Use this endpoint to view current VPS snapshot information. + operationId: VPS_getSnapshotV1 + parameters: + - $ref: "#/components/parameters/virtualMachineId" + responses: + "200": + description: Success response + content: + application/json: + schema: + $ref: "#/components/schemas/VPS.V1.Snapshot.SnapshotResource" + "401": + $ref: "#/components/responses/Common.Response.UnauthorizedResponse" + "500": + $ref: "#/components/responses/Common.Response.ErrorResponse" + post: + tags: + - "VPS: Snapshots" + summary: Create snapshot + description: >- + Create a snapshot of a specified virtual machine. + + + A snapshot captures the state and data of the virtual machine at a + specific point in time, + + allowing users to restore the virtual machine to that state if needed. + + This operation is useful for backup purposes, system recovery, + + and testing changes without affecting the current state of the virtual + machine. + + + **Creating new snapshot will overwrite the existing snapshot!** + + + Use this endpoint to capture VPS state for backup and recovery purposes. + operationId: VPS_createSnapshotV1 + parameters: + - $ref: "#/components/parameters/virtualMachineId" + responses: + "200": + description: Success response + content: + application/json: + schema: + $ref: "#/components/schemas/VPS.V1.Action.ActionResource" + "401": + $ref: "#/components/responses/Common.Response.UnauthorizedResponse" + "500": + $ref: "#/components/responses/Common.Response.ErrorResponse" + delete: + tags: + - "VPS: Snapshots" + summary: Delete snapshot + description: |- + Delete a snapshot of a specified virtual machine. + + Use this endpoint to remove VPS snapshots. + operationId: VPS_deleteSnapshotV1 + parameters: + - $ref: "#/components/parameters/virtualMachineId" + responses: + "200": + description: Success response + content: + application/json: + schema: + $ref: "#/components/schemas/VPS.V1.Action.ActionResource" + "401": + $ref: "#/components/responses/Common.Response.UnauthorizedResponse" + "500": + $ref: "#/components/responses/Common.Response.ErrorResponse" + /api/vps/v1/virtual-machines/{virtualMachineId}/snapshot/restore: + post: + tags: + - "VPS: Snapshots" + summary: Restore snapshot + description: >- + Restore a specified virtual machine to a previous state using a + snapshot. + + + Restoring from a snapshot allows users to revert the virtual machine to + that state, + + which is useful for system recovery, undoing changes, or testing. + + + Use this endpoint to revert VPS instances to previous saved states. + operationId: VPS_restoreSnapshotV1 + parameters: + - $ref: "#/components/parameters/virtualMachineId" + responses: + "200": + description: Success response + content: + application/json: + schema: + $ref: "#/components/schemas/VPS.V1.Action.ActionResource" + "401": + $ref: "#/components/responses/Common.Response.UnauthorizedResponse" + "500": + $ref: "#/components/responses/Common.Response.ErrorResponse" + /api/vps/v1/virtual-machines/{virtualMachineId}/start: + post: + tags: + - "VPS: Virtual machine" + summary: Start virtual machine + description: >- + Start a specified virtual machine. + + + If the virtual machine is already running, the request will still be + processed without any effect. + + + Use this endpoint to power on stopped VPS instances. + operationId: VPS_startVirtualMachineV1 + parameters: + - $ref: "#/components/parameters/virtualMachineId" + responses: + "200": + description: Success response + content: + application/json: + schema: + $ref: "#/components/schemas/VPS.V1.Action.ActionResource" + "401": + $ref: "#/components/responses/Common.Response.UnauthorizedResponse" + "500": + $ref: "#/components/responses/Common.Response.ErrorResponse" + /api/vps/v1/virtual-machines/{virtualMachineId}/stop: + post: + tags: + - "VPS: Virtual machine" + summary: Stop virtual machine + description: >- + Stop a specified virtual machine. + + + If the virtual machine is already stopped, the request will still be + processed without any effect. + + + Use this endpoint to power off running VPS instances. + operationId: VPS_stopVirtualMachineV1 + parameters: + - $ref: "#/components/parameters/virtualMachineId" + responses: + "200": + description: Success response + content: + application/json: + schema: + $ref: "#/components/schemas/VPS.V1.Action.ActionResource" + "401": + $ref: "#/components/responses/Common.Response.UnauthorizedResponse" + "500": + $ref: "#/components/responses/Common.Response.ErrorResponse" +components: + schemas: + Common.Schema.PaginationMetaSchema: + properties: + current_page: + type: integer + example: 1 + per_page: + type: integer + example: 15 + total: + type: integer + example: 100 + type: object + x-scalar-ignore: true + Billing.V1.Subscription.CancelRequest: + properties: + reason_code: + description: Cancellation reason code + type: string + enum: + - other + example: other + nullable: true + cancel_option: + description: Cancellation option + type: string + enum: + - immediately + example: immediately + nullable: true + type: object + DNS.V1.Zone.DestroyRequest: + required: + - filters + properties: + filters: + description: Filter records for deletion + type: array + items: + required: + - name + - type + properties: + name: + description: Name of the record + type: string + example: "@" + type: + description: Type of the record + type: string + enum: + - A + - AAAA + - CNAME + - ALIAS + - MX + - TXT + - NS + - SOA + - SRV + - CAA + example: A + type: object + type: object + DNS.V1.Zone.ResetRequest: + properties: + sync: + description: Determines if operation should be run synchronously + type: boolean + default: true + example: true + reset_email_records: + description: Determines if email records should be reset + type: boolean + default: true + example: true + whitelisted_record_types: + description: Specifies which record types to not reset + type: array + items: + type: string + example: + - MX + - TXT + type: object + DNS.V1.Zone.UpdateRequest: + required: + - zone + properties: + overwrite: + description: >- + If `true`, resource records (RRs) matching name and type will be + deleted and new RRs will be created, + + otherwise resource records' ttl's are updated and new records are + appended. + + If no matching RRs are found, they are created. + type: boolean + default: true + example: true + zone: + type: array + items: + required: + - name + - records + - type + properties: + name: + description: Name of the record (use `@` for wildcard name) + type: string + example: www + records: + description: Records assigned to the name + type: array + items: + required: + - content + properties: + content: + description: Content of the name record + type: string + example: mydomain.tld. + type: object + ttl: + description: TTL (Time-To-Live) of the record + type: integer + example: 14400 + type: + description: Type of the record + type: string + enum: + - A + - AAAA + - CNAME + - ALIAS + - MX + - TXT + - NS + - SOA + - SRV + - CAA + example: A + type: object + type: object + DomainAccessVerifier.V2.Verifications.ListRequest: + required: + - domains + properties: + domains: + description: The list of domains for which to get verification details for. + type: array + items: + type: string + example: example.com + type: object + Domains.V1.Availability.AvailabilityRequest: + required: + - domain + - tlds + properties: + domain: + description: Domain name (without TLD) + type: string + example: mydomain + tlds: + description: TLDs list + type: array + items: + description: TLD without leading dot + type: string + example: + - com + - net + - org + with_alternatives: + description: Should response include alternatives + type: boolean + default: false + example: true + type: object + Domains.V1.Forwarding.StoreRequest: + required: + - domain + - redirect_type + - redirect_url + properties: + domain: + description: Domain name + type: string + example: mydomain.tld + redirect_type: + description: Redirect type + type: string + enum: + - "301" + - "302" + example: "301" + x-enum-descriptions: + "301": Permanent + "302": Temporary + redirect_url: + description: URL to forward domain to + type: string + example: https://forward.to.my.url + type: object + Domains.V1.Portfolio.PurchaseRequest: + required: + - domain + - item_id + properties: + domain: + description: Domain name + type: string + example: my-new-domain.tld + item_id: + description: Catalog price item ID + type: string + example: hostingercom-domain-com-usd-1y + payment_method_id: + description: Payment method ID, default will be used if not provided + type: integer + example: 1327362 + domain_contacts: + description: Domain contact information + properties: + owner_id: + description: Owner contact WHOIS record ID + type: integer + example: 741288 + admin_id: + description: Administrative contact WHOIS record ID + type: integer + example: 546123 + billing_id: + description: Billing contact WHOIS record ID + type: integer + example: 741288 + tech_id: + description: Technical contact WHOIS record ID + type: integer + example: 741288 + type: object + additional_details: + description: Additional registration data, possible values depends on TLD + type: object + coupons: + description: Discount coupon codes + type: array + items: + example: + - Coupon 3 + type: object + Domains.V1.Portfolio.UpdateNameserversRequest: + required: + - ns1 + - ns2 + properties: + ns1: + description: First name server + type: string + example: ns1.some-nameserver.tld + ns2: + description: Second name server + type: string + example: ns2.some-nameserver.tld + ns3: + description: Third name server + type: string + example: ns3.some-nameserver.tld + ns4: + description: Fourth name server + type: string + example: ns4.some-nameserver.tld + type: object + Domains.V1.WHOIS.StoreRequest: + required: + - tld + - entity_type + - country + - whois_details + properties: + tld: + description: TLD of the domain (without leading dot) + type: string + example: com + country: + description: ISO 3166 2-letter country code + type: string + example: NL + entity_type: + description: Legal entity type + type: string + enum: + - individual + - organization + example: individual + tld_details: + description: TLD details + type: object + whois_details: + description: WHOIS details + type: object + type: object + Hosting.V1.Datacenters.ListRequest: + required: + - order_id + properties: + order_id: + type: integer + example: 12345 + type: object + Hosting.V1.Domains.VerifyOwnershipRequest: + required: + - domain + properties: + domain: + description: Domain to verify ownership for + type: string + example: example.com + type: object + Hosting.V1.Websites.CreateWebsiteRequest: + required: + - domain + - order_id + properties: + domain: + description: Domain name for the website. Cannot start with "www." + type: string + example: example.com + order_id: + description: ID of the associated order + type: integer + example: 12345 + datacenter_code: + description: Datacenter code. This parameter is required when creating the first + website on a new hosting plan. + type: string + example: us-east-1 + nullable: true + type: object + Reach.V1.Contacts.Segments.StoreRequest: + required: + - name + - conditions + - logic + properties: + name: + type: string + example: New segment name + conditions: + type: array + items: + properties: + operator: + type: string + enum: + - equals + - not_equals + - contains + - not_contains + - gte + - lte + - exists + - within_last_days + - not_within_last_days + - older_than_days + - processed + - not_processed + - delivered + - not_delivered + - dropped + - not_dropped + - bounced + - not_bounced + - opened + - not_opened + - clicked + - not_clicked + - unsubscribed + - not_unsubscribed + example: equals + value: + oneOf: + - type: string + example: example@example.com + - type: integer + example: 10 + attribute: + type: string + enum: + - note + - comment + - domain + - integration + - source + - name + - surname + - email + - subscribed_at + - unsubscribed_at + - subscription_status + - processed + - opened + - clicked + - delivered + - bounced + - unsubscribed + - dropped + - tag + - campaigns + example: note + type: object + maxItems: 5 + minItems: 1 + logic: + type: string + enum: + - AND + - OR + example: AND + type: object + Reach.V1.Contacts.StoreRequest: + required: + - email + properties: + email: + type: string + example: john.doe@example.com + name: + type: string + example: John + nullable: true + surname: + type: string + example: Doe + nullable: true + note: + type: string + maxLength: 75 + example: VIP customer + nullable: true + type: object + VPS.V1.Firewall.Rules.StoreRequest: + required: + - protocol + - port + - source + - source_detail + properties: + protocol: + type: string + enum: + - TCP + - UDP + - ICMP + - GRE + - any + - ESP + - AH + - ICMPv6 + - SSH + - HTTP + - HTTPS + - MySQL + - PostgreSQL + example: TCP + port: + description: "Port or port range, ex: 1024:2048" + type: string + example: "443" + source: + type: string + enum: + - any + - custom + example: any + source_detail: + description: IP range, CIDR, single IP or `any` + type: string + example: 351.15.24.0/24 + type: object + VPS.V1.Firewall.StoreRequest: + required: + - name + properties: + name: + type: string + example: My Firewall Group + type: object + VPS.V1.PostInstallScript.StoreRequest: + required: + - name + - content + properties: + name: + description: Name of the script + type: string + example: My Script + content: + description: Content of the script + type: string + example: |- + #!/bin/bash + + echo 'Hello, World!' + type: object + VPS.V1.PublicKey.AttachRequest: + required: + - ids + properties: + ids: + description: Public Key IDs to attach + type: array + items: + type: integer + example: + - 18232 + - 10230230 + type: object + VPS.V1.PublicKey.StoreRequest: + required: + - name + - key + properties: + name: + type: string + example: My Public Key + key: + type: string + example: ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQD... + type: object + VPS.V1.VirtualMachine.DockerManager.UpRequest: + required: + - project_name + - content + properties: + project_name: + description: Docker Compose project name using alphanumeric characters, dashes, + and underscores only + type: string + maxLength: 64 + minLength: 3 + example: my-project-1 + content: + description: URL pointing to docker-compose.yaml file, Github repository or raw + YAML content of the compose file + type: string + maxLength: 8192 + environment: + description: Project environment variables + type: string + maxLength: 8192 + nullable: true + type: object + VPS.V1.VirtualMachine.HostnameUpdateRequest: + required: + - hostname + properties: + hostname: + type: string + example: my.server.tld + type: object + VPS.V1.VirtualMachine.MetricGetRequest: + required: + - date_from + - date_to + properties: + date_from: + type: string + format: date-time + example: 2025-05-01T00:00:00Z + date_to: + type: string + format: date-time + example: 2025-06-01T00:00:00Z + type: object + VPS.V1.VirtualMachine.NameserversUpdateRequest: + required: + - ns1 + properties: + ns1: + type: string + example: 4.3.2.1 + ns2: + type: string + example: 1.2.3.4 + nullable: true + ns3: + type: string + example: 5.2.3.4 + nullable: true + type: object + VPS.V1.VirtualMachine.PTR.StoreRequest: + required: + - domain + properties: + domain: + description: Pointer record domain + type: string + example: example.tld + type: object + VPS.V1.VirtualMachine.PanelPasswordUpdateRequest: + required: + - password + properties: + password: + description: Panel password for the virtual machine + type: string + format: password + minLength: 8 + example: oMeNRustosIO + type: object + VPS.V1.VirtualMachine.PurchaseRequest: + required: + - item_id + - setup + properties: + item_id: + description: Catalog price item ID + type: string + example: hostingercom-vps-kvm2-usd-1m + payment_method_id: + description: Payment method ID, default will be used if not provided + type: integer + example: 1327362 + setup: + $ref: "#/components/schemas/VPS.V1.VirtualMachine.SetupRequest" + coupons: + description: Discount coupon codes + type: array + items: + example: + - Coupon 3 + type: object + VPS.V1.VirtualMachine.Recovery.StartRequest: + required: + - root_password + properties: + root_password: + description: Temporary root password for recovery mode + type: string + example: oMeNRustosIO + type: object + VPS.V1.VirtualMachine.RecreateRequest: + required: + - template_id + properties: + template_id: + description: Template ID + type: integer + example: 1130 + password: + description: >- + Root password for the virtual machine. If not provided, random + password will be generated. + + Password will not be shown in the response. + type: string + format: password + minLength: 12 + example: oMeNRustosIO + panel_password: + description: >- + Panel password for the panel-based OS template. If not provided, + random password will be generated. + + If OS does not support panel_password this field will be ignored. + + Password will not be shown in the response. + type: string + format: password + minLength: 12 + example: Mna58c17a4d + post_install_script_id: + description: Post-install script to execute after virtual machine was recreated + type: integer + example: 6324 + type: object + VPS.V1.VirtualMachine.RootPasswordUpdateRequest: + required: + - password + properties: + password: + description: Root password for the virtual machine + type: string + format: password + minLength: 12 + example: oMeNRustosIO + type: object + VPS.V1.VirtualMachine.SetupRequest: + required: + - data_center_id + - template_id + properties: + template_id: + description: Template ID + type: integer + example: 1130 + data_center_id: + description: Data center ID + type: integer + example: 19 + post_install_script_id: + description: Post-install script ID + type: integer + example: 6324 + password: + description: >- + Password for the virtual machine. If not provided, random password + will be generated. + + Password will not be shown in the response. + type: string + format: password + minLength: 12 + example: oMeNRustosIO + hostname: + description: Override default hostname of the virtual machine + type: string + example: my.server.tld + install_monarx: + description: Install Monarx malware scanner (if supported) + type: boolean + default: false + example: false + enable_backups: + description: Enable weekly backup schedule + type: boolean + default: true + example: true + ns1: + description: Name server 1 + type: string + example: 4.3.2.1 + ns2: + description: Name server 2 + type: string + example: 1.2.3.4 + public_key: + description: Use SSH key + properties: + name: + description: Name of the SSH key + type: string + example: my-key + key: + description: Contents of the SSH key + type: string + example: ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC2X... + type: object + type: object + Billing.V1.Catalog.CatalogItemCollection: + description: Array of + [`Billing.V1.Catalog.CatalogItemResource`](#model/billingv1catalogcatalogitemresource) + type: array + items: + $ref: "#/components/schemas/Billing.V1.Catalog.CatalogItemResource" + Billing.V1.Catalog.CatalogItemPriceCollection: + description: Array of + [`Billing.V1.Catalog.CatalogItemPriceResource`](#model/billingv1catalogcatalogitempriceresource) + type: array + items: + $ref: "#/components/schemas/Billing.V1.Catalog.CatalogItemPriceResource" + Billing.V1.Catalog.CatalogItemPriceResource: + properties: + id: + description: Price item ID + type: string + example: hostingercom-vps-kvm2-usd-1m + name: + description: Price item name + type: string + example: KVM 2 (billed every month) + currency: + description: Currency code + type: string + example: USD + price: + description: Price in cents + type: integer + example: 1799 + first_period_price: + description: First period price in cents + type: integer + example: 899 + period: + description: Period + type: integer + example: 1 + period_unit: + description: Period unit + type: string + enum: + - day + - week + - month + - year + - none + example: day + type: object + Billing.V1.Catalog.CatalogItemResource: + properties: + id: + description: Catalog item ID + type: string + example: hostingercom-vps-kvm2 + name: + type: string + example: KVM 2 + category: + type: string + example: VPS + metadata: + description: " + + \ Flexible key-value storage containing category-specific + metadata for the catalog item. + + \ The structure and available fields vary depending on + the item category. + + \ " + type: object + example: + field: value + nullable: true + prices: + $ref: "#/components/schemas/Billing.V1.Catalog.CatalogItemPriceCollection" + type: object + Billing.V1.Order.OrderBillingAddressResource: + properties: + first_name: + type: string + example: John + last_name: + type: string + example: Doe + company: + type: string + example: null + nullable: true + address_1: + type: string + example: null + nullable: true + address_2: + type: string + example: null + nullable: true + city: + type: string + example: null + nullable: true + state: + type: string + example: null + nullable: true + zip: + type: string + example: null + nullable: true + country: + type: string + example: NL + nullable: true + phone: + type: string + example: null + nullable: true + email: + type: string + example: john@doe.tld + type: object + Billing.V1.Order.OrderResource: + properties: + id: + description: Order ID + type: integer + example: 2957086 + subscription_id: + description: Subscription ID + type: string + example: Azz353Uhl1xC54pR0 + status: + type: string + enum: + - completed + - pending + - processing + - failed + - refunded + - cancelled + - awaiting_payment + - payment_initiated + - fraud_refund + example: completed + currency: + description: Currency code + type: string + example: USD + subtotal: + description: Subtotal price (exc. VAT) in cents + type: integer + example: 899 + total: + description: Total price (inc. VAT) in cents + type: integer + example: 1088 + billing_address: + $ref: "#/components/schemas/Billing.V1.Order.OrderBillingAddressResource" + created_at: + type: string + format: date-time + example: 2025-02-27T11:54:22Z + updated_at: + type: string + format: date-time + example: 2025-03-27T11:54:22Z + type: object + Billing.V1.Order.VirtualMachineOrderResource: + properties: + order: + $ref: "#/components/schemas/Billing.V1.Order.OrderResource" + virtual_machine: + $ref: "#/components/schemas/VPS.V1.VirtualMachine.VirtualMachineResource" + type: object + Billing.V1.PaymentMethod.PaymentMethodCollection: + description: Array of + [`Billing.V1.PaymentMethod.PaymentMethodResource`](#model/billingv1paymentmethodpaymentmethodresource) + type: array + items: + $ref: "#/components/schemas/Billing.V1.PaymentMethod.PaymentMethodResource" + Billing.V1.PaymentMethod.PaymentMethodResource: + properties: + id: + description: Payment method ID + type: integer + example: 6523 + name: + type: string + example: Credit Card + identifier: + type: string + example: 1234*****6464 + payment_method: + type: string + example: card + is_default: + type: boolean + example: true + is_expired: + type: boolean + example: false + is_suspended: + type: boolean + example: false + created_at: + type: string + format: date-time + example: 2025-02-27T11:54:22Z + expires_at: + type: string + format: date-time + example: 2025-03-27T11:54:22Z + type: object + Billing.V1.Subscription.SubscriptionCollection: + description: Array of + [`Billing.V1.Subscription.SubscriptionResource`](#model/billingv1subscriptionsubscriptionresource) + type: array + items: + $ref: "#/components/schemas/Billing.V1.Subscription.SubscriptionResource" + Billing.V1.Subscription.SubscriptionResource: + properties: + id: + description: Subscription ID + type: string + example: Azz36nUfKX1S1MSF + name: + type: string + example: KVM 1 + status: + type: string + enum: + - active + - paused + - cancelled + - not_renewing + - transferred + - in_trial + - future + example: active + billing_period: + type: integer + example: 1 + billing_period_unit: + type: string + example: day + currency_code: + type: string + example: USD + total_price: + description: Total price in cents + type: integer + example: 1799 + renewal_price: + description: Renewal price in cents + type: integer + example: 1799 + is_auto_renewed: + type: boolean + example: true + created_at: + type: string + format: date-time + example: 2025-02-27T11:54:22Z + expires_at: + type: string + format: date-time + example: 2025-03-27T11:54:22Z + nullable: true + next_billing_at: + type: string + format: date-time + example: 2025-02-28T11:54:22Z + nullable: true + type: object + Common.SuccessEmptyResource: + properties: + message: + type: string + example: Request accepted + type: object + x-scalar-ignore: true + DNS.V1.Snapshot.SnapshotCollection: + description: Array of + [`DNS.V1.Snapshot.SnapshotResource`](#model/dnsv1snapshotsnapshotresource) + type: array + items: + $ref: "#/components/schemas/DNS.V1.Snapshot.SnapshotResource" + DNS.V1.Snapshot.SnapshotResource: + properties: + id: + description: Snapshot ID + type: integer + example: 5341 + reason: + description: Reason of the update + type: string + example: Zone records update request + created_at: + type: string + format: date-time + example: 2025-02-27T11:54:22Z + type: object + DNS.V1.Snapshot.SnapshotWithContentResource: + properties: + id: + description: Snapshot ID + type: integer + example: 5341 + reason: + description: Reason of the update + type: string + example: Zone records update request + snapshot: + $ref: "#/components/schemas/DNS.V1.Zone.RecordCollection" + created_at: + type: string + format: date-time + example: 2025-02-27T11:54:22Z + type: object + DNS.V1.Zone.NameRecordCollection: + description: Array of + [`DNS.V1.Zone.NameRecordResource`](#model/dnsv1zonenamerecordresource) + type: array + items: + $ref: "#/components/schemas/DNS.V1.Zone.NameRecordResource" + DNS.V1.Zone.NameRecordResource: + properties: + content: + description: Content of the name record + type: string + example: mydomain.tld. + is_disabled: + description: Flag to mark name record as disabled + type: boolean + example: false + type: object + DNS.V1.Zone.RecordCollection: + description: Array of [`DNS.V1.Zone.RecordResource`](#model/dnsv1zonerecordresource) + type: array + items: + $ref: "#/components/schemas/DNS.V1.Zone.RecordResource" + DNS.V1.Zone.RecordResource: + properties: + name: + description: Name of the record (use `@` for wildcard name) + type: string + example: www + records: + $ref: "#/components/schemas/DNS.V1.Zone.NameRecordCollection" + ttl: + description: TTL (Time-To-Live) of the record + type: integer + example: 14400 + type: + description: Type of the record + type: string + enum: + - A + - AAAA + - CNAME + - ALIAS + - MX + - TXT + - NS + - SOA + - SRV + - CAA + example: A + type: object + DomainAccessVerifier.V2.Verifications.ActiveVerificationsCollection: + description: Returns active verifications (PENDING and VERIFIED) grouped by + status and domain. Includes last and next verification attempt dates and + expiration for PENDING verifications. + properties: + data: + description: List of active verifications by status. If no verifications are + found, this will return an empty array. + properties: + PENDING: + description: Pending verifications grouped by domain. Keys are domain names + (e.g., "pixel.tld"). This property will not be returned if no + pending verifications are found. + properties: + DOMAIN.TLD: + description: Domain name (example). Contains verification types as properties. + properties: + VERIFICATION_TYPE: + description: Verification type ("NAMESERVERS" or "TXT"). Only verification types + that exist for this domain will be present. + properties: + records: + description: Verification records + type: array + items: + type: string + last_verification_attempt: + description: Datetime when last verification attempt occurred + type: string + example: 2025-08-05 13:15:00 + next_verification_attempt: + description: Datetime when next verification attempt will occur + type: string + example: 2025-08-05 14:30:00 + verification_expiration: + description: Datetime when verification expires + type: string + example: 2025-08-12 13:15:00 + type: object + type: object + type: object + VERIFIED: + description: Verified verifications grouped by domain. Keys are domain names + (e.g., "byte.tld"). This property will not be returned if no + verified verifications are found. + properties: + DOMAIN.TLD: + description: Domain name (example). Contains verification types as properties. + properties: + VERIFICATION_TYPE: + description: Verification type (e.g., "NAMESERVERS", "TXT"). Only verification + types that exist for this domain will be present. + properties: + records: + description: Verification records + type: array + items: + type: string + type: object + type: object + type: object + type: object + type: object + example: + data: + PENDING: + pixel.tld: + NAMESERVERS: + records: + - ns1.nameserver.com + - ns2.nameserver.com + last_verification_attempt: 2025-08-05 13:15:00 + next_verification_attempt: 2025-08-05 14:30:00 + verification_expiration: 2025-08-12 13:15:00 + TXT: + records: + - txt-verification-hash + last_verification_attempt: 2025-08-05 14:45:00 + next_verification_attempt: 2025-08-05 15:00:00 + verification_expiration: 2025-08-12 14:45:00 + VERIFIED: + byte.tld: + TXT: + records: + - other-txt-verification-hash + Domains.V1.Availability.AvailabilityCollection: + description: Array of + [`Domains.V1.Availability.AvailabilityResource`](#model/domainsv1availabilityavailabilityresource) + type: array + items: + $ref: "#/components/schemas/Domains.V1.Availability.AvailabilityResource" + Domains.V1.Availability.AvailabilityResource: + properties: + domain: + description: Domain name, `null` when not claimed free domain + type: string + example: mydomain.tld + nullable: true + is_available: + description: "`true` if domain is available for registration" + type: boolean + example: true + is_alternative: + description: "`true` if domain is provided as an alternative" + type: boolean + example: false + restriction: + description: Special rules and/or restrictions applied for registering TLD + type: string + nullable: true + type: object + Domains.V1.Domain.DomainCollection: + description: Array of + [`Domains.V1.Domain.DomainResource`](#model/domainsv1domaindomainresource) + type: array + items: + $ref: "#/components/schemas/Domains.V1.Domain.DomainResource" + Domains.V1.Domain.DomainExtendedResource: + properties: + domain: + description: Domain name + type: string + example: mydomain.tld + status: + description: Status of the domain + type: string + enum: + - active + - pending_setup + - expired + - requested + - pending_verification + - deleted + - suspended + - failed + example: active + message: + type: string + nullable: true + is_privacy_protection_allowed: + description: Is privacy protection allowed for the domain + type: boolean + example: true + is_privacy_protected: + description: Is privacy protection enabled for the domain + type: boolean + example: false + is_lockable: + description: Is domain allowed to be locked + type: boolean + example: true + is_locked: + description: Is domain locked + type: boolean + example: true + name_servers: + description: Name servers + properties: + ns1: + description: Name server 1 + type: string + example: ns1.example.tld + ns2: + description: Name server 2 + type: string + example: ns2.example.tld + type: object + example: + ns1: ns1.example.tld + ns2: ns2.example.tld + child_name_servers: + description: Child name servers + type: array + items: + type: array + items: + type: string + example: + ns1.example.tld: + - 258.231.55.321 + - 258.231.55.322 + domain_contacts: + description: WHOIS profiles + properties: + admin_id: + description: Admin WHOIS profile ID + type: integer + example: 114698 + owner_id: + description: Owner WHOIS profile ID + type: integer + example: 614698 + billing_id: + description: Billing WHOIS profile ID + type: integer + example: 154698 + tech_id: + description: Technician WHOIS profile ID + type: integer + example: 524248 + type: object + created_at: + type: string + format: date-time + example: 2025-02-27T11:54:22Z + updated_at: + type: string + format: date-time + example: 2025-02-27T11:54:22Z + 60_days_lock_expires_at: + type: string + format: date-time + example: 2025-04-27T11:54:22Z + nullable: true + registered_at: + type: string + format: date-time + example: 2025-02-27T12:54:22Z + nullable: true + expires_at: + type: string + format: date-time + example: 2025-03-27T11:54:22Z + nullable: true + type: object + Domains.V1.Domain.DomainResource: + properties: + id: + description: Domain ID + type: integer + example: 13632 + domain: + description: Domain name, `null` when not claimed free domain + type: string + example: mydomain.tld + nullable: true + type: + type: string + enum: + - domain + - free_domain + - domain_transfer + - free_domain_transfer + example: domain + status: + type: string + enum: + - active + - pending_setup + - expired + - requested + - pending_verification + - deleted + - suspended + - failed + example: active + created_at: + type: string + format: date-time + example: 2025-02-27T11:54:22Z + expires_at: + type: string + format: date-time + example: 2025-03-27T11:54:22Z + nullable: true + type: object + Domains.V1.Forwarding.ForwardingResource: + properties: + domain: + description: Domain name + type: string + example: mydomain.tld + nullable: true + redirect_type: + description: Redirect type + type: string + enum: + - "301" + - "302" + example: "301" + x-enum-descriptions: + "301": Permanent + "302": Temporary + redirect_url: + description: URL domain is forwarded to + type: string + example: https://forward.to.my.url + created_at: + type: string + format: date-time + example: 2025-02-27T11:54:22Z + updated_at: + type: string + format: date-time + example: 2025-03-27T11:54:22Z + nullable: true + type: object + Domains.V1.WHOIS.ProfileCollection: + description: Array of + [`Domains.V1.WHOIS.ProfileResource`](#model/domainsv1whoisprofileresource) + type: array + items: + $ref: "#/components/schemas/Domains.V1.WHOIS.ProfileResource" + Domains.V1.WHOIS.ProfileResource: + properties: + id: + description: WHOIS Profile ID + type: integer + example: 746263 + tld: + description: TLD to which contact profile can be applied to + type: string + example: com + country: + description: ISO 3166 2-letter country code + type: string + example: NL + entity_type: + description: WHOIS profile entity type + type: string + enum: + - individual + - organization + example: individual + whois_details: + description: WHOIS profile details + type: object + example: + first_name: John + last_name: Doe + email: john@doe.tld + tld_details: + description: TLD details + type: object + created_at: + type: string + format: date-time + example: 2025-02-27T11:54:22Z + updated_at: + type: string + format: date-time + example: 2025-03-19T11:54:22Z + type: object + Domains.V1.WHOIS.ProfileUsageResource: + description: Array of domains + type: array + items: + type: string + example: + - mydomain1.tld + - mydomain2.tld + Hosting.V1.Datacenter.CoordinatesResource: + properties: + latitude: + description: Latitude coordinate + type: number + format: float + example: 51.5074 + longitude: + description: Longitude coordinate + type: number + format: float + example: 0.1278 + type: object + Hosting.V1.Datacenter.DatacenterCollection: + description: Array of + [`Hosting.V1.Datacenter.DatacenterResource`](#model/hostingv1datacenterdatacenterresource) + type: array + items: + $ref: "#/components/schemas/Hosting.V1.Datacenter.DatacenterResource" + Hosting.V1.Datacenter.DatacenterResource: + properties: + title: + description: Data center title + type: string + example: Europe (UK) + code: + description: Data center code + type: string + example: uk-fast + coordinates: + $ref: "#/components/schemas/Hosting.V1.Datacenter.CoordinatesResource" + type: object + Hosting.V1.Domains.DomainAccessResource: + properties: + domain: + description: Domain name + type: string + example: example.com + is_accessible: + description: Whether domain is accessible + type: boolean + example: false + txt_to_verify: + description: TXT record for verification + type: string + example: example.com=example-verification-code + type: object + Hosting.V1.Domains.FreeSubdomainResource: + properties: + domain: + description: Generated free subdomain + type: string + example: palegreen-fox-548498.hostingersite.com + type: object + Hosting.V1.NodeJs.BuildOptionsResource: + required: + - node_version + - app_type + - root_directory + - output_directory + - build_script + - entry_file + - package_manager + - source_type + - source_options + properties: + node_version: + description: Node.js version + type: integer + example: 24 + app_type: + description: Node.js application type + type: string + enum: + - create-react-app + - vite + - angular + - react + - vue + - parcel + example: vite + nullable: true + root_directory: + description: Application root directory + type: string + example: src + nullable: true + output_directory: + description: Build output directory + type: string + example: dist + nullable: true + build_script: + description: The npm script to run to build the application + type: string + example: build + nullable: true + entry_file: + description: The main entry point file for the application + type: string + example: server.js + nullable: true + package_manager: + description: Package manager + type: string + enum: + - npm + - yarn + - pnpm + example: npm + nullable: true + source_type: + description: Source type for the build + type: string + enum: + - archive + example: archive + nullable: true + source_options: + oneOf: + - $ref: "#/components/schemas/Hosting.V1.NodeJs.SourceOptionsResource" + nullable: true + description: Source options, varies based on sourceType + type: object + Hosting.V1.NodeJs.SourceOptionsResource: + properties: + archive_path: + description: Present if sourceType is "archive" + type: string + example: archive.zip + nullable: true + type: object + Hosting.V1.Orders.OrderCollection: + description: Array of + [`Hosting.V1.Orders.OrderResource`](#model/hostingv1ordersorderresource) + type: array + items: + $ref: "#/components/schemas/Hosting.V1.Orders.OrderResource" + Hosting.V1.Orders.OrderResource: + properties: + id: + description: Order ID + type: integer + example: 12345 + client_id: + description: Client ID + type: integer + example: 67890 + subscription_id: + description: Subscription ID + type: string + example: sub_abc123 + nullable: true + created_at: + description: Creation date + type: string + format: date-time + example: 2023-10-08T12:00:00+00:00 + plan: + $ref: "#/components/schemas/Hosting.V1.Orders.PlanResource" + status: + description: Order status + type: string + example: active + type: object + Hosting.V1.Orders.PlanResource: + properties: + name: + description: Plan name + type: string + example: hostinger_business + type: object + Hosting.V1.Websites.WebsiteCollection: + description: Array of + [`Hosting.V1.Websites.WebsiteResource`](#model/hostingv1websiteswebsiteresource) + type: array + items: + $ref: "#/components/schemas/Hosting.V1.Websites.WebsiteResource" + Hosting.V1.Websites.WebsiteResource: + properties: + domain: + description: Website domain + type: string + example: example.com + vhost_type: + description: Virtual host type + type: string + enum: + - main + - addon + - parked + - subdomain + example: main + is_enabled: + description: Whether website is enabled + type: boolean + example: true + username: + description: Username + type: string + example: cl_user123 + client_id: + description: Client ID + type: integer + example: 67890 + order_id: + description: Order ID + type: integer + example: 12345 + created_at: + description: Creation date + type: string + format: date-time + example: 2024-01-15T10:30:00+00:00 + root_directory: + description: Root directory path + type: string + example: /home/u123456798/domains/example.com/public_html + parent_domain: + description: Parent domain + type: string + example: parent.com + nullable: true + type: object + Reach.V1.Contacts.ContactCollection: + description: Array of + [`Reach.V1.Contacts.ContactResource`](#model/reachv1contactscontactresource) + type: array + items: + $ref: "#/components/schemas/Reach.V1.Contacts.ContactResource" + Reach.V1.Contacts.ContactResource: + properties: + uuid: + type: string + example: 550e8400-e29b-41d4-a716-446655440000 + name: + type: string + example: John + nullable: true + surname: + type: string + example: Doe + nullable: true + email: + type: string + example: john.doe@example.com + subscription_status: + type: string + enum: + - subscribed + - unsubscribed + example: subscribed + subscribed_at: + type: string + format: date-time + example: 2023-01-01T00:00:00Z + source: + type: string + enum: + - sync + - import + - manual + example: sync + nullable: true + note: + type: string + maxLength: 75 + example: VIP customer + nullable: true + type: object + Reach.V1.Contacts.Groups.ContactGroupCollection: + description: Array of + [`Reach.V1.Contacts.Groups.ContactGroupResource`](#model/reachv1contactsgroupscontactgroupresource) + type: array + items: + $ref: "#/components/schemas/Reach.V1.Contacts.Groups.ContactGroupResource" + Reach.V1.Contacts.Groups.ContactGroupResource: + properties: + uuid: + type: string + example: 550e8400-e29b-41d4-a716-446655440000 + title: + type: string + example: Newsletter Subscribers + type: object + Reach.V1.Contacts.Segments.ContactSegmentCollection: + description: Array of + [`Reach.V1.Contacts.Segments.ContactSegmentResource`](#model/reachv1contactssegmentscontactsegmentresource) + type: array + items: + $ref: "#/components/schemas/Reach.V1.Contacts.Segments.ContactSegmentResource" + Reach.V1.Contacts.Segments.ContactSegmentResource: + properties: + uuid: + type: string + example: 550e8400-e29b-41d4-a716-446655440000 + name: + type: string + example: Newsletter Subscribers + created_at: + type: string + format: date-time + example: 2025-02-27T11:54:22Z + updated_at: + type: string + format: date-time + example: 2025-02-27T11:54:22Z + type: object + Reach.V1.Contacts.Segments.SegmentResource: + properties: + uuid: + type: string + example: 550e8400-e29b-41d4-a716-446655440000 + name: + type: string + example: Segment name + query: + type: array + items: {} + example: + conditions: + - attribute: email + operator: contains + value: example.com + logic: and + created_at: + type: string + format: date-time + example: 2025-02-27T11:54:22Z + updated_at: + type: string + format: date-time + example: 2025-02-27T11:54:22Z + type: object + Reach.V1.Contacts.Segments.SegmentationContactCollection: + description: Array of + [`Reach.V1.Contacts.Segments.SegmentationContactResource`](#model/reachv1contactssegmentssegmentationcontactresource) + type: array + items: + $ref: "#/components/schemas/Reach.V1.Contacts.Segments.SegmentationContactResou\ + rce" + Reach.V1.Contacts.Segments.SegmentationContactResource: + properties: + uuid: + type: string + example: 550e8400-e29b-41d4-a716-446655440000 + name: + type: string + example: John + nullable: true + surname: + type: string + example: Doe + nullable: true + email: + type: string + example: john.doe@example.com + subscription_status: + type: string + enum: + - subscribed + - unsubscribed + example: subscribed + subscribed_at: + type: string + format: date-time + example: 2023-01-01T00:00:00Z + source: + type: string + enum: + - sync + - import + - manual + example: sync + nullable: true + note: + type: string + maxLength: 75 + example: VIP customer + nullable: true + type: object + Reach.V1.Profiles.ProfileCollection: + description: Array of + [`Reach.V1.Profiles.ProfileResource`](#model/reachv1profilesprofileresource) + type: array + items: + $ref: "#/components/schemas/Reach.V1.Profiles.ProfileResource" + Reach.V1.Profiles.ProfileResource: + properties: + limits: + properties: + ai_messages_limit: + type: integer + example: 10 + subscribers_limit: + type: integer + example: 500 + emails_monthly_limit: + type: integer + example: 3500 + ai_messages_additional: + type: integer + example: 1096 + type: object + is_trial: + type: boolean + example: false + expires_at: + type: string + format: date-time + example: 2027-10-21T05:38:23.000000Z + resource_id: + type: integer + example: 44340307 + status: + type: string + example: active + profiles: + type: array + items: + properties: + uuid: + type: string + example: 550e8400-e29b-41d4-a716-446655440000 + domain: + type: string + example: example.com + created_at: + type: string + format: date-time + example: 2026-01-21T07:35:04.000000Z + updated_at: + type: string + format: date-time + example: 2026-01-21T07:35:04.000000Z + type: object + type: object + VPS.V1.Action.ActionCollection: + description: Array of + [`VPS.V1.Action.ActionResource`](#model/vpsv1actionactionresource) + type: array + items: + $ref: "#/components/schemas/VPS.V1.Action.ActionResource" + VPS.V1.Action.ActionResource: + properties: + id: + description: Action ID + type: integer + example: 8123712 + name: + description: Action name + type: string + example: action_name + state: + description: Action state + type: string + enum: + - success + - error + - delayed + - sent + - created + example: success + x-enum-descriptions: + success: Action was successful + error: Action failed + delayed: Action is delayed + sent: Action was sent + created: Action was created + created_at: + type: string + format: date-time + example: 2025-02-27T11:54:00Z + updated_at: + type: string + format: date-time + example: 2025-02-27T11:58:00Z + type: object + VPS.V1.Backup.BackupCollection: + description: Array of + [`VPS.V1.Backup.BackupResource`](#model/vpsv1backupbackupresource) + type: array + items: + $ref: "#/components/schemas/VPS.V1.Backup.BackupResource" + VPS.V1.Backup.BackupResource: + properties: + id: + description: Backup ID + type: integer + example: 325 + size: + description: Backup size in kilobytes + type: integer + example: 15240192 + restore_time: + description: Estimated backup restore time in seconds + type: integer + example: 3600 + location: + description: Location of the backup + type: string + example: nl-srv-nodebackups + created_at: + type: string + format: date-time + example: 2025-02-27T11:54:22Z + type: object + VPS.V1.DataCenter.DataCenterCollection: + description: Array of + [`VPS.V1.DataCenter.DataCenterResource`](#model/vpsv1datacenterdatacenterresource) + type: array + items: + $ref: "#/components/schemas/VPS.V1.DataCenter.DataCenterResource" + VPS.V1.DataCenter.DataCenterResource: + properties: + id: + description: Data center ID + type: integer + example: 29 + name: + description: Data center name + type: string + example: phx + nullable: true + location: + description: Data center location country (two letter code) + type: string + example: us + nullable: true + city: + description: Data center location city + type: string + example: Phoenix + nullable: true + continent: + description: Data center location continent + type: string + example: North America + nullable: true + type: object + VPS.V1.DockerManager.ContainerCollection: + description: Array of + [`VPS.V1.DockerManager.ContainerResource`](#model/vpsv1dockermanagercontainerresource) + type: array + items: + $ref: "#/components/schemas/VPS.V1.DockerManager.ContainerResource" + VPS.V1.DockerManager.ContainerPortCollection: + description: Array of + [`VPS.V1.DockerManager.ContainerPortResource`](#model/vpsv1dockermanagercontainerportresource) + type: array + items: + $ref: "#/components/schemas/VPS.V1.DockerManager.ContainerPortResource" + VPS.V1.DockerManager.ContainerPortResource: + properties: + type: + description: Port mapping type - published (accessible from host), exposed (only + internal), or range variants + type: string + enum: + - published + - published_range + - exposed + - exposed_range + example: published + x-enum-descriptions: + published: " + + \ A single port mapped from the host to the container + (e.g., host:8080 -> container:80) + + \ " + published_range: " + + \ A range of ports mapped from the host to the + container + + \ (e.g., host:8000-8010 -> container:3000-3010) + + \ " + exposed: " + + \ A single port made available for inter-container + communication within Docker networks + + \ " + exposed_range: " + + \ A range of ports made available for inter-container + communication within Docker networks + + \ " + protocol: + description: Network protocol used for communication + type: string + enum: + - tcp + - udp + example: tcp + host_ip: + description: IP address on host where port is bound (null for exposed-only ports) + type: string + example: 0.0.0.0 + nullable: true + host_port: + description: Port number on host machine (null for exposed-only or range ports) + type: integer + example: 8080 + nullable: true + container_port: + description: Port number inside container (null for range ports) + type: integer + example: 80 + nullable: true + host_port_start: + description: Starting port number in host port range (null for single ports) + type: integer + nullable: true + host_port_end: + description: Ending port number in host port range (null for single ports) + type: integer + nullable: true + container_port_start: + description: Starting port number in container port range (null for single ports) + type: integer + nullable: true + container_port_end: + description: Ending port number in container port range (null for single ports) + type: integer + nullable: true + type: object + VPS.V1.DockerManager.ContainerResource: + properties: + id: + description: Unique container identifier (short form of Docker container ID) + type: string + example: bbd4c89e850d + name: + description: Container name as defined in docker-compose or assigned by Docker + type: string + example: nginx + image: + description: Docker image name and tag used to create this container + type: string + example: nginx:latest + command: + description: Command being executed inside the container (may be truncated with + ...) + type: string + example: /docker-entrypoint.sh nginx -g daemon off; + status: + description: Human-readable container status including uptime, exit codes, or + error information + type: string + example: Up 4 hours + state: + description: Programmatic container lifecycle state for automated processing + type: string + enum: + - created + - running + - restarting + - exited + - paused + - dead + - stopping + example: running + x-enum-descriptions: + created: Container has been created but never started + running: Container is actively running and performing its tasks + restarting: Container is in the process of being restarted + exited: Container ran and completed/stopped + paused: " + + \ Container's processes have been paused, but container + is still allocated + + \ " + dead: " + + \ Container that the daemon tried and failed to stop + + \ (usually due to the busy device or resource used by + the container) + + \ " + stopping: Container is in the process of being stopped + health: + description: Container health status + type: string + enum: + - starting + - healthy + - unhealthy + - "" + example: healthy + x-enum-descriptions: + "": " + + \ No health check is configured for the container + + \ (this is the default when no HEALTHCHECK is defined) + + \ " + healthy: " + + \ The container has passed its health checks and is + operating normally + + \ " + unhealthy: " + + \ The container has failed its health checks (exceeded + the failure threshold) + + \ " + starting: " + + \ The container is still within its startup period + (health checks are running but + + \ haven't passed the required number of consecutive + checks yet) + + \ " + ports: + $ref: "#/components/schemas/VPS.V1.DockerManager.ContainerPortCollection" + stats: + oneOf: + - $ref: "#/components/schemas/VPS.V1.DockerManager.ContainerStatsResource" + nullable: true + description: Real-time resource usage statistics (only available for running + containers) + type: object + VPS.V1.DockerManager.ContainerStatsResource: + properties: + cpu_percentage: + description: CPU usage in percentage + type: number + format: float + example: 15.4 + memory_percentage: + description: Memory usage in percentage + type: number + format: float + example: 0.4 + memory_used: + description: Used memory in bytes + type: number + format: float + example: 66532147.2 + memory_total: + description: Total available memory in bytes + type: number + format: float + example: 16771847290.88 + net_in: + description: Inbound network traffic in bytes + type: integer + example: 2110000 + net_out: + description: Outbound network traffic in bytes + type: integer + example: 30100 + type: object + VPS.V1.DockerManager.ContentResource: + properties: + content: + description: Contents of docker-compose file + type: string + example: |- + services: + my-app: + image: nginx + ports: + - "80:80" + my-db: + image: mysql + environment: + description: Project environment variables + type: string + example: |- + VARIABLE1=value1 + VARIABLE2=value2 + nullable: true + type: object + VPS.V1.DockerManager.LogEntryCollection: + description: Array of + [`VPS.V1.DockerManager.LogEntryResource`](#model/vpsv1dockermanagerlogentryresource) + type: array + items: + $ref: "#/components/schemas/VPS.V1.DockerManager.LogEntryResource" + VPS.V1.DockerManager.LogEntryResource: + properties: + timestamp: + description: ISO 8601 formatted timestamp when the log entry was generated by + the container + type: string + example: 2024-01-15T10:30:45.123456Z + line: + description: Raw log message content as output by the application inside the + container + type: string + example: 127.0.0.1 - - [15/Jan/2024:10:30:45 +0000] "GET / HTTP/1.1" 200 612 + type: object + VPS.V1.DockerManager.LogsCollection: + description: Array of + [`VPS.V1.DockerManager.LogsResource`](#model/vpsv1dockermanagerlogsresource) + type: array + items: + $ref: "#/components/schemas/VPS.V1.DockerManager.LogsResource" + VPS.V1.DockerManager.LogsResource: + properties: + service: + description: Name of the Docker Compose service that generated these log entries + type: string + example: web + entries: + $ref: "#/components/schemas/VPS.V1.DockerManager.LogEntryCollection" + type: object + VPS.V1.DockerManager.ProjectCollection: + description: Array of + [`VPS.V1.DockerManager.ProjectResource`](#model/vpsv1dockermanagerprojectresource) + type: array + items: + $ref: "#/components/schemas/VPS.V1.DockerManager.ProjectResource" + VPS.V1.DockerManager.ProjectResource: + properties: + name: + description: Docker Compose project name (derived from directory name or compose + file) + type: string + example: my-project + status: + description: Raw output from docker compose ps command showing service count and + states + type: string + example: running(2) + state: + description: Derived project state parsed from the raw docker compose status + type: string + enum: + - running + - stopped + - created + - mixed + - unknown + example: running + x-enum-descriptions: + running: Project is running and all services are healthy + stopped: Project is not running and all services are stopped + created: Project is created and not built yet, services are not running + mixed: Project is running with some services not healthy or not running + unknown: Could not determine the state of the project + path: + description: Full filesystem path to the docker-compose.yml file + type: string + example: /docker/my-project/docker-compose.yaml + containers: + $ref: "#/components/schemas/VPS.V1.DockerManager.ContainerCollection" + type: object + VPS.V1.Firewall.FirewallCollection: + description: Array of + [`VPS.V1.Firewall.FirewallResource`](#model/vpsv1firewallfirewallresource) + type: array + items: + $ref: "#/components/schemas/VPS.V1.Firewall.FirewallResource" + VPS.V1.Firewall.FirewallResource: + properties: + id: + description: Firewall ID + type: integer + example: 65224 + name: + description: Firewall name + type: string + example: HTTP and SSH only + is_synced: + description: Is current firewall synced with VPS + type: boolean + example: false + rules: + $ref: "#/components/schemas/VPS.V1.Firewall.FirewallRuleCollection" + created_at: + type: string + format: date-time + example: 2021-09-01T12:00:00Z + updated_at: + type: string + format: date-time + example: 2021-09-01T12:00:00Z + type: object + VPS.V1.Firewall.FirewallRuleCollection: + description: Array of + [`VPS.V1.Firewall.FirewallRuleResource`](#model/vpsv1firewallfirewallruleresource) + type: array + items: + $ref: "#/components/schemas/VPS.V1.Firewall.FirewallRuleResource" + VPS.V1.Firewall.FirewallRuleResource: + properties: + id: + description: Firewall rule ID + type: integer + example: 24541 + action: + description: Firewall rule action + type: string + enum: + - accept + - drop + example: accept + protocol: + description: Firewall rule protocol + type: string + enum: + - TCP + - UDP + - ICMP + - GRE + - any + - ESP + - AH + - ICMPv6 + - SSH + - HTTP + - HTTPS + - MySQL + - PostgreSQL + example: TCP + port: + description: "Firewall rule destination port: single or port range" + type: string + example: 1024:2048 + source: + description: Firewall rule source. Can be `any` or `custom` + type: string + example: any + source_detail: + description: Firewall rule source detail. Can be `any` or IP address, CIDR or + range + type: string + example: any + type: object + VPS.V1.IPAddress.IPAddressCollection: + description: Array of + [`VPS.V1.IPAddress.IPAddressResource`](#model/vpsv1ipaddressipaddressresource) + type: array + items: + $ref: "#/components/schemas/VPS.V1.IPAddress.IPAddressResource" + VPS.V1.IPAddress.IPAddressResource: + properties: + id: + description: IP address ID + type: integer + example: 52347 + address: + description: "IP address: IPv4 or IPv6" + type: string + example: 213.331.273.15 + ptr: + description: IP address PTR record + type: string + example: something.domain.tld + nullable: true + type: object + VPS.V1.Malware.MetricsResource: + properties: + records: + description: Records found during last scan + type: integer + example: 1 + malicious: + description: Malicious files found during last scan + type: integer + example: 2 + compromised: + description: Compromised files found during last scan + type: integer + example: 3 + scanned_files: + description: Total number of files scanned during last scan + type: integer + example: 193218 + scan_started_at: + type: string + format: date-time + example: 2025-02-27T11:54:22Z + scan_ended_at: + type: string + format: date-time + example: 2025-03-27T11:54:22Z + nullable: true + type: object + VPS.V1.Metrics.MetricsCollection: + properties: + cpu_usage: + oneOf: + - $ref: "#/components/schemas/VPS.V1.Metrics.MetricsResource" + nullable: true + description: CPU usage in percentage, 0 - 100% + type: object + example: + unit: "%" + usage: + "1742269632": 1.45 + ram_usage: + oneOf: + - $ref: "#/components/schemas/VPS.V1.Metrics.MetricsResource" + nullable: true + description: RAM usage in bytes + type: object + example: + unit: bytes + usage: + "1742269632": 554176512 + disk_space: + oneOf: + - $ref: "#/components/schemas/VPS.V1.Metrics.MetricsResource" + nullable: true + description: Disk space usage in bytes + type: object + example: + unit: bytes + usage: + "1742269632": 2620018688 + outgoing_traffic: + oneOf: + - $ref: "#/components/schemas/VPS.V1.Metrics.MetricsResource" + nullable: true + description: Outgoing traffic in bytes + type: object + example: + unit: bytes + usage: + "1742269632": 784800 + incoming_traffic: + oneOf: + - $ref: "#/components/schemas/VPS.V1.Metrics.MetricsResource" + nullable: true + description: Incoming traffic in bytes + type: object + example: + unit: bytes + usage: + "1742269632": 8978400 + uptime: + oneOf: + - $ref: "#/components/schemas/VPS.V1.Metrics.MetricsResource" + nullable: true + description: Uptime in milliseconds + type: object + example: + unit: milliseconds + usage: + "1742269632": 455248 + type: object + VPS.V1.Metrics.MetricsResource: + properties: + unit: + description: Measurement unit + type: string + example: measurement-unit + usage: + description: Object, containing UNIX timestamps as a key and measurement as a + value. + type: object + example: + timestamp: 123 + type: object + VPS.V1.PostInstallScript.PostInstallScriptCollection: + description: Array of + [`VPS.V1.PostInstallScript.PostInstallScriptResource`](#model/vpsv1postinstallscriptpostinstallscriptresource) + type: array + items: + $ref: "#/components/schemas/VPS.V1.PostInstallScript.PostInstallScriptResource" + VPS.V1.PostInstallScript.PostInstallScriptResource: + properties: + id: + description: Post-install script ID + type: integer + example: 325 + name: + description: Name of the script + type: string + example: My Setup Script + content: + description: Content of the script + type: string + example: "#!/bin/bash\\napt-get update\\napt-get install -y nginx" + created_at: + type: string + format: date-time + example: 2025-02-27T11:54:22Z + updated_at: + type: string + format: date-time + example: 2025-03-19T11:54:22Z + type: object + VPS.V1.PublicKey.PublicKeyCollection: + description: Array of + [`VPS.V1.PublicKey.PublicKeyResource`](#model/vpsv1publickeypublickeyresource) + type: array + items: + $ref: "#/components/schemas/VPS.V1.PublicKey.PublicKeyResource" + VPS.V1.PublicKey.PublicKeyResource: + properties: + id: + description: Public key ID + type: integer + example: 325 + name: + description: Public key name + type: string + example: My public key + key: + description: Public key content + type: string + example: ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQD... + type: object + VPS.V1.Snapshot.SnapshotResource: + properties: + id: + description: Snapshot ID + type: integer + example: 325 + restore_time: + description: Estimated snapshot restore time in seconds + type: integer + example: 1800 + created_at: + type: string + format: date-time + example: 2025-02-27T11:54:22Z + expires_at: + type: string + format: date-time + example: 2025-03-19T11:54:22Z + type: object + VPS.V1.Template.TemplateCollection: + description: Array of + [`VPS.V1.Template.TemplateResource`](#model/vpsv1templatetemplateresource) + type: array + items: + $ref: "#/components/schemas/VPS.V1.Template.TemplateResource" + VPS.V1.Template.TemplateResource: + properties: + id: + description: Template ID + type: integer + example: 6523 + name: + description: Template name + type: string + example: Ubuntu 20.04 LTS + description: + description: Template description + type: string + example: Ubuntu 20.04 LTS + documentation: + description: Link to official OS documentation + type: string + example: https://docs.ubuntu.com + nullable: true + type: object + VPS.V1.VirtualMachine.VirtualMachineCollection: + description: Array of + [`VPS.V1.VirtualMachine.VirtualMachineResource`](#model/vpsv1virtualmachinevirtualmachineresource) + type: array + items: + $ref: "#/components/schemas/VPS.V1.VirtualMachine.VirtualMachineResource" + VPS.V1.VirtualMachine.VirtualMachineResource: + properties: + id: + description: Virtual machine ID + type: integer + example: 17923 + firewall_group_id: + description: Active firewall ID, `null` if disabled + type: integer + example: null + nullable: true + subscription_id: + description: Subscription ID + type: string + example: Azz353Uhl1xC54pR0 + nullable: true + data_center_id: + description: Data center ID + type: integer + example: 521 + nullable: true + plan: + description: VPS plan name + type: string + example: KVM 4 + nullable: true + hostname: + type: string + example: srv17923.hstgr.cloud + state: + type: string + enum: + - running + - starting + - stopping + - stopped + - creating + - initial + - error + - suspending + - unsuspending + - suspended + - destroying + - destroyed + - recreating + - restoring + - recovery + - stopping_recovery + example: running + actions_lock: + type: string + enum: + - unlocked + - locked + example: unlocked + cpus: + description: CPUs count assigned to virtual machine + type: integer + example: 4 + memory: + description: Memory available to virtual machine (in megabytes) + type: integer + example: 8192 + disk: + description: Virtual machine disk size (in megabytes) + type: integer + example: 51200 + bandwidth: + description: Monthly internet traffic available to virtual machine (in megabytes) + type: integer + example: 1073741824 + ns1: + description: Primary DNS resolver + type: string + example: 1.1.1.1 + nullable: true + ns2: + description: Secondary DNS resolver + type: string + example: 8.8.8.8 + nullable: true + ipv4: + oneOf: + - $ref: "#/components/schemas/VPS.V1.IPAddress.IPAddressCollection" + nullable: true + description: IPv4 address of virtual machine + ipv6: + oneOf: + - $ref: "#/components/schemas/VPS.V1.IPAddress.IPAddressCollection" + nullable: true + description: IPv6 address of virtual machine, `null` if not assigned + template: + oneOf: + - $ref: "#/components/schemas/VPS.V1.Template.TemplateResource" + nullable: true + description: OS template installed in virtual machine + created_at: + type: string + format: date-time + example: 2024-09-05T07:25:36.00000Z + type: object + responses: + Common.Response.ErrorResponse: + description: Error response + content: + application/json: + schema: + properties: + message: + description: Message of the error + type: string + example: Error message + correlation_id: + description: Request correlation ID + type: string + example: 26a91bd9-f8c8-4a83-9df9-83e23d696fe3 + type: object + x-scalar-ignore: true + Common.Response.UnauthorizedResponse: + description: Unauthenticated response + content: + application/json: + schema: + properties: + message: + description: Message of the error + type: string + example: Unauthenticated + correlation_id: + description: Request correlation ID + type: string + example: 26a91bd9-f8c8-4a83-9df9-83e23d696fe3 + type: object + x-scalar-ignore: true + Common.Response.UnprocessableContentResponse: + description: Validation error response + content: + application/json: + schema: + properties: + message: + description: Validation error message + type: string + example: The name field is required. (and 1 more error) + errors: + description: Object of detailed errors for each field + properties: + field_1: + type: array + items: {} + example: + - The field_1 field is required. + - The field_1 must be a number. + field_2: + type: array + items: {} + example: + - The field_2 field is required. + - The field_2 must be a string. + type: object + correlation_id: + description: Request correlation ID + type: string + example: 26a91bd9-f8c8-4a83-9df9-83e23d696fe3 + type: object + x-scalar-ignore: true + parameters: + category: + name: category + in: query + description: Filter catalog items by category + schema: + type: string + enum: + - DOMAIN + - VPS + example: VPS + name: + name: name + in: query + description: Filter catalog items by name. Use `*` for wildcard search, e.g. + `.COM*` to find .com domain + schema: + type: string + example: .COM* + paymentMethodId: + name: paymentMethodId + in: path + description: Payment method ID + required: true + schema: + type: integer + example: 9693613 + subscriptionId: + name: subscriptionId + in: path + description: Subscription ID + required: true + schema: + type: string + example: Cxy353Uhl1xC54pG6 + domain: + name: domain + in: path + description: Domain name + required: true + schema: + type: string + example: mydomain.tld + page: + name: page + in: query + description: Page number + required: false + schema: + type: integer + example: 1 + per_page: + name: per_page + in: query + description: Number of items per page + required: false + schema: + type: integer + default: 25 + maximum: 100 + example: 25 + snapshotId: + name: snapshotId + in: path + description: Snapshot ID + required: true + schema: + type: integer + example: 53513053 + tld: + name: tld + in: query + description: Filter by TLD (without leading dot) + schema: + type: string + example: com + whoisId: + name: whoisId + in: path + description: WHOIS ID + required: true + schema: + type: integer + example: 564651 + build_uuid_path: + name: uuid + in: path + description: Build UUID + required: true + schema: + type: string + format: uuid + example: 123e4567-e89b-12d3-a456-426614174000 + directory: + name: directory + in: query + description: Directory path to check + required: false + schema: + type: string + default: "" + example: blog + domain_filter: + name: domain + in: query + description: Filter by domain name (exact match) + required: false + schema: + type: string + example: example.com + nullable: true + is_enabled: + name: is_enabled + in: query + description: Filter by enabled status + required: false + schema: + type: boolean + example: true + nullable: true + order_id: + name: order_id + in: query + description: Order ID + required: false + schema: + type: integer + example: 123 + nullable: true + order_ids: + name: order_ids + in: query + description: Filter by specific order IDs + required: false + schema: + type: array + items: + type: integer + example: + - 12345 + - 67890 + nullable: true + statuses: + name: statuses + in: query + description: Filter by order statuses + required: false + schema: + type: array + items: + type: string + enum: + - active + - deleting + - deleted + - suspended + example: + - active + - suspended + nullable: true + order_id_required: + name: order_id + in: query + description: Order ID + required: true + schema: + type: integer + example: 123 + nullable: false + username: + name: username + in: query + description: Filter by specific username + required: false + schema: + type: string + example: cl_user123 + nullable: true + username_path: + name: username + in: path + required: true + schema: + type: string + example: u123456789 + uuid: + name: uuid + in: path + description: UUID of the contact to delete + required: true + schema: + type: string + format: uuid + group_uuid: + name: group_uuid + in: query + description: Filter contacts by group UUID + required: false + schema: + type: string + example: 550e8400-e29b-41d4-a716-446655440000 + profileUuid: + name: profileUuid + in: path + description: Profile uuid parameter + required: true + schema: + type: string + example: 550e8400-e09b-41d4-a716-400055000000 + segmentUuid: + name: segmentUuid + in: path + description: Segment uuid parameter + required: true + schema: + type: string + example: 550e8400-e09b-41d4-a716-400055000000 + subscription_status: + name: subscription_status + in: query + description: Filter contacts by subscription status + required: false + schema: + type: string + enum: + - subscribed + - unsubscribed + example: subscribed + tokenId: + name: tokenId + in: path + description: Token ID + required: true + schema: + type: integer + example: 6409747 + actionId: + name: actionId + in: path + description: Action ID + required: true + schema: + type: integer + example: 8123712 + backupId: + name: backupId + in: path + description: Backup ID + required: true + schema: + type: integer + example: 8676502 + projectName: + name: projectName + in: path + description: Docker Compose project name using alphanumeric characters, dashes, + and underscores only + required: true + schema: + type: string + maxLength: 64 + minLength: 3 + example: my-docker-project + firewallId: + name: firewallId + in: path + description: Firewall ID + required: true + schema: + type: integer + example: 9449049 + ruleId: + name: ruleId + in: path + description: Firewall Rule ID + required: true + schema: + type: integer + example: 8941182 + ipAddressId: + name: ipAddressId + in: path + description: IP Address ID + required: true + schema: + type: integer + example: 246547 + postInstallScriptId: + name: postInstallScriptId + in: path + description: Post-install script ID + required: true + schema: + type: integer + example: 9568314 + publicKeyId: + name: publicKeyId + in: path + description: Public Key ID + required: true + schema: + type: integer + example: 6672861 + templateId: + name: templateId + in: path + description: Template ID + required: true + schema: + type: integer + example: 2868928 + virtualMachineId: + name: virtualMachineId + in: path + description: Virtual Machine ID + required: true + schema: + type: integer + example: 1268054 + securitySchemes: + apiToken: + type: http + description: API Token authentication + scheme: bearer +security: + - apiToken: [] +tags: + - name: "Billing: Catalog" + description: |- + Access a comprehensive catalog of service plans and + subscription options, complete with detailed pricing + and features. + x-displayName: Catalog + - name: "Billing: Payment methods" + description: |- + Review and manage the payment methods linked to your + Hostinger account. Enjoy a secure and convenient overview + for handling billing and transactions. + x-displayName: Payment methods + - name: "Billing: Subscriptions" + description: |- + Manage your account's subscriptions by retrieving lists of + active and expired plans along with details such as + activation and expiration dates. + x-displayName: Subscriptions + - name: "DNS: Snapshot" + description: |- + Manage DNS snapshots for your domains. + This category includes endpoints for viewing and restoring + snapshots of your domain DNS zone. + Snapshot is a point-in-time copy of your DNS zone, allowing you + to restore your domain's DNS settings to a previous state. + x-displayName: Snapshot + - name: "DNS: Zone" + description: |- + Manage DNS zones and records for your domains. This category + includes endpoints for retrieving, updating, deleting DNS zone + and it's associated records. + The DNS zone will be created once you purchase new domain + at Hostinger. + x-displayName: Zone + - name: "Domain Access Verifier: Verifications" + description: |- + Manage domain verifications. + This category includes endpoints for retrieving active domain + verifications, including verification status, records, and + attempt dates. + Domain verification allows you to prove ownership of domains + through nameserver or TXT record verification methods. + x-displayName: Verifications + - name: "Domains: Availability" + description: |- + Check the availability of domain names across multiple TLDs. + This category allows you to verify if a specific domain name + is available for registration. + x-displayName: Availability + - name: "Domains: Forwarding" + description: |- + Domain forwarding or redirect is an easy way to direct your + website visitors to another site or page, making it simple to + maintain your brand and keep your visitors engaged. + x-displayName: Forwarding + - name: "Domains: Portfolio" + description: |- + Retrieve and manage your domain portfolio. This category lets + you list all domains linked to your account, including their + creation and expiration details. + x-displayName: Portfolio + - name: "Domains: WHOIS" + description: |- + Manage WHOIS contact profiles for your domains. This category + includes endpoints for creating, updating, deleting, and + retrieving WHOIS profiles. + WHOIS profile stores registration data for domain names and + is required for domain registration. + x-displayName: WHOIS + - name: "Hosting: Datacenters" + description: |- + Access information about available datacenters for hosting + services. This category provides details about data center + locations and capabilities to help you choose the optimal + region for your hosting needs. + x-displayName: Datacenters + - name: "Hosting: Domains" + description: |- + Manage domain-related hosting services and configurations. + This category includes endpoints for domain management, + verification, and domain-specific hosting features. + x-displayName: Domains + - name: "Hosting: Files" + description: "Hosting: Files" + x-displayName: Files + - name: "Hosting: NodeJS" + description: "Hosting: NodeJS" + x-displayName: NodeJS + - name: "Hosting: Orders" + description: |- + Manage hosting service orders and subscriptions. This + category provides access to order information, status + tracking, and order management capabilities for hosting + services. + x-displayName: Orders + - name: "Hosting: Websites" + description: |- + Manage hosted websites and web applications. This category + includes endpoints for website deployment, configuration, + monitoring, and management of hosting resources. + x-displayName: Websites + - name: "Hosting: Wordpress" + description: "Hosting: Wordpress" + x-displayName: Wordpress + - name: "Reach: Contacts" + description: |- + Manage your email contacts and contact groups. This category + includes endpoints for creating, deleting, and listing + contacts, as well as managing contact groups. + x-displayName: Contacts + - name: "Reach: Segments" + description: |- + Filter and segment your email contacts using various + criteria. This category includes endpoints for filtering + contacts by attributes, tags, and email addresses, as well + as listing all available segments and retrieving contacts + that match specific attribute conditions. + x-displayName: Segments + - name: "Reach: Profiles" + description: "Reach: Profiles" + x-displayName: Profiles + - name: "VPS: Data centers" + description: |- + Access information on available data centers, including + location details, so you can choose the optimal region for + deploying your virtual machines. + x-displayName: Data centers + - name: "VPS: Docker Manager" + description: |- + Manage Docker Compose projects directly on your VPS + instances. This feature is only available for VPS instances + using Docker OS templates and is currently experimental - + breaking changes may occur in future updates. + It enables you to programmatically deploy projects from + docker-compose.yml files by providing either a URL (including + GitHub repositories) or the compose file contents directly. + Control project lifecycle (start/stop/restart/update/delete) + and retrieve runtime information including container lists, + project details, and aggregated logs. + All operations are scoped to a specific virtual machine for + multi-tenant management. + x-displayName: Docker Manager + - name: "VPS: Firewall" + description: |- + Enhance network security with endpoints for creating, + activating, deactivating, syncing, updating, and deleting + firewalls and firewall rules for your virtual machines. + This firewall applies rules at the network level, so it will + take precedence over the virtual machine's internal firewall. + + **Access to firewall requires having at least one virtual machine.** + x-displayName: Firewall + - name: "VPS: Post-install scripts" + description: |- + This category allows you to create, update, delete, and + retrieve scripts that can be used for automated tasks after + the operating system installation. Use case includes setting + up software, configuring settings, or running custom commands. + x-displayName: Post-install scripts + - name: "VPS: Public Keys" + description: |- + Manage SSH keys for secure access. This category covers + adding new public keys, attaching them to virtual machines, + retrieving key lists, and deleting keys. + x-displayName: Public Keys + - name: "VPS: OS Templates" + description: |- + Retrieve details of operating system templates or list all + available templates to choose the right configuration when + deploying or recreating virtual machines. + x-displayName: OS Templates + - name: "VPS: Actions" + description: |- + Track and review operations performed on your virtual + machines. These endpoints provide details about specific + actions—such as start, stop, or restart—including + timestamps and statuses. + x-displayName: Actions + - name: "VPS: Virtual machine" + description: |- + Core virtual machine management functionality. Endpoints in + this category let you retrieve machine details, configure + settings (hostname, nameservers, passwords), and perform + operations like start, stop, restart, or recreate. + x-displayName: Virtual machine + - name: "VPS: Backups" + description: |- + Safeguard your data by managing backups. You can list + available backups or restore a virtual machine from a backup. + x-displayName: Backups + - name: "VPS: Malware scanner" + description: |- + Monitor your virtual machines' security using the Monarx + malware scanner. Retrieve scan metrics or install/uninstall + the scanner to help protect against malware threats. + x-displayName: Malware scanner + - name: "VPS: PTR records" + description: |- + Manage reverse DNS settings by creating or deleting PTR + records for your virtual machines, ensuring that IP addresses + correctly resolve to hostnames. + x-displayName: PTR records + - name: "VPS: Recovery" + description: |- + Initiate or stop recovery mode to perform system rescue + operations. This category enables you to boot a virtual + machine into a state suitable for repairing file systems + or recovering data. + x-displayName: Recovery + - name: "VPS: Snapshots" + description: |- + Create, restore, or delete snapshots that capture the state + of your virtual machines at a given point, allowing you to + quickly recover or test changes without affecting current + operations. + x-displayName: Snapshots +x-tagGroups: + - name: Billing + tags: + - "Billing: Catalog" + - "Billing: Payment methods" + - "Billing: Subscriptions" + - name: Domains + tags: + - "Domains: Availability" + - "Domains: Forwarding" + - "Domains: Portfolio" + - "Domains: WHOIS" + - name: DNS + tags: + - "DNS: Snapshot" + - "DNS: Zone" + - name: Domain Access Verifier + tags: + - "Domain Access Verifier: Verifications" + - name: Hosting + tags: + - "Hosting: Datacenters" + - "Hosting: Domains" + - "Hosting: Files" + - "Hosting: NodeJS" + - "Hosting: Orders" + - "Hosting: Websites" + - "Hosting: Wordpress" + - name: Reach + tags: + - "Reach: Contacts" + - "Reach: Segments" + - "Reach: Profiles" + - name: VPS + tags: + - "VPS: Actions" + - "VPS: Backups" + - "VPS: Data centers" + - "VPS: Docker Manager" + - "VPS: PTR records" + - "VPS: Firewall" + - "VPS: Malware scanner" + - "VPS: OS Templates" + - "VPS: Post-install scripts" + - "VPS: Public Keys" + - "VPS: Recovery" + - "VPS: Snapshots" + - "VPS: Virtual machine" + - name: Miscellaneous + tags: + - Models diff --git a/backend/db.js b/backend/db.js new file mode 100644 index 0000000..d42f6a0 --- /dev/null +++ b/backend/db.js @@ -0,0 +1,21 @@ +import pg from 'pg'; +import dotenv from 'dotenv'; + +dotenv.config(); + +const { Pool } = pg; + +const pool = new Pool({ + host: process.env.PG_HOST || '10.99.0.3', + port: process.env.PG_PORT || 5432, + database: process.env.PG_DATABASE || 'subdominio', + user: process.env.PG_USER || 'mercado_admin', + password: process.env.PG_PASSWORD || 'mErC4d0_2026_Club3!#', + max: 20, + idleTimeoutMillis: 30000, + connectionTimeoutMillis: 5000, +}); + +export const query = (text, params) => pool.query(text, params); + +export default pool; diff --git a/backend/package-lock.json b/backend/package-lock.json new file mode 100644 index 0000000..09e3091 --- /dev/null +++ b/backend/package-lock.json @@ -0,0 +1,796 @@ +{ + "name": "subdominio-backend", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "subdominio-backend", + "version": "1.0.0", + "dependencies": { + "cors": "^2.8.5", + "dotenv": "^16.4.5", + "express": "^4.19.2" + } + }, + "node_modules/accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "dependencies": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" + }, + "node_modules/body-parser": { + "version": "1.20.5", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.5.tgz", + "integrity": "sha512-3grm+/2tUOvu2cjJkvsIxrv/wVpfXQW4PsQHYm7yk4vfpu7Ekl6nEsYBoJUL6qDwZUx8wUhQ8tR2qz+ad9c9OA==", + "dependencies": { + "bytes": "~3.1.2", + "content-type": "~1.0.5", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "~1.2.0", + "http-errors": "~2.0.1", + "iconv-lite": "~0.4.24", + "on-finished": "~2.4.1", + "qs": "~6.15.1", + "raw-body": "~2.5.3", + "type-is": "~1.6.18", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "dependencies": { + "safe-buffer": "5.2.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", + "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.7.tgz", + "integrity": "sha512-NXdYc3dLr47pBkpUCHtKSwIOQXLVn8dZEuywboCOJY/osA0wFSLlSawr3KN8qXJEyX66FcONTH8EIlVuK0yyFA==" + }, + "node_modules/cors": { + "version": "2.8.6", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.6.tgz", + "integrity": "sha512-tJtZBBHA6vjIAaF6EnIaq6laBBP9aq/Y3ouVJjEfoHbRBcHBAHYcMh/w8LDrk2PvIMMq8gmopa5D4V8RmbrxGw==", + "dependencies": { + "object-assign": "^4", + "vary": "^1" + }, + "engines": { + "node": ">= 0.10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "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==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/dotenv": { + "version": "16.6.1", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.6.1.tgz", + "integrity": "sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.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==" + }, + "node_modules/encodeurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "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==" + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/express": { + "version": "4.22.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.22.2.tgz", + "integrity": "sha512-IuL+Elrou2ZvCFHs18/CIzy2Nzvo25nZ1/D2eIZlz7c+QUayAcYoiM2BthCjs+EBHVpjYjcuLDAiCWgeIX3X1Q==", + "dependencies": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "~1.20.5", + "content-disposition": "~0.5.4", + "content-type": "~1.0.4", + "cookie": "~0.7.1", + "cookie-signature": "~1.0.6", + "debug": "2.6.9", + "depd": "2.0.0", + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "~1.3.1", + "fresh": "~0.5.2", + "http-errors": "~2.0.0", + "merge-descriptors": "1.0.3", + "methods": "~1.1.2", + "on-finished": "~2.4.1", + "parseurl": "~1.3.3", + "path-to-regexp": "~0.1.12", + "proxy-addr": "~2.0.7", + "qs": "~6.15.1", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "~0.19.0", + "serve-static": "~1.16.2", + "setprototypeof": "1.2.0", + "statuses": "~2.0.1", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/finalhandler": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.2.tgz", + "integrity": "sha512-aA4RyPcd3badbdABGDuTXCMTtOneUCAYH/gxoYRTZlIJdF0YPWuGqiAsIrhNnnqdXGswYk6dGujem4w80UJFhg==", + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "on-finished": "~2.4.1", + "parseurl": "~1.3.3", + "statuses": "~2.0.2", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.3.tgz", + "integrity": "sha512-ej4AhfhfL2Q2zpMmLo7U1Uv9+PyhIZpgQLGT1F9miIGmiCJIoCgSmczFdrc97mWT4kVY72KA+WnnhJ5pghSvSg==", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "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==", + "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/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/merge-descriptors": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz", + "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==", + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-inspect": { + "version": "1.13.4", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", + "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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==", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/path-to-regexp": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.13.tgz", + "integrity": "sha512-A/AGNMFN3c8bOlvV9RreMdrv7jsmF9XIfDeCd87+I8RNg6s78BhJxMu69NEMHBSJFxKidViTEdruRwEk/WIKqA==" + }, + "node_modules/proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "dependencies": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/qs": { + "version": "6.15.1", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.15.1.tgz", + "integrity": "sha512-6YHEFRL9mfgcAvql/XhwTvf5jKcOiiupt2FiJxHkiX1z4j7WL8J/jRHYLluORvc1XxB5rV20KoeK00gVJamspg==", + "dependencies": { + "side-channel": "^1.1.0" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/raw-body": { + "version": "2.5.3", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.3.tgz", + "integrity": "sha512-s4VSOf6yN0rvbRZGxs8Om5CWj6seneMwK3oDb4lWDH0UPhWcxwOWw5+qk24bxq87szX1ydrwylIOp2uG1ojUpA==", + "dependencies": { + "bytes": "~3.1.2", + "http-errors": "~2.0.1", + "iconv-lite": "~0.4.24", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "node_modules/send": { + "version": "0.19.2", + "resolved": "https://registry.npmjs.org/send/-/send-0.19.2.tgz", + "integrity": "sha512-VMbMxbDeehAxpOtWJXlcUS5E8iXh6QmN+BkRX1GARS3wRaXEEgzCcB10gTQazO42tpNIya8xIyNx8fll1OFPrg==", + "dependencies": { + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "~0.5.2", + "http-errors": "~2.0.1", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "~2.4.1", + "range-parser": "~1.2.1", + "statuses": "~2.0.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/send/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==" + }, + "node_modules/serve-static": { + "version": "1.16.3", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.3.tgz", + "integrity": "sha512-x0RTqQel6g5SY7Lg6ZreMmsOzncHFU7nhnRWkKgWuMTu5NN0DR5oruckMqRvacAN9d5w6ARnRBXl9xhDCgfMeA==", + "dependencies": { + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "~0.19.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" + }, + "node_modules/side-channel": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", + "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3", + "side-channel-list": "^1.0.0", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-list": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.1.tgz", + "integrity": "sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w==", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", + "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-weakmap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", + "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/statuses": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz", + "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==", + "engines": { + "node": ">= 0.8" + } + }, + "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==", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "engines": { + "node": ">= 0.8" + } + } + } +} diff --git a/backend/package.json b/backend/package.json index b78c998..e15760e 100644 --- a/backend/package.json +++ b/backend/package.json @@ -9,6 +9,7 @@ "dependencies": { "express": "^4.19.2", "cors": "^2.8.5", - "dotenv": "^16.4.5" + "dotenv": "^16.4.5", + "pg": "^8.11.5" } } diff --git a/backend/schema.sql b/backend/schema.sql new file mode 100644 index 0000000..29624bc --- /dev/null +++ b/backend/schema.sql @@ -0,0 +1,32 @@ +-- Tabela de domínios principais +CREATE TABLE IF NOT EXISTS domains ( + id SERIAL PRIMARY KEY, + name VARCHAR(255) UNIQUE NOT NULL, + hostinger_id VARCHAR(255), + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP +); + +-- Tabela de subdomínios (entradas DNS) +CREATE TABLE IF NOT EXISTS subdomains ( + id SERIAL PRIMARY KEY, + domain_id INTEGER REFERENCES domains(id) ON DELETE CASCADE, + subdomain VARCHAR(255) NOT NULL, + full_domain VARCHAR(255) UNIQUE NOT NULL, + type VARCHAR(10) DEFAULT 'A', + value VARCHAR(255) NOT NULL, + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + UNIQUE(domain_id, subdomain) +); + +-- Tabela de branding (identidade visual) +CREATE TABLE IF NOT EXISTS branding ( + id SERIAL PRIMARY KEY, + subdomain_id INTEGER UNIQUE REFERENCES subdomains(id) ON DELETE CASCADE, + logo_url TEXT, + primary_color VARCHAR(50) DEFAULT '#FF6B00', + secondary_color VARCHAR(50) DEFAULT '#1A1A1A', + title VARCHAR(255), + description TEXT, + favicon_url TEXT, + updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP +); diff --git a/backend/server.js b/backend/server.js index aaaff29..4acf064 100644 --- a/backend/server.js +++ b/backend/server.js @@ -1,120 +1,162 @@ import express from 'express'; import cors from 'cors'; -import { readFileSync, writeFileSync, existsSync } from 'fs'; -import { fileURLToPath } from 'url'; -import { dirname, join } from 'path'; +import dotenv from 'dotenv'; +import { query } from './db.js'; -const __dirname = dirname(fileURLToPath(import.meta.url)); -const CONFIG_FILE = join(__dirname, 'config.json'); +dotenv.config(); const app = express(); app.use(cors()); app.use(express.json()); -function loadConfig() { - if (!existsSync(CONFIG_FILE)) return { hostinger_api_key: '' }; - try { return JSON.parse(readFileSync(CONFIG_FILE, 'utf8')); } catch { return { hostinger_api_key: '' }; } -} +// API Key da Hostinger (Fallback para env se não estiver no banco futuramente) +let HOSTINGER_API_KEY = process.env.HOSTINGER_API_KEY || ''; -function saveConfig(data) { - writeFileSync(CONFIG_FILE, JSON.stringify(data, null, 2), 'utf8'); -} - -// GET configuração (mascara a key) +// --- Configuração --- app.get('/api/config', (req, res) => { - const cfg = loadConfig(); - res.json({ has_api_key: !!cfg.hostinger_api_key }); + res.json({ has_api_key: !!HOSTINGER_API_KEY }); }); -// POST salvar API key da Hostinger app.post('/api/config/hostinger-key', (req, res) => { const { api_key } = req.body; if (!api_key?.trim()) return res.status(400).json({ error: 'api_key obrigatória' }); - const cfg = loadConfig(); - cfg.hostinger_api_key = api_key.trim(); - saveConfig(cfg); + HOSTINGER_API_KEY = api_key.trim(); res.json({ ok: true }); }); -// GET listar domínios via Hostinger API (Corrigido para v1/portfolio) -app.get('/api/subdomains', async (req, res) => { - const cfg = loadConfig(); - console.log('[BACKEND] Buscando domínios na Hostinger...'); - if (!cfg.hostinger_api_key) return res.status(400).json({ error: 'API key não configurada' }); +// --- Domínios --- +// Listar domínios salvos no banco +app.get('/api/domains', async (req, res) => { try { - const r = await fetch('https://developers.hostinger.com/api/domains/v1/portfolio', { - headers: { - 'Authorization': `Bearer ${cfg.hostinger_api_key}`, - 'Accept': 'application/json' - } - }); - - console.log('[BACKEND] Status Hostinger:', r.status); - - if (!r.ok) { - const errText = await r.text(); - console.error('[BACKEND] Erro Hostinger:', errText); - return res.status(r.status).json({ error: `Hostinger Error: ${r.status}` }); - } - - const data = await r.json(); - console.log('[BACKEND] Domínios encontrados:', Array.isArray(data) ? data.length : 'Não é array'); - res.json(data); - } catch (e) { - console.error('[BACKEND] Crash fetch:', e.message); - res.status(500).json({ error: e.message }); + const result = await query('SELECT * FROM domains ORDER BY name ASC'); + res.json(result.rows); + } catch (err) { + res.status(500).json({ error: err.message }); } }); -// POST criar subdomínio no DNS da Hostinger (Corrigido para v1/zones/{domain}) -app.post('/api/subdomains', async (req, res) => { - const cfg = loadConfig(); - if (!cfg.hostinger_api_key) return res.status(400).json({ error: 'API key não configurada' }); - - const { domain, subdomain, type = 'A', value } = req.body; - console.log(`[BACKEND] Criando subdomínio ${subdomain}.${domain} -> ${value}`); - - if (!domain || !subdomain || !value) return res.status(400).json({ error: 'domain, subdomain e value obrigatórios' }); +// Sincronizar domínios da Hostinger para o banco +app.post('/api/domains/sync', async (req, res) => { + if (!HOSTINGER_API_KEY) return res.status(400).json({ error: 'API key não configurada' }); try { - const r = await fetch(`https://developers.hostinger.com/api/dns/v1/zones/${domain}`, { + const r = await fetch('https://developers.hostinger.com/api/domains/v1/portfolio', { + headers: { 'Authorization': `Bearer ${HOSTINGER_API_KEY}`, 'Accept': 'application/json' } + }); + + if (!r.ok) { + const errText = await r.text(); + return res.status(r.status).json({ error: `Hostinger Error: ${errText}` }); + } + + const domains = await r.json(); + + for (const dom of domains) { + await query( + 'INSERT INTO domains (name, hostinger_id) VALUES ($1, $2) ON CONFLICT (name) DO UPDATE SET hostinger_id = $2', + [dom.domain, dom.id || null] + ); + } + + const result = await query('SELECT * FROM domains ORDER BY name ASC'); + res.json({ ok: true, domains: result.rows }); + } catch (err) { + res.status(500).json({ error: err.message }); + } +}); + +// --- Subdomínios --- + +// Listar subdomínios de um domínio (do banco) +app.get('/api/domains/:domainId/subdomains', async (req, res) => { + try { + const result = await query( + 'SELECT s.*, b.logo_url, b.primary_color, b.secondary_color, b.title, b.description FROM subdomains s LEFT JOIN branding b ON s.id = b.subdomain_id WHERE s.domain_id = $1 ORDER BY s.subdomain ASC', + [req.params.domainId] + ); + res.json(result.rows); + } catch (err) { + res.status(500).json({ error: err.message }); + } +}); + +// Criar subdomínio (Hostinger + Banco) +app.post('/api/subdomains', async (req, res) => { + if (!HOSTINGER_API_KEY) return res.status(400).json({ error: 'API key não configurada' }); + const { domainId, domainName, subdomain, type = 'A', value } = req.body; + + if (!domainId || !domainName || !subdomain || !value) { + return res.status(400).json({ error: 'Campos obrigatórios ausentes' }); + } + + try { + // 1. Criar na Hostinger + const r = await fetch(`https://developers.hostinger.com/api/dns/v1/zones/${domainName}`, { method: 'PUT', headers: { - 'Authorization': `Bearer ${cfg.hostinger_api_key}`, + 'Authorization': `Bearer ${HOSTINGER_API_KEY}`, 'Content-Type': 'application/json', 'Accept': 'application/json' }, body: JSON.stringify({ overwrite: false, - zone: [ - { - name: subdomain, - type: type, - records: [ - { - content: value, - ttl: 300 - } - ] - } - ] + zone: [{ name: subdomain, type: type, records: [{ content: value, ttl: 300 }] }] }) }); - - console.log('[BACKEND] Status Criação DNS:', r.status); if (!r.ok) { const errText = await r.text(); - console.error('[BACKEND] Erro Criação DNS:', errText); - return res.status(r.status).json({ error: `Erro DNS: ${r.status}` }); + return res.status(r.status).json({ error: `Erro Hostinger: ${errText}` }); } - const data = await r.json(); - res.json({ ok: true, data }); - } catch (e) { - console.error('[BACKEND] Crash Criação DNS:', e.message); - res.status(500).json({ error: e.message }); + // 2. Salvar no Banco + const fullDomain = `${subdomain}.${domainName}`; + const dbResult = await query( + 'INSERT INTO subdomains (domain_id, subdomain, full_domain, type, value) VALUES ($1, $2, $3, $4, $5) ON CONFLICT (full_domain) DO UPDATE SET value = $5 RETURNING *', + [domainId, subdomain, fullDomain, type, value] + ); + + res.json({ ok: true, subdomain: dbResult.rows[0] }); + } catch (err) { + res.status(500).json({ error: err.message }); + } +}); + +// --- Branding / Identidade Visual --- + +app.get('/api/branding/:subdomainId', async (req, res) => { + try { + const result = await query('SELECT * FROM branding WHERE subdomain_id = $1', [req.params.subdomainId]); + res.json(result.rows[0] || {}); + } catch (err) { + res.status(500).json({ error: err.message }); + } +}); + +app.put('/api/branding/:subdomainId', async (req, res) => { + const { logo_url, primary_color, secondary_color, title, description, favicon_url } = req.body; + const subdomainId = req.params.subdomainId; + + try { + const result = await query( + `INSERT INTO branding (subdomain_id, logo_url, primary_color, secondary_color, title, description, favicon_url) + VALUES ($1, $2, $3, $4, $5, $6, $7) + ON CONFLICT (subdomain_id) + DO UPDATE SET + logo_url = EXCLUDED.logo_url, + primary_color = EXCLUDED.primary_color, + secondary_color = EXCLUDED.secondary_color, + title = EXCLUDED.title, + description = EXCLUDED.description, + favicon_url = EXCLUDED.favicon_url, + updated_at = CURRENT_TIMESTAMP + RETURNING *`, + [subdomainId, logo_url, primary_color, secondary_color, title, description, favicon_url] + ); + res.json(result.rows[0]); + } catch (err) { + res.status(500).json({ error: err.message }); } }); diff --git a/deploy-prod-builder.sh b/deploy-prod-builder.sh new file mode 100755 index 0000000..987ae44 --- /dev/null +++ b/deploy-prod-builder.sh @@ -0,0 +1,65 @@ +#!/bin/bash +# ─── deploy-prod-builder-subdominio.sh ─────────────────────────────────────── +# Script sênior de automação de build e despacho (GitOps) de VPS 4 -> VPS 1. +# ───────────────────────────────────────────────────────────────────────────── +set -e + +LOCK_FILE="/tmp/deploy-prod-subdominio.lock" +if [ -f "$LOCK_FILE" ]; then + echo "🚨 Deploy já está em andamento! Aguarde..." + exit 1 +fi +touch "$LOCK_FILE" +trap 'rm -f "$LOCK_FILE"' EXIT + +LOG_FILE="/home/deploy/stack/webhook-listener/deploy.log" +log() { + echo "[$(date -u +'%Y-%m-%dT%H:%M:%SZ')] [SUBDOMINIO] $1" | tee -a "$LOG_FILE" +} + +log "🚀 Iniciando ciclo de build e deploy automático para Subdominio..." + +# 1. Atualizar repositório Git +log "📦 Sincronizando repositório Git local na VPS 4..." +cd /home/deploy/stack/subdominio.clube67.com +git pull origin main + +# 1.1 Incrementar versão +log "🔢 Incrementando versão..." +node update-version.js + +# 2. Compilar o Backend +log "⚙️ Instalando dependências do Backend..." +cd /home/deploy/stack/subdominio.clube67.com/backend +npm install + +# 3. Compilar o Frontend +log "⚙️ Instalando dependências e compilando o Frontend (Vite)..." +cd /home/deploy/stack/subdominio.clube67.com/frontend +npm install +npm run build + +# 4. Sincronizar arquivos com a VPS 1 (Produção) via Rsync VPN +log "🚚 Despachando Backend para a VPS 1 (Produção)..." +rsync -avz --delete \ + --exclude 'node_modules/.cache' \ + /home/deploy/stack/subdominio.clube67.com/backend/ \ + deploy@10.99.0.1:/home/deploy/stack/subdominio.clube67.com/backend/ + +log "🚚 Despachando Frontend (build) para a VPS 1 (Produção)..." +rsync -avz --delete \ + /home/deploy/stack/subdominio.clube67.com/frontend/dist/ \ + deploy@10.99.0.1:/home/deploy/stack/subdominio.clube67.com/frontend/dist/ + +# 5. Reiniciar os serviços de produção na VPS 1 +log "🔄 Reiniciando containers na VPS 1..." +ssh -o BatchMode=yes deploy@10.99.0.1 "cd /home/deploy/stack/subdominio.clube67.com && DOCKER_HOST=unix:///run/user/1000/docker.sock docker compose up -d" + +# 6. Salvar incremento de versão no Git +log "💾 Comitando o incremento de versão de volta para o repositório central..." +cd /home/deploy/stack/subdominio.clube67.com +git add frontend/src/constants.ts +git commit -m "chore(deploy): bump version" +git push origin main + +log "✅ Deploy de Subdominio concluído com absoluto sucesso!" diff --git a/docker-compose.yml b/docker-compose.yml index 919b24d..632adcf 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -12,10 +12,18 @@ services: context: ./backend container_name: subdominio-backend restart: unless-stopped + environment: + - PG_HOST=10.99.0.3 + - PG_PORT=5432 + - PG_DATABASE=subdominio + - PG_USER=mercado_admin + - PG_PASSWORD=mErC4d0_2026_Club3!# + - PORT=8019 volumes: - ./backend/config.json:/app/config.json networks: - subdominio-net + - soc nginx: image: nginx:alpine @@ -30,13 +38,19 @@ services: - backend networks: - subdominio-net + - web labels: - "traefik.enable=true" - "traefik.http.routers.subdominio.rule=Host(`subdominio.clube67.com`)" - "traefik.http.routers.subdominio.entrypoints=websecure" - "traefik.http.routers.subdominio.tls.certresolver=le" - "traefik.http.services.subdominio.loadbalancer.server.port=8021" + - "traefik.docker.network=web" networks: subdominio-net: driver: bridge + soc: + external: true + web: + external: true diff --git a/frontend/Dockerfile b/frontend/Dockerfile index 0fc3369..077c4c4 100644 --- a/frontend/Dockerfile +++ b/frontend/Dockerfile @@ -7,4 +7,5 @@ RUN npm run build FROM nginx:alpine COPY --from=builder /app/frontend/dist /usr/share/nginx/html +COPY nginx.conf /etc/nginx/conf.d/default.conf EXPOSE 3014 diff --git a/frontend/nginx.conf b/frontend/nginx.conf new file mode 100644 index 0000000..42fc5b6 --- /dev/null +++ b/frontend/nginx.conf @@ -0,0 +1 @@ +server { listen 3014; location / { root /usr/share/nginx/html; index index.html; try_files $uri $uri/ /index.html; } } diff --git a/frontend/package-lock.json b/frontend/package-lock.json new file mode 100644 index 0000000..7849b20 --- /dev/null +++ b/frontend/package-lock.json @@ -0,0 +1,2275 @@ +{ + "name": "subdominio-frontend", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "subdominio-frontend", + "version": "1.0.0", + "dependencies": { + "react": "^19.0.0", + "react-dom": "^19.0.0" + }, + "devDependencies": { + "@tailwindcss/vite": "^4.2.0", + "@types/react": "^19.0.0", + "@types/react-dom": "^19.0.0", + "@vitejs/plugin-react": "^5.0.0", + "tailwindcss": "^4.2.0", + "typescript": "~5.8.2", + "vite": "^6.2.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.0.tgz", + "integrity": "sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==", + "dev": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.28.5", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.29.3", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.29.3.tgz", + "integrity": "sha512-LIVqM46zQWZhj17qA8wb4nW/ixr2y1Nw+r1etiAWgRM6U1IqP+LNhL1yg440jYZR72jCWcWbLWzIosH+uP1fqg==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.29.0.tgz", + "integrity": "sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.29.0", + "@babel/generator": "^7.29.0", + "@babel/helper-compilation-targets": "^7.28.6", + "@babel/helper-module-transforms": "^7.28.6", + "@babel/helpers": "^7.28.6", + "@babel/parser": "^7.29.0", + "@babel/template": "^7.28.6", + "@babel/traverse": "^7.29.0", + "@babel/types": "^7.29.0", + "@jridgewell/remapping": "^2.3.5", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/generator": { + "version": "7.29.1", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.1.tgz", + "integrity": "sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==", + "dev": true, + "dependencies": { + "@babel/parser": "^7.29.0", + "@babel/types": "^7.29.0", + "@jridgewell/gen-mapping": "^0.3.12", + "@jridgewell/trace-mapping": "^0.3.28", + "jsesc": "^3.0.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.28.6.tgz", + "integrity": "sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA==", + "dev": true, + "dependencies": { + "@babel/compat-data": "^7.28.6", + "@babel/helper-validator-option": "^7.27.1", + "browserslist": "^4.24.0", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-globals": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz", + "integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.28.6.tgz", + "integrity": "sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw==", + "dev": true, + "dependencies": { + "@babel/traverse": "^7.28.6", + "@babel/types": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.28.6.tgz", + "integrity": "sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA==", + "dev": true, + "dependencies": { + "@babel/helper-module-imports": "^7.28.6", + "@babel/helper-validator-identifier": "^7.28.5", + "@babel/traverse": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.28.6.tgz", + "integrity": "sha512-S9gzZ/bz83GRysI7gAD4wPT/AI3uCnY+9xn+Mx/KPs2JwHJIz1W8PZkg2cqyt3RNOBM8ejcXhV6y8Og7ly/Dug==", + "dev": true, + "engines": { + "node": ">=6.9.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==", + "dev": true, + "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==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz", + "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.29.2", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.29.2.tgz", + "integrity": "sha512-HoGuUs4sCZNezVEKdVcwqmZN8GoHirLUcLaYVNBK2J0DadGtdcqgr3BCbvH8+XUo4NGjNl3VOtSjEKNzqfFgKw==", + "dev": true, + "dependencies": { + "@babel/template": "^7.28.6", + "@babel/types": "^7.29.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.29.3", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.3.tgz", + "integrity": "sha512-b3ctpQwp+PROvU/cttc4OYl4MzfJUWy6FZg+PMXfzmt/+39iHVF0sDfqay8TQM3JA2EUOyKcFZt75jWriQijsA==", + "dev": true, + "dependencies": { + "@babel/types": "^7.29.0" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-self": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.27.1.tgz", + "integrity": "sha512-6UzkCs+ejGdZ5mFFC/OCUrv028ab2fp1znZmCZjAOBKiBK2jXD1O+BPSfX8X2qjJ75fZBMSnQn3Rq2mrBJK2mw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-source": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.27.1.tgz", + "integrity": "sha512-zbwoTsBruTeKB9hSq73ha66iFeJHuaFkUbwvqElnygoNbj/jHRsSeokowZFN3CZ64IvEqcmmkVe89OPXc7ldAw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/template": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.28.6.tgz", + "integrity": "sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.28.6", + "@babel/parser": "^7.28.6", + "@babel/types": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.0.tgz", + "integrity": "sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.29.0", + "@babel/generator": "^7.29.0", + "@babel/helper-globals": "^7.28.0", + "@babel/parser": "^7.29.0", + "@babel/template": "^7.28.6", + "@babel/types": "^7.29.0", + "debug": "^4.3.1" + }, + "engines": { + "node": ">=6.9.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==", + "dev": true, + "dependencies": { + "@babel/helper-string-parser": "^7.27.1", + "@babel/helper-validator-identifier": "^7.28.5" + }, + "engines": { + "node": ">=6.9.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" + ], + "dev": true, + "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" + ], + "dev": true, + "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" + ], + "dev": true, + "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" + ], + "dev": true, + "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" + ], + "dev": true, + "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" + ], + "dev": true, + "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" + ], + "dev": true, + "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" + ], + "dev": true, + "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" + ], + "dev": true, + "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" + ], + "dev": true, + "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" + ], + "dev": true, + "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" + ], + "dev": true, + "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" + ], + "dev": true, + "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" + ], + "dev": true, + "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" + ], + "dev": true, + "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" + ], + "dev": true, + "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" + ], + "dev": true, + "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" + ], + "dev": true, + "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" + ], + "dev": true, + "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" + ], + "dev": true, + "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" + ], + "dev": true, + "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" + ], + "dev": true, + "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" + ], + "dev": true, + "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" + ], + "dev": true, + "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" + ], + "dev": true, + "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" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", + "dev": true, + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/remapping": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", + "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", + "dev": true, + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "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==", + "dev": true + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", + "dev": true, + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@rolldown/pluginutils": { + "version": "1.0.0-rc.3", + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-rc.3.tgz", + "integrity": "sha512-eybk3TjzzzV97Dlj5c+XrBFW57eTNhzod66y9HrBlzJ6NsCrWCp/2kaPS3K9wJmurBC0Tdw4yPjXKZqlznim3Q==", + "dev": true + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.60.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.60.4.tgz", + "integrity": "sha512-F5QXMSiFebS9hKZj02XhWLLnRpJ3B3AROP0tWbFBSj+6kCbg5m9j5JoHKd4mmSVy5mS/IMQloYgYxCuJC0fxEQ==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.60.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.60.4.tgz", + "integrity": "sha512-GxxTKApUpzRhof7poWvCJHRF51C67u1R7D6DiluBE8wKU1u5GWE8t+v81JvJYtbawoBFX1hLv5Ei4eVjkWokaw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.60.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.60.4.tgz", + "integrity": "sha512-tua0TaJxMOB1R0V0RS1jFZ/RpURFDJIOR2A6jWwQeawuFyS4gBW+rntLRaQd0EQ4bd6Vp44Z2rXW+YYDBsj6IA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.60.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.60.4.tgz", + "integrity": "sha512-CSKq7MsP+5PFIcydhAiR1K0UhEI1A2jWXVKHPCBZ151yOutENwvnPocgVHkivu2kviURtCEB6zUQw0vs8RrhMg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.60.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.60.4.tgz", + "integrity": "sha512-+O8OkVdyvXMtJEciu2wS/pzm1IxntEEQx3z5TAVy4l32G0etZn+RsA48ARRrFm6Ri8fvqPQfgrvNxSjKAbnd3g==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.60.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.60.4.tgz", + "integrity": "sha512-Iw3oMskH3AfNuhU0MSN7vNbdi4me/NiYo2azqPz/Le16zHSa+3RRmliCMWWQmh4lcndccU40xcJuTYJZxNo/lw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.60.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.60.4.tgz", + "integrity": "sha512-EIPRXTVQpHyF8WOo219AD2yEltPehLTcTMz2fn6JsatLYSzQf00hj3rulF+yauOlF9/FtM2WpkT/hJh/KJFGhA==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.60.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.60.4.tgz", + "integrity": "sha512-J3Yh9PzzF1Ovah2At+lHiGQdsYgArxBbXv/zHfSyaiFQEqvNv7DcW98pCrmdjCZBrqBiKrKKe2V+aaSGWuBe/w==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.60.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.60.4.tgz", + "integrity": "sha512-BFDEZMYfUvLn37ONE1yMBojPxnMlTFsdyNoqncT0qFq1mAfllL+ATMMJd8TeuVMiX84s1KbcxcZbXInmcO2mRg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.60.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.60.4.tgz", + "integrity": "sha512-pc9EYOSlOgdQ2uPl1o9PF6/kLSgaUosia7gOuS8mB69IxJvlclko1MECXysjs5ryez1/5zjYqx3+xYU0TU6R1A==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-gnu": { + "version": "4.60.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.60.4.tgz", + "integrity": "sha512-NxnomyxYerDh5n4iLrNa+sH+Z+U4BMEE46V2PgQ/hoB909i8gV1M5wPojWg9fk1jWpO3IQnOs20K4wyZuFLEFQ==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-musl": { + "version": "4.60.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.60.4.tgz", + "integrity": "sha512-nbJnQ8a3z1mtmrwImCYhc6BGpThAyYVRQxw9uKSKG4wR6aAYno9sVjJ0zaZcW9BPJX1GbrDPf+SvdWjgTuDmnw==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-gnu": { + "version": "4.60.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.60.4.tgz", + "integrity": "sha512-2EU6acNrQLd8tYvo/LXW535wupT3m6fo7HKo6lr7ktQoItxTyOL1ZCR/GfGCuXl2vR+zmfI6eRXkSemafv+iVg==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-musl": { + "version": "4.60.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.60.4.tgz", + "integrity": "sha512-WeBtoMuaMxiiIrO2IYP3xs6GMWkJP2C0EoT8beTLkUPmzV1i/UcOSVw1d5r9KBODtHKilG5yFxsGRnBbK3wJ4A==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.60.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.60.4.tgz", + "integrity": "sha512-FJHFfqpKUI3A10WrWKiFbBZ7yVbGT4q4B5o1qKFFojqpaYoh9LrQgqWCmmcxQzVSXYtyB5bzkXrYzlHTs21MYA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-musl": { + "version": "4.60.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.60.4.tgz", + "integrity": "sha512-mcEl6CUT5IAUmQf1m9FYSmVqCJlpQ8r8eyftFUHG8i9OhY7BkBXSUdnLH5DOf0wCOjcP9v/QO93zpmF1SptCCw==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.60.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.60.4.tgz", + "integrity": "sha512-ynt3JxVd2w2buzoKDWIyiV1pJW93xlQic1THVLXilz429oijRpSHivZAgp65KBu+cMcgf1eVVjdnTLvPxgCuoQ==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.60.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.60.4.tgz", + "integrity": "sha512-Boiz5+MsaROEWDf+GGEwF8VMHGhlUoQMtIPjOgA5fv4osupqTVnJteQNKJwUcnUog2G55jYXH7KZFFiJe0TEzQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.60.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.60.4.tgz", + "integrity": "sha512-+qfSY27qIrFfI/Hom04KYFw3GKZSGU4lXus51wsb5EuySfFlWRwjkKWoE9emgRw/ukoT4Udsj4W/+xxG8VbPKg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-openbsd-x64": { + "version": "4.60.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.60.4.tgz", + "integrity": "sha512-VpTfOPHgVXEBeeR8hZ2O0F3aSso+JDWqTWmTmzcQKted54IAdUVbxE+j/MVxUsKa8L20HJhv3vUezVPoquqWjA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ] + }, + "node_modules/@rollup/rollup-openharmony-arm64": { + "version": "4.60.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.60.4.tgz", + "integrity": "sha512-IPOsh5aRYuLv/nkU51X10Bf75Bsf6+gZdx1X+QP5QM6lIJFHHqbHLG0uJn/hWthzo13UAc2umiUorqZy3axoZg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "openharmony" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.60.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.60.4.tgz", + "integrity": "sha512-4QzE9E81OohJ/HKzHhsqU+zcYYojVOXlFMs1DdyMT6qXl/niOH7AVElmmEdUNHHS/oRkc++d5k6Vy85zFs0DEw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.60.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.60.4.tgz", + "integrity": "sha512-zTPgT1YuHHcd+Tmx7h8aml0FWFVelV5N54oHow9SLj+GfoDy/huQ+UV396N/C7KpMDMiPspRktzM1/0r1usYEA==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-gnu": { + "version": "4.60.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.60.4.tgz", + "integrity": "sha512-DRS4G7mi9lJxqEDezIkKCaUIKCrLUUDCUaCsTPCi/rtqaC6D/jjwslMQyiDU50Ka0JKpeXeRBFBAXwArY52vBw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.60.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.60.4.tgz", + "integrity": "sha512-QVTUovf40zgTqlFVrKA1uXMVvU2QWEFWfAH8Wdc48IxLvrJMQVMBRjuQyUpzZCDkakImib9eVazbWlC6ksWtJw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@tailwindcss/node": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.3.0.tgz", + "integrity": "sha512-aFb4gUhFOgdh9AXo4IzBEOzBkkAxm9VigwDJnMIYv3lcfXCJVesNfbEaBl4BNgVRyid92AmdviqwBUBRKSeY3g==", + "dev": true, + "dependencies": { + "@jridgewell/remapping": "^2.3.5", + "enhanced-resolve": "^5.21.0", + "jiti": "^2.6.1", + "lightningcss": "1.32.0", + "magic-string": "^0.30.21", + "source-map-js": "^1.2.1", + "tailwindcss": "4.3.0" + } + }, + "node_modules/@tailwindcss/oxide": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.3.0.tgz", + "integrity": "sha512-F7HZGBeN9I0/AuuJS5PwcD8xayx5ri5GhjYUDBEVYUkexyA/giwbDNjRVrxSezE3T250OU2K/wp/ltWx3UOefg==", + "dev": true, + "engines": { + "node": ">= 20" + }, + "optionalDependencies": { + "@tailwindcss/oxide-android-arm64": "4.3.0", + "@tailwindcss/oxide-darwin-arm64": "4.3.0", + "@tailwindcss/oxide-darwin-x64": "4.3.0", + "@tailwindcss/oxide-freebsd-x64": "4.3.0", + "@tailwindcss/oxide-linux-arm-gnueabihf": "4.3.0", + "@tailwindcss/oxide-linux-arm64-gnu": "4.3.0", + "@tailwindcss/oxide-linux-arm64-musl": "4.3.0", + "@tailwindcss/oxide-linux-x64-gnu": "4.3.0", + "@tailwindcss/oxide-linux-x64-musl": "4.3.0", + "@tailwindcss/oxide-wasm32-wasi": "4.3.0", + "@tailwindcss/oxide-win32-arm64-msvc": "4.3.0", + "@tailwindcss/oxide-win32-x64-msvc": "4.3.0" + } + }, + "node_modules/@tailwindcss/oxide-android-arm64": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.3.0.tgz", + "integrity": "sha512-TJPiq67tKlLuObP6RkwvVGDoxCMBVtDgKkLfa/uyj7/FyxvQwHS+UOnVrXXgbEsfUaMgiVvC4KbJnRr26ho4Ng==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-darwin-arm64": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.3.0.tgz", + "integrity": "sha512-oMN/WZRb+SO37BmUElEgeEWuU8E/HXRkiODxJxLe1UTHVXLrdVSgfaJV7pSlhRGMSOiXLuxTIjfsF3wYvz8cgQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-darwin-x64": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.3.0.tgz", + "integrity": "sha512-N6CUmu4a6bKVADfw77p+iw6Yd9Q3OBhe0veaDX+QazfuVYlQsHfDgxBrsjQ/IW+zywL8mTrNd0SdJT/zgtvMdA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-freebsd-x64": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.3.0.tgz", + "integrity": "sha512-zDL5hBkQdH5C6MpqbK3gQAgP80tsMwSI26vjOzjJtNCMUo0lFgOItzHKBIupOZNQxt3ouPH7RPhvNhiTfCe5CQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-linux-arm-gnueabihf": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.3.0.tgz", + "integrity": "sha512-R06HdNi7A7OEoMsf6d4tjZ71RCWnZQPHj2mnotSFURjNLdBC+cIgXQ7l81CqeoiQftjf6OOblxXMInMgN2VzMA==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-linux-arm64-gnu": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.3.0.tgz", + "integrity": "sha512-qTJHELX8jetjhRQHCLilkVLmybpzNQAtaI/gaoVoidn/ufbNDbAo8KlK2J+yPoc8wQxvDxCmh/5lr8nC1+lTbg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-linux-arm64-musl": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.3.0.tgz", + "integrity": "sha512-Z6sukiQsngnWO+l39X4pPbiWT81IC+PLKF+PHxIlyZbGNb9MODfYlXEVlFvej5BOZInWX01kVyzeLvHsXhfczQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-linux-x64-gnu": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.3.0.tgz", + "integrity": "sha512-DRNdQRpSGzRGfARVuVkxvM8Q12nh19l4BF/G7zGA1oe+9wcC6saFBHTISrpIcKzhiXtSrlSrluCfvMuledoCTQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-linux-x64-musl": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.3.0.tgz", + "integrity": "sha512-Z0IADbDo8bh6I7h2IQMx601AdXBLfFpEdUotft86evd/8ZPflZe9COPO8Q1vw+pfLWIUo9zN/JGZvwuAJqduqg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-wasm32-wasi": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.3.0.tgz", + "integrity": "sha512-HNZGOUxEmElksYR7S6sC5jTeNGpobAsy9u7Gu0AskJ8/20FR9GqebUyB+HBcU/ax6BHuiuJi+Oda4B+YX6H1yA==", + "bundleDependencies": [ + "@napi-rs/wasm-runtime", + "@emnapi/core", + "@emnapi/runtime", + "@tybys/wasm-util", + "@emnapi/wasi-threads", + "tslib" + ], + "cpu": [ + "wasm32" + ], + "dev": true, + "optional": true, + "dependencies": { + "@emnapi/core": "^1.10.0", + "@emnapi/runtime": "^1.10.0", + "@emnapi/wasi-threads": "^1.2.1", + "@napi-rs/wasm-runtime": "^1.1.4", + "@tybys/wasm-util": "^0.10.1", + "tslib": "^2.8.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@tailwindcss/oxide-win32-arm64-msvc": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.3.0.tgz", + "integrity": "sha512-Pe+RPVTi1T+qymuuRpcdvwSVZjnll/f7n8gBxMMh3xLTctMDKqpdfGimbMyioqtLhUYZxdJ9wGNhV7MKHvgZsQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-win32-x64-msvc": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.3.0.tgz", + "integrity": "sha512-Mvrf2kXW/yeW/OTezZlCGOirXRcUuLIBx/5Y12BaPM7wJoryG6dfS/NJL8aBPqtTEx/Vm4T4vKzFUcKDT+TKUA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/vite": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/@tailwindcss/vite/-/vite-4.3.0.tgz", + "integrity": "sha512-t6J3OrB5Fc0ExuhohouH0fWUGMYL6PTLhW+E7zIk/pdbnJARZDCwjBznFnkh5ynRnIRSI4YjtTH0t6USjJISrw==", + "dev": true, + "dependencies": { + "@tailwindcss/node": "4.3.0", + "@tailwindcss/oxide": "4.3.0", + "tailwindcss": "4.3.0" + }, + "peerDependencies": { + "vite": "^5.2.0 || ^6 || ^7 || ^8" + } + }, + "node_modules/@types/babel__core": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", + "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", + "dev": true, + "dependencies": { + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "node_modules/@types/babel__generator": { + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.27.0.tgz", + "integrity": "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==", + "dev": true, + "dependencies": { + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__template": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", + "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", + "dev": true, + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__traverse": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.28.0.tgz", + "integrity": "sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==", + "dev": true, + "dependencies": { + "@babel/types": "^7.28.2" + } + }, + "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==", + "dev": true + }, + "node_modules/@types/react": { + "version": "19.2.14", + "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.14.tgz", + "integrity": "sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w==", + "dev": true, + "dependencies": { + "csstype": "^3.2.2" + } + }, + "node_modules/@types/react-dom": { + "version": "19.2.3", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.2.3.tgz", + "integrity": "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==", + "dev": true, + "peerDependencies": { + "@types/react": "^19.2.0" + } + }, + "node_modules/@vitejs/plugin-react": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-5.2.0.tgz", + "integrity": "sha512-YmKkfhOAi3wsB1PhJq5Scj3GXMn3WvtQ/JC0xoopuHoXSdmtdStOpFrYaT1kie2YgFBcIe64ROzMYRjCrYOdYw==", + "dev": true, + "dependencies": { + "@babel/core": "^7.29.0", + "@babel/plugin-transform-react-jsx-self": "^7.27.1", + "@babel/plugin-transform-react-jsx-source": "^7.27.1", + "@rolldown/pluginutils": "1.0.0-rc.3", + "@types/babel__core": "^7.20.5", + "react-refresh": "^0.18.0" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "peerDependencies": { + "vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/baseline-browser-mapping": { + "version": "2.10.29", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.29.tgz", + "integrity": "sha512-Asa2krT+XTPZINCS+2QcyS8WTkObE77RwkydwF7h6DmnKqbvlalz93m/dnphUyCa6SWSP51VgtEUf2FN+gelFQ==", + "dev": true, + "bin": { + "baseline-browser-mapping": "dist/cli.cjs" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/browserslist": { + "version": "4.28.2", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.2.tgz", + "integrity": "sha512-48xSriZYYg+8qXna9kwqjIVzuQxi+KYWp2+5nCYnYKPTr0LvD89Jqk2Or5ogxz0NUMfIjhh2lIUX/LyX9B4oIg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "baseline-browser-mapping": "^2.10.12", + "caniuse-lite": "^1.0.30001782", + "electron-to-chromium": "^1.5.328", + "node-releases": "^2.0.36", + "update-browserslist-db": "^1.2.3" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001792", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001792.tgz", + "integrity": "sha512-hVLMUZFgR4JJ6ACt1uEESvQN1/dBVqPAKY0hgrV70eN3391K6juAfTjKZLKvOMsx8PxA7gsY1/tLMMTcfFLLpw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ] + }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true + }, + "node_modules/csstype": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz", + "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==", + "dev": true + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "dev": true, + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "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==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/electron-to-chromium": { + "version": "1.5.356", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.356.tgz", + "integrity": "sha512-9NgFd7m5t5MCJ5rUSjJITUXAH9mEGlrlofnMf4YEr+pz6JlP7cWmTAH+JFmbPnaSW8koVTkuW7pacORWAnA5Yw==", + "dev": true + }, + "node_modules/enhanced-resolve": { + "version": "5.21.3", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.21.3.tgz", + "integrity": "sha512-QyL119InA+XXEkNLNTPCXPugSvOfhwv0JOlGNzvxs0hZaiHLNvXSpudUWsOlsXGWJh8G6ckCScEkVHfX3kw/2Q==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.3.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/esbuild": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.12.tgz", + "integrity": "sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==", + "dev": true, + "hasInstallScript": true, + "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/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true + }, + "node_modules/jiti": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.7.0.tgz", + "integrity": "sha512-AC/7JofJvZGrrneWNaEnJeOLUx+JlGt7tNa0wZiRPT4MY1wmfKjt2+6O2p2uz2+skll8OZZmJMNqeke7kKbNgQ==", + "dev": true, + "bin": { + "jiti": "lib/jiti-cli.mjs" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "node_modules/jsesc": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", + "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", + "dev": true, + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/lightningcss": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.32.0.tgz", + "integrity": "sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==", + "dev": true, + "dependencies": { + "detect-libc": "^2.0.3" + }, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "lightningcss-android-arm64": "1.32.0", + "lightningcss-darwin-arm64": "1.32.0", + "lightningcss-darwin-x64": "1.32.0", + "lightningcss-freebsd-x64": "1.32.0", + "lightningcss-linux-arm-gnueabihf": "1.32.0", + "lightningcss-linux-arm64-gnu": "1.32.0", + "lightningcss-linux-arm64-musl": "1.32.0", + "lightningcss-linux-x64-gnu": "1.32.0", + "lightningcss-linux-x64-musl": "1.32.0", + "lightningcss-win32-arm64-msvc": "1.32.0", + "lightningcss-win32-x64-msvc": "1.32.0" + } + }, + "node_modules/lightningcss-android-arm64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.32.0.tgz", + "integrity": "sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-arm64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.32.0.tgz", + "integrity": "sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-x64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.32.0.tgz", + "integrity": "sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-freebsd-x64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.32.0.tgz", + "integrity": "sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm-gnueabihf": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.32.0.tgz", + "integrity": "sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-gnu": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.32.0.tgz", + "integrity": "sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-musl": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.32.0.tgz", + "integrity": "sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-gnu": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.32.0.tgz", + "integrity": "sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-musl": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.32.0.tgz", + "integrity": "sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-arm64-msvc": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.32.0.tgz", + "integrity": "sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-x64-msvc": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.32.0.tgz", + "integrity": "sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "dependencies": { + "yallist": "^3.0.2" + } + }, + "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==", + "dev": true, + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.5" + } + }, + "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==", + "dev": true + }, + "node_modules/nanoid": { + "version": "3.3.12", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.12.tgz", + "integrity": "sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/node-releases": { + "version": "2.0.44", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.44.tgz", + "integrity": "sha512-5WUyunoPMsvvEhS8AxHtRzP+oA8UCkJ7YRxatWKjngndhDGLiqEVAQKWjFAiAiuL8zMRGzGSJxFnLetoa43qGQ==", + "dev": true + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true + }, + "node_modules/picomatch": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", + "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/postcss": { + "version": "8.5.14", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.14.tgz", + "integrity": "sha512-SoSL4+OSEtR99LHFZQiJLkT59C5B1amGO1NzTwj7TT1qCUgUO6hxOvzkOYxD+vMrXBM3XJIKzokoERdqQq/Zmg==", + "dev": true, + "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" + } + ], + "dependencies": { + "nanoid": "^3.3.11", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/react": { + "version": "19.2.6", + "resolved": "https://registry.npmjs.org/react/-/react-19.2.6.tgz", + "integrity": "sha512-sfWGGfavi0xr8Pg0sVsyHMAOziVYKgPLNrS7ig+ivMNb3wbCBw3KxtflsGBAwD3gYQlE/AEZsTLgToRrSCjb0Q==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-dom": { + "version": "19.2.6", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.6.tgz", + "integrity": "sha512-0prMI+hvBbPjsWnxDLxlCGyM8PN6UuWjEUCYmZhO67xIV9Xasa/r/vDnq+Xyq4Lo27g8QSbO5YzARu0D1Sps3g==", + "dependencies": { + "scheduler": "^0.27.0" + }, + "peerDependencies": { + "react": "^19.2.6" + } + }, + "node_modules/react-refresh": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.18.0.tgz", + "integrity": "sha512-QgT5//D3jfjJb6Gsjxv0Slpj23ip+HtOpnNgnb2S5zU3CB26G/IDPGoy4RJB42wzFE46DRsstbW6tKHoKbhAxw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/rollup": { + "version": "4.60.4", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.60.4.tgz", + "integrity": "sha512-WHeFSbZYsPu3+bLoNRUuAO+wavNlocOPf3wSHTP7hcFKVnJeWsYlCDbr3mTS14FCizf9ccIxXA8sGL8zKeQN3g==", + "dev": true, + "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.60.4", + "@rollup/rollup-android-arm64": "4.60.4", + "@rollup/rollup-darwin-arm64": "4.60.4", + "@rollup/rollup-darwin-x64": "4.60.4", + "@rollup/rollup-freebsd-arm64": "4.60.4", + "@rollup/rollup-freebsd-x64": "4.60.4", + "@rollup/rollup-linux-arm-gnueabihf": "4.60.4", + "@rollup/rollup-linux-arm-musleabihf": "4.60.4", + "@rollup/rollup-linux-arm64-gnu": "4.60.4", + "@rollup/rollup-linux-arm64-musl": "4.60.4", + "@rollup/rollup-linux-loong64-gnu": "4.60.4", + "@rollup/rollup-linux-loong64-musl": "4.60.4", + "@rollup/rollup-linux-ppc64-gnu": "4.60.4", + "@rollup/rollup-linux-ppc64-musl": "4.60.4", + "@rollup/rollup-linux-riscv64-gnu": "4.60.4", + "@rollup/rollup-linux-riscv64-musl": "4.60.4", + "@rollup/rollup-linux-s390x-gnu": "4.60.4", + "@rollup/rollup-linux-x64-gnu": "4.60.4", + "@rollup/rollup-linux-x64-musl": "4.60.4", + "@rollup/rollup-openbsd-x64": "4.60.4", + "@rollup/rollup-openharmony-arm64": "4.60.4", + "@rollup/rollup-win32-arm64-msvc": "4.60.4", + "@rollup/rollup-win32-ia32-msvc": "4.60.4", + "@rollup/rollup-win32-x64-gnu": "4.60.4", + "@rollup/rollup-win32-x64-msvc": "4.60.4", + "fsevents": "~2.3.2" + } + }, + "node_modules/scheduler": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.27.0.tgz", + "integrity": "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==" + }, + "node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "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==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/tailwindcss": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.3.0.tgz", + "integrity": "sha512-y6nxMGB1nMW9R6k96e5gdIFzcfL/gTJRNaqGes1YvkLnPVXzWgbqFF2yLC0T8G774n24cx3Pe8XrKoniCOAH+Q==", + "dev": true + }, + "node_modules/tapable": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.3.3.tgz", + "integrity": "sha512-uxc/zpqFg6x7C8vOE7lh6Lbda8eEL9zmVm/PLeTPBRhh1xCgdWaQ+J1CUieGpIfm2HdtsUpRv+HshiasBMcc6A==", + "dev": true, + "engines": { + "node": ">=6" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/tinyglobby": { + "version": "0.2.16", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.16.tgz", + "integrity": "sha512-pn99VhoACYR8nFHhxqix+uvsbXineAasWm5ojXoN8xEwK5Kd3/TrhNn1wByuD52UxWRLy8pu+kRMniEi6Eq9Zg==", + "dev": true, + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.4" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/typescript": { + "version": "5.8.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz", + "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz", + "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "escalade": "^3.2.0", + "picocolors": "^1.1.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/vite": { + "version": "6.4.2", + "resolved": "https://registry.npmjs.org/vite/-/vite-6.4.2.tgz", + "integrity": "sha512-2N/55r4JDJ4gdrCvGgINMy+HH3iRpNIz8K6SFwVsA+JbQScLiC+clmAxBgwiSPgcG9U15QmvqCGWzMbqda5zGQ==", + "dev": true, + "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/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true + } + } +} diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index 228aac6..1f1926b 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -4,9 +4,24 @@ import { APP_VERSION } from './constants'; const API = '/api'; interface Domain { - domain: string; - id?: number; - status?: string; + id: number; + name: string; + hostinger_id?: string; +} + +interface Subdomain { + id: number; + domain_id: number; + subdomain: string; + full_domain: string; + type: string; + value: string; + logo_url?: string; + primary_color?: string; + secondary_color?: string; + title?: string; + description?: string; + favicon_url?: string; } export default function App() { @@ -18,19 +33,48 @@ export default function App() { const [error, setError] = useState(''); const [success, setSuccess] = useState(''); + // Navigation states + const [selectedDomain, setSelectedDomain] = useState(null); + const [subdomains, setSubdomains] = useState([]); + const [loadingSubdomains, setLoadingSubdomains] = useState(false); + const [editingBranding, setEditingBranding] = useState(null); + // Form states - const [selectedDomain, setSelectedDomain] = useState(''); const [newSubdomain, setNewSubdomain] = useState(''); const [newValue, setNewValue] = useState(''); const [creating, setCreating] = useState(false); + // Branding states + const [brandingForm, setBrandingForm] = useState({ + title: '', + description: '', + logo_url: '', + primary_color: '#FF6B00', + secondary_color: '#1A1A1A', + favicon_url: '' + }); + useEffect(() => { - fetch(`${API}/config`) - .then(r => r.json()) - .then(d => setHasKey(d.has_api_key)) - .catch(() => setHasKey(false)); + fetchConfig(); + fetchDomains(); }, []); + useEffect(() => { + if (selectedDomain) { + fetchSubdomains(selectedDomain.id); + } + }, [selectedDomain]); + + async function fetchConfig() { + try { + const r = await fetch(`${API}/config`); + const d = await r.json(); + setHasKey(d.has_api_key); + } catch (e) { + setHasKey(false); + } + } + async function saveKey() { if (!apiKeyInput.trim()) return; setSaving(true); @@ -45,7 +89,8 @@ export default function App() { if (r.ok) { setHasKey(true); setApiKeyInput(''); - setSuccess('Chave API salva e configurada com sucesso.'); + setSuccess('Chave API salva e configurada.'); + fetchDomains(); } else { const d = await r.json(); setError(d.error || 'Erro ao salvar chave.'); @@ -55,25 +100,45 @@ export default function App() { async function fetchDomains() { setLoadingDomains(true); - setError(''); - setSuccess(''); try { - const r = await fetch(`${API}/subdomains`); - const d = await r.json(); + const r = await fetch(`${API}/domains`); if (r.ok) { - setDomains(Array.isArray(d) ? d : d.data || []); - } else { - setError(d.error || 'Erro ao buscar domínios na Hostinger.'); + const d = await r.json(); + setDomains(d); } } finally { setLoadingDomains(false); } } + async function syncDomains() { + setLoadingDomains(true); + setError(''); + setSuccess(''); + try { + const r = await fetch(`${API}/domains/sync`, { method: 'POST' }); + const d = await r.json(); + if (r.ok) { + setDomains(d.domains); + setSuccess('Sincronização concluída com sucesso!'); + } else { + setError(d.error || 'Erro na sincronização.'); + } + } finally { setLoadingDomains(false); } + } + + async function fetchSubdomains(domainId: number) { + setLoadingSubdomains(true); + try { + const r = await fetch(`${API}/domains/${domainId}/subdomains`); + if (r.ok) { + const d = await r.json(); + setSubdomains(d); + } + } finally { setLoadingSubdomains(false); } + } + async function createSubdomain(e: React.FormEvent) { e.preventDefault(); - if (!selectedDomain || !newSubdomain || !newValue) { - setError('Preencha todos os campos do subdomínio.'); - return; - } + if (!selectedDomain || !newSubdomain || !newValue) return; setCreating(true); setError(''); setSuccess(''); @@ -82,201 +147,371 @@ export default function App() { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ - domain: selectedDomain, + domainId: selectedDomain.id, + domainName: selectedDomain.name, subdomain: newSubdomain, value: newValue }) }); - const d = await r.json(); if (r.ok) { - setSuccess(`Sucesso! ${newSubdomain}.${selectedDomain} foi criado/atualizado.`); + setSuccess(`Subdomínio ${newSubdomain}.${selectedDomain.name} criado.`); setNewSubdomain(''); setNewValue(''); + fetchSubdomains(selectedDomain.id); } else { + const d = await r.json(); setError(d.error || 'Erro ao criar subdomínio.'); } - } catch (err: any) { - setError(err.message); } finally { setCreating(false); } } - return ( -
-
+ function openBranding(sub: Subdomain) { + setEditingBranding(sub); + setBrandingForm({ + title: sub.title || '', + description: sub.description || '', + logo_url: sub.logo_url || '', + primary_color: sub.primary_color || '#FF6B00', + secondary_color: sub.secondary_color || '#1A1A1A', + favicon_url: sub.favicon_url || '' + }); + } + async function saveBranding() { + if (!editingBranding) return; + try { + const r = await fetch(`${API}/branding/${editingBranding.id}`, { + method: 'PUT', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify(brandingForm) + }); + if (r.ok) { + setSuccess('Identidade visual atualizada!'); + setEditingBranding(null); + if (selectedDomain) fetchSubdomains(selectedDomain.id); + } + } catch (e: any) { + setError(e.message); + } + } + + return ( +
+ + {/* BACKGROUND DECORATION */} +
+
+
+
+ +
+ {/* HEADER */} -
-
-
- C +
+
+
+ S
-

Gerenciador de DNS

-

Clube67 — Automação Hostinger

+

Subdominio.Manager

+

Identidade Visual & DNS

- - {hasKey && ( -
-
- API Hostinger Ativa -
- )} -
-
- - {/* COLUNA ESQUERDA: CONFIG & LISTA */} -
- - {/* CONFIG CARD */} - {!hasKey && ( -
-

Configuração Necessária

-
- setApiKeyInput(e.target.value)} - className="w-full bg-gray-950 border border-gray-800 rounded-2xl px-5 py-4 text-sm focus:outline-none focus:border-orange-500/50 transition-all placeholder:text-gray-700" - /> - -
-
- )} - - {/* LISTA DE DOMÍNIOS */} +
{hasKey && ( -
-
-

Meus Domínios

- + )} +
+ v{APP_VERSION} +
+
+
+ + {/* ALERTS */} + {(error || success) && ( +
+ {error &&
🚨 {error}
} + {success &&
✅ {success}
} +
+ )} + + {!hasKey && hasKey !== null && ( +
+

Configuração da API

+

Insira sua chave de API da Hostinger para começar a gerenciar seus domínios e identidades visuais.

+
+ setApiKeyInput(e.target.value)} + className="w-full bg-gray-950/50 border border-gray-800 rounded-2xl px-6 py-5 text-sm focus:outline-none focus:border-orange-500 transition-all text-center" + /> + +
+
+ )} + + {hasKey && ( +
+ + {/* DOMAIN CARDS GRID */} +
+
+

Selecione um Domínio

+
+
+ +
+ {domains.map((dom) => ( + + ))} +
+
+ + {/* SELECTED DOMAIN VIEW */} + {selectedDomain && ( +
+ + {/* SUBDOMAINS LIST */} +
+
+

Subdomínios de {selectedDomain.name}

+ + {subdomains.length} registros + +
+ +
+ {subdomains.map((sub) => ( +
+
+
+ {sub.logo_url ? ( + Logo + ) : ( +
+ {sub.subdomain.charAt(0).toUpperCase()} +
+ )} +
+

{sub.full_domain}

+

Aponta para: {sub.value}

+
+
+ +
+ +
+
+
+
+
+ ))} + + {/* ADD NEW BOX */} +
+
+ + +
+

Novo Subdomínio

+
+
-
- {domains.length === 0 ? ( -
-

Clique em sincronizar para listar seus domínios da Hostinger.

-
- ) : ( - domains.map((d, i) => ( + {/* CREATE FORM */} +
+
+

Criar Subdomínio

+
+
+ +
+ setNewSubdomain(e.target.value)} + className="flex-1 bg-transparent px-5 py-4 text-sm focus:outline-none" + /> + .{selectedDomain.name} +
+
+
+ + setNewValue(e.target.value)} + className="w-full bg-gray-950 border border-gray-800 rounded-2xl px-5 py-4 text-sm focus:outline-none focus:border-orange-500 transition-all" + /> +
- )) - )} +
+
+
)}
+ )} - {/* COLUNA DIREITA: FORMULÁRIO DE CRIAÇÃO */} -
-
-
- DNS + {/* BRANDING MODAL */} + {editingBranding && ( +
+
+
+
+

Identidade Visual

+

{editingBranding.full_domain}

+
+ +
+ +
+
+
+ + setBrandingForm({...brandingForm, title: e.target.value})} + className="w-full bg-gray-950 border border-gray-800 rounded-2xl px-4 py-3 text-sm focus:outline-none focus:border-orange-500 transition-all" + /> +
+
+ +