{"id":30208315,"url":"https://github.com/Lissy93/domain-locker","last_synced_at":"2025-08-13T17:05:14.490Z","repository":{"id":282727561,"uuid":"868173860","full_name":"Lissy93/domain-locker","owner":"Lissy93","description":"🌐 The all-in-one tool, for keeping track of your domain name portfolio. Got domain names? Get Domain Locker!","archived":false,"fork":false,"pushed_at":"2025-07-25T19:52:48.000Z","size":28072,"stargazers_count":280,"open_issues_count":3,"forks_count":25,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-07-25T21:40:54.336Z","etag":null,"topics":["alternative-to","automation","dashboard","docker","domain-investment","domain-management","monitoring","saas","saas-application","self-hosted","status-page","web-security"],"latest_commit_sha":null,"homepage":"https://domain-locker.com","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Lissy93.png","metadata":{"files":{"readme":".github/README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":".github/CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null},"funding":{"github":["lissy93"]}},"created_at":"2024-10-05T17:03:06.000Z","updated_at":"2025-07-25T14:46:25.000Z","dependencies_parsed_at":"2025-07-12T11:29:46.363Z","dependency_job_id":"56a80ee4-813e-437d-abe6-94ffabd160ab","html_url":"https://github.com/Lissy93/domain-locker","commit_stats":null,"previous_names":["lissy93/domain-locker"],"tags_count":10,"template":false,"template_full_name":null,"purl":"pkg:github/Lissy93/domain-locker","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Lissy93%2Fdomain-locker","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Lissy93%2Fdomain-locker/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Lissy93%2Fdomain-locker/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Lissy93%2Fdomain-locker/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Lissy93","download_url":"https://codeload.github.com/Lissy93/domain-locker/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Lissy93%2Fdomain-locker/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":270278337,"owners_count":24557172,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-13T02:00:09.904Z","response_time":66,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["alternative-to","automation","dashboard","docker","domain-investment","domain-management","monitoring","saas","saas-application","self-hosted","status-page","web-security"],"created_at":"2025-08-13T17:03:16.070Z","updated_at":"2025-08-13T17:05:14.471Z","avatar_url":"https://github.com/Lissy93.png","language":"TypeScript","funding_links":["https://github.com/sponsors/lissy93"],"categories":["TypeScript","automation"],"sub_categories":[],"readme":"\u003ch1 align=\"center\"\u003eDomain Locker\u003c/h1\u003e\n\u003cp align=\"center\"\u003e\n\t\u003ci\u003eThe Central Hub for all your Domain Names\u003c/i\u003e\n  \u003cbr\u003e\n  \u003cb\u003e🌐\u003ca href=\"https://domain-locker.com\"\u003edomain-locker.com\u003c/a\u003e\u003c/b\u003e\n\u003c/p\u003e\n\u003cp align=\"center\"\u003e\n  \u003cimg width=\"48\" src=\"https://github.com/Lissy93/domain-locker/blob/main/src/assets/logo.png?raw=true\" /\u003e\n\u003c/p\u003e\n\n\u003cdetails\u003e\n  \u003csummary\u003e\u003cb\u003eContents\u003c/b\u003e\u003c/summary\u003e\n  \n  - [About](#about)\n\t- [Screenshot](#screenshot)\n\t- [Features](#features)\n\t- [Live Demo](#demo)\n- [Get Started](#get-started)\n\t- [Domain-Locker.com](#option-1-domain-lockercom)\n\t- [Self-Hosting](#option-2-self-hosting)\n- [Developing](#developing)\n  - [App Setup](#project-setup)\n  - [Architecture](#architecture)\n- [Contributing](#contributing)\n- [Attributions](#attributions)\n- [License](#license)\n\u003c/details\u003e\n\n## About\n\nThe aim of Domain Locker, is to give you complete visibility of your domain name portfolio, in once central place.\n\nFor each domain you add, we analyse it and fetch all associated data. We then continuously monitor your domains, and notify you (according to your preferences) when something important changes or when it's soon to expire. So you'll get detailed domain analysis, security insights, change history, recent performance, valuation data and much more.\n\nWith Domain Locker, you'll never again loose track of your domains, miss an expiration, or forget which registrar and providers each domain uses.\n\n### Screenshot\n\n\u003csup\u003e(Sorry about the 5fps, I wanted to keep file size down!)\u003c/sup\u003e\n\n\u003cp align=\"center\"\u003e\n\u003cimg width=\"800\" src=\"/.github/screenshots/quick-demo.gif\" /\u003e\u003cbr\u003e\n\u003cimg width=\"800\" src=\"/.github/screenshots/screenshot-grid.png\" /\u003e\n\u003c/p\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003eMore screenshots...\u003c/summary\u003e\n\u003cp align=\"center\"\u003e\n\u003cimg width=\"800\" src=\"/.github/screenshots/domain-locker-viz-screenshots.png\" /\u003e\n\u003cimg width=\"800\" src=\"/.github/screenshots/domain-locker-settings-screenshots.png\" /\u003e\n\u003c/p\u003e\n\u003c/details\u003e\n\n\n### Features\n\n- 👁️ Total visibility of all your domains and upcoming expirations\n- 📡 Auto-fetched data: SSL certs, hosts, registrars, IPs, subdomains, DNS, etc\n- 🔬 View detailed metrics and analysis for each domain\n- 📊 Visual analytics and breakdowns and trends across your portfolio\n- 💬 Configurable alerts and webhook notifications\n- 🗃️ Easy import/export, as well as API data access\n- 📜 Track changes in domain configuration over time\n- 📈 Monitor website health, security and performance\n- 💹 Keep record of purchase prices and renewal costs\n- 🔖 Add categories, and link related resources to domains\n- 🎨 Multi-language support, dark/light/custom themes\n\n\u003cdetails\u003e\n\u003csummary\u003eMore features...\u003c/summary\u003e\n\n```mermaid\n%%{init: {\"theme\": \"default\"}}%%\nkanban\n    🌐 Domain Data\n        🛰️ Auto-fetch assets: SSL, hosts, registrars, IPs, DNS, subdomains\n        🔎 Detailed domain data like SSL, hosts, registrars, IPs and more\n        🏷️ Enrich data with tags, notes, costs, and other metadata to track\n        🖇️ Connection with external tools for more data\n    📊 Metrics\n        🗂️ Breakdown of domain providers: registrars, SSL, hosts\n        🕒 Timeline of registrations and upcoming expirations\n        📶 Monitor domain uptime, performance and health\n        💹 Record valuation, purchase prices and renewal costs\n    🔔 Notifications\n        ⏱️ Get notified before your domain is due to expire\n        📲 Configurable alerts for monitoring changes in domain config\n        📬 Multiple channels: webhook, email, SMS, Slack, Telegram, WhatsApp and more\n        🛤️ Track change history of each domain\n    🛡️ Data\n        💽 Own your data: Export, import, delte at any time\n        ⌨️ Programatic access via a REST or GraphQL API, or with RSS, iCal, Prometheus integrations\n        📈 Keep detailed change logs of all domain updates\n        🔐 Transparent privacy policy\n    🛠️ Customization\n        👤 SSO and 2FA supported\n        🎨 Custom themes, fonts, light/dark mode\n        🌍 Multi-language support\n        💻 Open-source and self-hostable\n        ✅ Accessible, responsive, and well-documented\n```\n\n\u003c/details\u003e\n\n### Demo\n\nTry the live demo to [demo.domain-locker.com](https://demo.domain-locker.com) \u003cbr\u003e\n(Username: `demo@domain-locker.com` Password: `domainlocker`)\n\n---\n\n## Get Started\n\nTo use Domain Locker, you have two options:\n1. 💻 The managed instance, at **[domain-locker.com](https://domain-locker.com/)** _(free)_\n2. 🏗️ Or **[self-hosting](#deployment)** yourself via Docker _(also free, ofc!)_\n\n### Option 1: Domain-Locker.com\nHead to [our website](https://domain-locker.com), and sign up with Google, GitHub or your email.\u003cbr\u003e\nThe starter plan is free, and no setup is required. Just sign in, add your domains, and start tracking them.\n\n### Option 2: Self-Hosting\n\n```bash\ncurl -fsSL https://install.domain-locker.com | bash\n```\n\nUse the one-liner abover, or use the [`docker-compose.yml`](https://github.com/Lissy93/domain-locker/blob/main/docker-compose.yml)\n\n\u003cdetails\u003e\n\t\u003csummary\u003eDetails\u003c/summary\u003e\n\n \n- **Prerequisites**:\n  - Domain Locker is intended to be run in a container, so you'll need Docker [installed](https://docs.docker.com/engine/install/) on your host system.\n- **Containers**:\n  - We have a Docker image published to [`lissy93/domain-locker`](https://hub.docker.com/r/lissy93/domain-locker).\n  - You'll also need a Postgres database, such as the [`postgres:15-alpine`](https://hub.docker.com/_/postgres?tab=tags\u0026name=15-alpine) container.\n- **Environment**:\n  - When starting the container, bind `3000` in the container, to your host `PORT` (defaults to `3000`).\n  - Then specify the Postgres vars: `DL_PG_HOST`, `DL_PG_PORT`, `DL_PG_USER`, `DL_PG_PASSWORD` and `DL_PG_NAME`.\n- **Volumes**:\n  - Mount a volume to `/var/lib/postgresql/data` to persist your Postgres data\n- **Crons**\n  - `/api/domain-updater` - Execute this daily, to keep domain data up-to-date and trigger notifications\n  - `/api/uptime-monitor` - Execute this every N minutes, to monitor website uptime and performance\n- **Example**:\n  - Putting it all together, you can use our [`docker-compose.yml`](https://github.com/Lissy93/domain-locker/blob/main/docker-compose.yml) file.\n  - For more details, view the [Self-Hosting Docs](https://domain-locker.com/about/self-hosting)\n\n\n\u003cdetails\u003e\n\u003csummary\u003eDocker Diagram\u003c/summary\u003e\n\n```mermaid\nflowchart TB\n  subgraph Volume Mounts\n    direction TB\n    Vpostgresdata([📦 postgres_data]) x-. /var/lib/postgresql/data .-x postgres[(🐘 PostgreSQL DB)]\n    Vdbschemasql{{📄 ./db/schema.sql}} -. Mounted on Init .-\u003e postgres\n  end\n\n  subgraph Network\n    direction TB\n    domainlockernetwork[/🌐 domain_locker_network/]\n  end\n\n  postgres -.- domainlockernetwork\n\n  subgraph app[⚙️ App Container]\n    SSR[HTTP Server]\n    CLIENT[Client App]\n    API[API Endpoints]\n    SSR --\u003e CLIENT\n    SSR --\u003e API\n  end\n\n  app -.- domainlockernetwork\n```\n\n\u003c/details\u003e\n\n \n\u003c/details\u003e\n\n\n---\n\n## Developing\n\n#### Project Setup\n\n```bash\ngit clone git@github.com:Lissy93/domain-locker.git    # Get the code\ncd domain-locker                                      # Navigate into directory\nnpm install --legacy-peer-deps                        # Install dependencies\ncp .env.example .env                                  # Set environmental variables\nnpm run dev                                           # Start the dev server\n```\n\n- **Prerequisites**\n  - You'll need Git and Node installed on your system.\n- **Configuring**\n  - The example `.env.sample` file includes the public creds for our Supabase dev instance\n  - To use alternate db, see the [Database](#database) section below to configure with Postgres\n- **Deploying**\n  - You can build with code with `npm run build`, then run with `npm start`\n  - Or, with Docker building the container with `docker build -t domain-locker .`\n  - Don't use the dev Supabase instance in prod, as it's frequently wiped\n\n---\n\n## App Architecture\n\n#### Tech Stack\n\nDomain Locker is made up of an app, database and some API endpoints.\n- **The app** is built with Angular, using Analog+Nitro with PrimeNg components, and Tailwind for styling\n- **The server** is a series of Deno endpoints with Typescript functions\n- **The database** can be either Postgres or Supabase\n\nWhile the self-hosted instance is intended to be deployed stand-alone, the managed version however depends on a few additional third-party services, which you can see below, [the docs of which are here](https://domain-locker.com/about/developing/third-party-docs).\n\n\u003cdetails\u003e\n\u003csummary\u003eWhy\u003c/summary\u003e\nWhy Angular? As some sort of sick joke to future me, who then needs to maintain this.\n\u003c/details\u003e\n\n\n\u003cp align=\"center\"\u003e\n\u003cimg width=\"800\" src=\"/.github/screenshots/architecture.png\" /\u003e\n\u003cbr\u003e\n\u003cspan\u003eYou can view docs for the technologies and services used \u003ca href=\"https://domain-locker.com/about/developing/third-party-docs\"\u003ehere\u003c/a\u003e\u003c/span\u003e\n\u003c/p\u003e\n\n\n#### Architecture\n\nThe architecture is pretty simple.\nWe have an app (consisting of a frontend and API endpoints), where the user can read and write to the database (through adapters). Then a cron service will periodically call API endpoints to keep domain data up-to-date, track changes, monitor health, and trigger notifications on certain changes (according to user preference) or before an upcoming expiration.\n\n```mermaid\ngraph TD;\n    subgraph User Interactions\n        User[👤 User] --\u003e|Enter domain| WebApp[🌐 Frontend];\n        WebApp --\u003e|Send API request| API[⚙️ Nitro API];\n        API --\u003e|Auth Check| Auth[🔐 Auth Service];\n        API --\u003e|Store domain info| Database[🗄️ PostgreSQL / Supabase];\n    end\n\n    subgraph Automated Cron Jobs\n        CronService[⏳ Cron Service] --\u003e|Trigger Updates| EdgeFunctions[⚡ Edge Functions];\n        EdgeFunctions --\u003e|Fetch WHOIS, DNS, SSL| ExternalAPIs[🌎 Analysis Services];\n        EdgeFunctions --\u003e|Store Data| Database;\n        \n        CronService --\u003e|Monitor Uptime| WebsiteMonitor[📡 Uptime Monitor];\n        WebsiteMonitor --\u003e|Store Metrics| Database;\n\n        CronService --\u003e|Check Expirations| ExpiryChecker[📆 Expiration Check];\n        ExpiryChecker --\u003e|Update Status| Database;\n        \n        CronService --\u003e|Send Notifications| NotificationService[🔔 Notification System];\n        NotificationService --\u003e|Email| Resend[📧 Resend];\n        NotificationService --\u003e|SMS| Twilio[📱 Twilio];\n    end\n\n    Database --\u003e|Serve Data| WebApp;\n```\n\n#### Database\n\nA database is needed to store all your domains and associated info.\nDomain Locker supports both Supabase and standard Postgres for storing data.\nThe db used will depend on which env vars are set.\n\n- **Supabase**: Follow the Supabase [self-hosting docs](https://supabase.com/docs/guides/self-hosting), then use [dl-sb-iac](https://github.com/lissy93/dl-sb-iac) to import the schema and configure auth, edge functions, emails, etc.\n\t- Then set: `SUPABASE_URL` and `SUPABASE_ANON_KEY` environmental variables\n- **Postgres**: Deploy a Postgres instance, then use our [`setup-postgres.sh`](https://github.com/Lissy93/domain-locker/blob/main/db/setup-postgres.sh) script to init your DB with our[`schema.sql`](https://github.com/Lissy93/domain-locker/blob/main/db/schema.sql)\n\t- Then set: `DL_PG_HOST`, `DL_PG_PORT`, `DL_PG_USER`, `DL_PG_PASSWORD`, `DL_PG_NAME`\n\n```mermaid\nclassDiagram\n  class users {\n    uuid id\n    text email\n    timestamp created_at\n    timestamp updated_at\n  }\n\n  class domains {\n    uuid id\n    uuid user_id\n    text domain_name\n    date expiry_date\n    text notes\n    timestamp created_at\n    timestamp updated_at\n    uuid registrar_id\n    timestamp registration_date\n    timestamp updated_date\n  }\n\n  class registrars {\n    uuid id\n    text name\n    text url\n    uuid user_id\n  }\n\n  class tags {\n    uuid id\n    text name\n    text color\n    text description\n    text icon\n    uuid user_id\n  }\n\n  class domain_tags {\n    uuid domain_id\n    uuid tag_id\n  }\n\n  class notifications {\n    uuid id\n    uuid user_id\n    uuid domain_id\n    text change_type\n    text message\n    boolean sent\n    boolean read\n    timestamp created_at\n  }\n\n  class billing {\n    uuid id\n    uuid user_id\n    text current_plan\n    timestamp next_payment_due\n    text billing_method\n    timestamp created_at\n    timestamp updated_at\n    jsonb meta\n  }\n\n  class dns_records {\n    uuid id\n    uuid domain_id\n    text record_type\n    text record_value\n    timestamp created_at\n    timestamp updated_at\n  }\n\n  class domain_costings {\n    uuid id\n    uuid domain_id\n    numeric purchase_price\n    numeric current_value\n    numeric renewal_cost\n    boolean auto_renew\n    timestamp created_at\n    timestamp updated_at\n  }\n\n  class domain_hosts {\n    uuid domain_id\n    uuid host_id\n  }\n\n  class domain_links {\n    uuid id\n    uuid domain_id\n    text link_name\n    text link_url\n    timestamp created_at\n    timestamp updated_at\n    text link_description\n  }\n\n  class domain_statuses {\n    uuid id\n    uuid domain_id\n    text status_code\n    timestamp created_at\n  }\n\n  class domain_updates {\n    uuid id\n    uuid domain_id\n    uuid user_id\n    text change\n    text change_type\n    text old_value\n    text new_value\n    timestamp date\n  }\n\n  class uptime {\n    uuid id\n    uuid domain_id\n    timestamp checked_at\n    boolean is_up\n    integer response_code\n    numeric response_time_ms\n    numeric dns_lookup_time_ms\n    numeric ssl_handshake_time_ms\n    timestamp created_at\n  }\n\n  class ssl_certificates {\n    uuid id\n    uuid domain_id\n    text issuer\n    text issuer_country\n    text subject\n    date valid_from\n    date valid_to\n    text fingerprint\n    integer key_size\n    text signature_algorithm\n    timestamp created_at\n    timestamp updated_at\n  }\n\n  class whois_info {\n    uuid id\n    uuid domain_id\n    text country\n    text state\n    text name\n    text organization\n    text street\n    text city\n    text postal_code\n  }\n\n  class user_info {\n    uuid id\n    uuid user_id\n    jsonb notification_channels\n    timestamp created_at\n    timestamp updated_at\n    text current_plan\n  }\n\n  class hosts {\n    uuid id\n    inet ip\n    numeric lat\n    numeric lon\n    text isp\n    text org\n    text as_number\n    text city\n    text region\n    text country\n    uuid user_id\n  }\n\n  class ip_addresses {\n    uuid id\n    uuid domain_id\n    inet ip_address\n    boolean is_ipv6\n    timestamp created_at\n    timestamp updated_at\n  }\n\n  class notification_preferences {\n    uuid id\n    uuid domain_id\n    text notification_type\n    boolean is_enabled\n    timestamp created_at\n    timestamp updated_at\n  }\n\n  class sub_domains {\n    uuid id\n    uuid domain_id\n    text name\n    timestamp created_at\n    timestamp updated_at\n    jsonb sd_info\n  }\n\n  users --\u003e domains : user_id\n  registrars --\u003e domains : registrar_id\n  users --\u003e registrars : user_id\n  users --\u003e tags : user_id\n  domains --\u003e domain_tags : domain_id\n  tags --\u003e domain_tags : tag_id\n  users --\u003e notifications : user_id\n  domains --\u003e notifications : domain_id\n  users --\u003e billing : user_id\n  domains --\u003e dns_records : domain_id\n  domains --\u003e domain_costings : domain_id\n  domains --\u003e domain_hosts : domain_id\n  hosts --\u003e domain_hosts : host_id\n  domains --\u003e domain_links : domain_id\n  domains --\u003e domain_statuses : domain_id\n  domains --\u003e domain_updates : domain_id\n  users --\u003e domain_updates : user_id\n  domains --\u003e uptime : domain_id\n  domains --\u003e ssl_certificates : domain_id\n  domains --\u003e whois_info : domain_id\n  users --\u003e user_info : user_id\n  users --\u003e hosts : user_id\n  domains --\u003e ip_addresses : domain_id\n  domains --\u003e notification_preferences : domain_id\n  domains --\u003e sub_domains : domain_id\n```\n\n\u003cp align=\"center\"\u003e\u003csub\u003eYou can download the schema from \u003ca href=\"https://github.com/Lissy93/domain-locker/blob/main/db/schema.sql\"\u003ccode\u003edb/schema.sql\u003c/code\u003e\u003c/a\u003e\u003c/sub\u003e\u003c/p\u003e\n\n---\n\n### Contributing\n\nContributions, of any kind are always welcome, and very much appreciated! 💗\n\nIf you're new to Git, the general flow of contributing, is as follows:\n- Fork the repo, by [clicking here](https://github.com/lissy93/domain-locker/fork)\n- Clone your fork (with `git clone git@github.com:[your_username]/domain-locker.git`)\n- Follow the [Project Setup](#project-setup) above, to get the project running in development mode\n- Implement your awesome new feature or amazing bug fix...\n- Checkout a branch, with `git checkout -b feature-branch`, then `git add` your changes and `git commit` using conventional commits, before `git push`ing to your branch\n- Head back to GitHub, and you can then open up a PR against our `main` branch. Don't forget to include what you changed, why and link to any associated issues.\n- We'll then review, feedback, and merge, and once released your changes will go live to prod, as well as be available in the latest Docker image.\n\n\u003cdetails\u003e\n\t\u003csummary\u003eGit Branch Example\u003c/summary\u003e\n\n```mermaid\n%%{init: {\"theme\": \"default\"}}%%\ngitGraph\n    commit id: \"Initial commit\"\n    branch trunk\n    commit id: \"Feature A\"\n    commit id: \"Feature B\"\n    commit id: \"v1.0.0 (Tag)\"\n    branch demo\n    checkout main\n    commit id: \"Feature C\"\n    commit id: \"v1.1.0 (Tag)\"\n    checkout demo\n    merge main id: \"Merge main into demo\"\n    checkout main\n    commit id: \"Feature D\"\n    commit id: \"v1.2.0 (Tag)\"\n    checkout demo\n    merge main id: \"Merge main into demo (v1.2.0)\"\n    checkout main\n    branch feature-branch-1\n    commit id: \"Contributor Feature 1\"\n    checkout main\n    merge feature-branch-1 id: \"Merge contributor feature 1\"\n    commit id: \"v1.3.0 (Tag)\"\n    checkout demo\n    merge main id: \"Merge main into demo (v1.3.0)\"\n    checkout main\n    branch feature-branch-2\n    commit id: \"Contributor Feature 2\"\n    checkout main\n    merge feature-branch-2 id: \"Merge contributor feature 2\"\n    commit id: \"v1.4.0 (Tag)\"\n    checkout demo\n    merge main id: \"Merge main into demo (v1.4.0)\"\n```\n\n\u003c/details\u003e\n\n---\n\n## Attributions\n\n##### Contributors\n\n![contributors](https://readme-contribs.as93.net/contributors/lissy93/domain-locker)\n\n##### Sponsors\n\n![sponsors](https://readme-contribs.as93.net/sponsors/lissy93)\n\n---\n\n## License\n\n\n\u003e _**[Lissy93/Domain-Locker](https://github.com/Lissy93/domain-locker)** is licensed under [MIT](https://github.com/Lissy93/domain-locker/blob/HEAD/LICENSE) © [Alicia Sykes](https://aliciasykes.com) 2025._\u003cbr\u003e\n\u003e \u003csup align=\"right\"\u003eFor information, see \u003ca href=\"https://tldrlegal.com/license/mit-license\"\u003eTLDR Legal \u003e MIT\u003c/a\u003e\u003c/sup\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003eExpand License\u003c/summary\u003e\n\n```\nThe MIT License (MIT)\nCopyright (c) Alicia Sykes \u003calicia@omg.com\u003e \n\nPermission is hereby granted, free of charge, to any person obtaining a copy \nof this software and associated documentation files (the \"Software\"), to deal \nin the Software without restriction, including without limitation the rights \nto use, copy, modify, merge, publish, distribute, sub-license, and/or sell \ncopies of the Software, and to permit persons to whom the Software is furnished \nto do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included install \ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\nINCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANT ABILITY, FITNESS FOR A\nPARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\nHOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\nOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\nSOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n```\n\n\u003c/details\u003e\n\n\u003c!-- License + Copyright --\u003e\n\u003cp  align=\"center\"\u003e\n  \u003ci\u003e© \u003ca href=\"https://aliciasykes.com\"\u003eAlicia Sykes\u003c/a\u003e 2025\u003c/i\u003e\u003cbr\u003e\n  \u003ci\u003eLicensed under \u003ca href=\"https://gist.github.com/Lissy93/143d2ee01ccc5c052a17\"\u003eMIT\u003c/a\u003e\u003c/i\u003e\u003cbr\u003e\n  \u003ca href=\"https://github.com/lissy93\"\u003e\u003cimg src=\"https://i.ibb.co/4KtpYxb/octocat-clean-mini.png\" /\u003e\u003c/a\u003e\u003cbr\u003e\n  \u003csup\u003eThanks for visiting :)\u003c/sup\u003e\n\u003c/p\u003e\n\n\u003c!-- Dinosaurs are Awesome --\u003e\n\u003c!-- \n                        . - ~ ~ ~ - .\n      ..     _      .-~               ~-.\n     //|     \\ `..~                      `.\n    || |      }  }              /       \\  \\\n(\\   \\\\ \\~^..'                 |         }  \\\n \\`.-~  o      /       }       |        /    \\\n (__          |       /        |       /      `.\n  `- - ~ ~ -._|      /_ - ~ ~ ^|      /- _      `.\n              |     /          |     /     ~-.     ~- _\n              |_____|          |_____|         ~ - . _ _~_-_\n--\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FLissy93%2Fdomain-locker","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FLissy93%2Fdomain-locker","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FLissy93%2Fdomain-locker/lists"}