From d59996459639ba114d67dcd7b97a3035cbabfc37 Mon Sep 17 00:00:00 2001 From: Dan Lynch Date: Sat, 24 Oct 2026 14:26:11 +0000 Subject: [PATCH] chore: remove reserved-names module --- .github/workflows/ci.yml | 1 - MODULES.md | 1 - README.md | 1 - packages/reserved-names/.npmignore | 2 - packages/reserved-names/LICENSE | 22 -- packages/reserved-names/Makefile | 6 - packages/reserved-names/README.md | 82 ------- .../__tests__/reserved-names.test.ts | 222 ------------------ .../reserved_names/procedures/is_reserved.sql | 16 -- .../reserved_names/procedures/reserved_by.sql | 23 -- .../deploy/schemas/reserved_names/schema.sql | 9 - .../kinds/fixtures/1792800000000_fixture.sql | 14 -- .../reserved_names/tables/kinds/table.sql | 16 -- .../names/fixtures/1792800000002_fixture.sql | 72 ------ .../tables/names/indexes/names_reason_idx.sql | 10 - .../reserved_names/tables/names/table.sql | 23 -- .../fixtures/1792800000001_fixture.sql | 14 -- .../reserved_names/tables/reasons/table.sql | 16 -- packages/reserved-names/jest.config.js | 16 -- packages/reserved-names/package.json | 38 --- .../pgpm-reserved-names.control | 7 - packages/reserved-names/pgpm.plan | 14 -- .../reserved_names/procedures/is_reserved.sql | 7 - .../reserved_names/procedures/reserved_by.sql | 7 - .../revert/schemas/reserved_names/schema.sql | 7 - .../kinds/fixtures/1792800000000_fixture.sql | 7 - .../reserved_names/tables/kinds/table.sql | 7 - .../names/fixtures/1792800000002_fixture.sql | 7 - .../tables/names/indexes/names_reason_idx.sql | 7 - .../reserved_names/tables/names/table.sql | 7 - .../fixtures/1792800000001_fixture.sql | 7 - .../reserved_names/tables/reasons/table.sql | 7 - .../pgpm-reserved-names--0.47.5.bundle.tar.gz | Bin 5488 -> 0 bytes .../sql/pgpm-reserved-names--0.47.5.sql | 157 ------------- .../reserved_names/procedures/is_reserved.sql | 7 - .../reserved_names/procedures/reserved_by.sql | 7 - .../verify/schemas/reserved_names/schema.sql | 7 - .../kinds/fixtures/1792800000000_fixture.sql | 7 - .../reserved_names/tables/kinds/table.sql | 7 - .../names/fixtures/1792800000002_fixture.sql | 7 - .../tables/names/indexes/names_reason_idx.sql | 7 - .../reserved_names/tables/names/table.sql | 7 - .../fixtures/1792800000001_fixture.sql | 7 - .../reserved_names/tables/reasons/table.sql | 7 - pnpm-lock.yaml | 10 - 45 files changed, 932 deletions(-) delete mode 100644 packages/reserved-names/.npmignore delete mode 100644 packages/reserved-names/LICENSE delete mode 100644 packages/reserved-names/Makefile delete mode 100644 packages/reserved-names/README.md delete mode 100644 packages/reserved-names/__tests__/reserved-names.test.ts delete mode 100644 packages/reserved-names/deploy/schemas/reserved_names/procedures/is_reserved.sql delete mode 100644 packages/reserved-names/deploy/schemas/reserved_names/procedures/reserved_by.sql delete mode 100644 packages/reserved-names/deploy/schemas/reserved_names/schema.sql delete mode 100644 packages/reserved-names/deploy/schemas/reserved_names/tables/kinds/fixtures/1792800000000_fixture.sql delete mode 100644 packages/reserved-names/deploy/schemas/reserved_names/tables/kinds/table.sql delete mode 100644 packages/reserved-names/deploy/schemas/reserved_names/tables/names/fixtures/1792800000002_fixture.sql delete mode 100644 packages/reserved-names/deploy/schemas/reserved_names/tables/names/indexes/names_reason_idx.sql delete mode 100644 packages/reserved-names/deploy/schemas/reserved_names/tables/names/table.sql delete mode 100644 packages/reserved-names/deploy/schemas/reserved_names/tables/reasons/fixtures/1792800000001_fixture.sql delete mode 100644 packages/reserved-names/deploy/schemas/reserved_names/tables/reasons/table.sql delete mode 100644 packages/reserved-names/jest.config.js delete mode 100644 packages/reserved-names/package.json delete mode 100644 packages/reserved-names/pgpm-reserved-names.control delete mode 100644 packages/reserved-names/pgpm.plan delete mode 100644 packages/reserved-names/revert/schemas/reserved_names/procedures/is_reserved.sql delete mode 100644 packages/reserved-names/revert/schemas/reserved_names/procedures/reserved_by.sql delete mode 100644 packages/reserved-names/revert/schemas/reserved_names/schema.sql delete mode 100644 packages/reserved-names/revert/schemas/reserved_names/tables/kinds/fixtures/1792800000000_fixture.sql delete mode 100644 packages/reserved-names/revert/schemas/reserved_names/tables/kinds/table.sql delete mode 100644 packages/reserved-names/revert/schemas/reserved_names/tables/names/fixtures/1792800000002_fixture.sql delete mode 100644 packages/reserved-names/revert/schemas/reserved_names/tables/names/indexes/names_reason_idx.sql delete mode 100644 packages/reserved-names/revert/schemas/reserved_names/tables/names/table.sql delete mode 100644 packages/reserved-names/revert/schemas/reserved_names/tables/reasons/fixtures/1792800000001_fixture.sql delete mode 100644 packages/reserved-names/revert/schemas/reserved_names/tables/reasons/table.sql delete mode 100644 packages/reserved-names/sql/pgpm-reserved-names--0.47.5.bundle.tar.gz delete mode 100644 packages/reserved-names/sql/pgpm-reserved-names--0.47.5.sql delete mode 100644 packages/reserved-names/verify/schemas/reserved_names/procedures/is_reserved.sql delete mode 100644 packages/reserved-names/verify/schemas/reserved_names/procedures/reserved_by.sql delete mode 100644 packages/reserved-names/verify/schemas/reserved_names/schema.sql delete mode 100644 packages/reserved-names/verify/schemas/reserved_names/tables/kinds/fixtures/1792800000000_fixture.sql delete mode 100644 packages/reserved-names/verify/schemas/reserved_names/tables/kinds/table.sql delete mode 100644 packages/reserved-names/verify/schemas/reserved_names/tables/names/fixtures/1792800000002_fixture.sql delete mode 100644 packages/reserved-names/verify/schemas/reserved_names/tables/names/indexes/names_reason_idx.sql delete mode 100644 packages/reserved-names/verify/schemas/reserved_names/tables/names/table.sql delete mode 100644 packages/reserved-names/verify/schemas/reserved_names/tables/reasons/fixtures/1792800000001_fixture.sql delete mode 100644 packages/reserved-names/verify/schemas/reserved_names/tables/reasons/table.sql diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c2c236ff0..ab1fe5499 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -36,7 +36,6 @@ jobs: - partman - db-utils - infra-utils - - reserved-names env: PGHOST: localhost diff --git a/MODULES.md b/MODULES.md index 4ce9f2a1a..aae4464aa 100644 --- a/MODULES.md +++ b/MODULES.md @@ -60,7 +60,6 @@ - [ ] `packages/utils/inflection` - String inflection utilities - [ ] `packages/utils/base32` - Base32 encoding/decoding - [ ] `packages/utils/faker` - Fake data generation -- [ ] `packages/reserved-names` - Reserved names (subdomains, usernames, slugs) nobody may claim - [ ] `packages/db-utils` - General database utilities (deep jsonb merge/set, timestamps, column smart comments) - [ ] `packages/infra-utils` - Typed parameter interface for infrastructure resource bundles (declared params, bindings, k8s quantities, admission) diff --git a/README.md b/README.md index 3774b64f4..f433bdd34 100644 --- a/README.md +++ b/README.md @@ -140,7 +140,6 @@ Each module includes its own README with detailed documentation. See individual - [`@pgpm/inflection`](https://www.npmjs.com/package/@pgpm/inflection) - String inflection utilities - [`@pgpm/base32`](https://www.npmjs.com/package/@pgpm/base32) - Base32 encoding/decoding - [`@pgpm/faker`](https://www.npmjs.com/package/@pgpm/faker) - Fake data generation for testing -- [`@pgpm/reserved-names`](https://www.npmjs.com/package/@pgpm/reserved-names) - Reserved names (subdomains, usernames, slugs) nobody may claim ### Metrics & Analytics - [`@pgpm/measurements`](https://www.npmjs.com/package/@pgpm/measurements) - Performance tracking and analytics diff --git a/packages/reserved-names/.npmignore b/packages/reserved-names/.npmignore deleted file mode 100644 index cf8a45548..000000000 --- a/packages/reserved-names/.npmignore +++ /dev/null @@ -1,2 +0,0 @@ -__tests__ -jest.config.js diff --git a/packages/reserved-names/LICENSE b/packages/reserved-names/LICENSE deleted file mode 100644 index 7b18c9183..000000000 --- a/packages/reserved-names/LICENSE +++ /dev/null @@ -1,22 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2025 Dan Lynch -Copyright (c) 2025 Constructive - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/packages/reserved-names/Makefile b/packages/reserved-names/Makefile deleted file mode 100644 index d0e4bb229..000000000 --- a/packages/reserved-names/Makefile +++ /dev/null @@ -1,6 +0,0 @@ -EXTENSION = pgpm-reserved-names -DATA = sql/pgpm-reserved-names--0.47.5.sql - -PG_CONFIG = pg_config -PGXS := $(shell $(PG_CONFIG) --pgxs) -include $(PGXS) diff --git a/packages/reserved-names/README.md b/packages/reserved-names/README.md deleted file mode 100644 index 1672c0486..000000000 --- a/packages/reserved-names/README.md +++ /dev/null @@ -1,82 +0,0 @@ -# @pgpm/reserved-names - -

- -

- -

- - - - - -

- -Reserved names that nobody may claim — subdomains, usernames, slugs, or any other kind — kept as rows and checked live by one function. - -## Overview - -`@pgpm/reserved-names` keeps one shared list, as tables, and callers check it live at the moment someone claims a name. A new entry takes effect at once for every caller, with no regeneration or redeploy of the callers. - -| table | what it holds | -| --- | --- | -| `reserved_names.kinds` | categories of name: `subdomain`, `username`, `domain`, `slug` (add more with a migration) | -| `reserved_names.reasons` | why a name is reserved: `platform`, `brand`, `lookalike`, `abuse` | -| `reserved_names.names` | the entries: `kind`, `name` (lowercase), `match` (`exact` / `prefix` / `suffix`), `reason` | - -Every entry must point at a real kind and reason (foreign keys), so a typo cannot quietly create an empty category. The primary key is `(kind, name, match)`. - -The starter data, in fixtures, is the four kinds and four reasons plus a `subdomain` list: hostnames a visitor would read as the platform's own under a shared domain (`login`, `admin`, `www`, `mail`, `ns1`, …), and a `xn--` prefix entry that blocks punycode lookalikes (`аpple` with a Cyrillic `а`). The other kinds start empty. - -## Installation - -```bash -pgpm install @pgpm/reserved-names -pgpm deploy -``` - -## Usage - -```sql -SELECT reserved_names.is_reserved('subdomain', 'login'); -- true -SELECT reserved_names.is_reserved('subdomain', 'LOGIN'); -- true (case-insensitive) -SELECT reserved_names.is_reserved('subdomain', 'xn--pple-43d'); -- true (prefix entry) -SELECT reserved_names.is_reserved('subdomain', 'mystore'); -- false -SELECT reserved_names.is_reserved('username', 'login'); -- false (kinds are separate) - -SELECT name, match, reason FROM reserved_names.reserved_by('subdomain', 'xn--pple-43d'); --- xn-- | prefix | lookalike -``` - -- `is_reserved(kind, name) RETURNS boolean`: true when any entry matches. -- `reserved_by(kind, name) RETURNS SETOF reserved_names.names`: the matching entries, so an error can say why. - -Both are `STABLE` SQL, lowercase `kind` and `name` before comparing, and treat `NULL` as not reserved. Matching: - -- `exact`: the name itself. -- `prefix`: every name starting with it (`xn--`, `staff-`). -- `suffix`: every name ending with it. `.example.com` blocks `shop.example.com`, but not `example.com` itself (add an `exact` entry for that) and not `notexample.com`. - -### Adding names - -The list changes only through migrations. Add a pgpm fixture change that inserts rows: - -```sql -INSERT INTO reserved_names.names (kind, name, match, reason) VALUES - ('subdomain', 'www2', 'exact', 'platform'), - ('subdomain', 'staff-', 'prefix', 'platform'), - ('domain', '.example.com', 'suffix', 'brand'), - ('username', 'support', 'exact', 'platform'); -``` - -A new category or reason is a row in `kinds` or `reasons` first. - -## Access - -Everyone can read the three tables and call both functions, so a UI can say "that name is reserved" before submitting. The list is public, so there is no row-level security. No role is granted `INSERT`, `UPDATE` or `DELETE`: only the owner (migrations, or a `SECURITY DEFINER` function it owns) can change it. - -## Testing - -```bash -pnpm test -``` diff --git a/packages/reserved-names/__tests__/reserved-names.test.ts b/packages/reserved-names/__tests__/reserved-names.test.ts deleted file mode 100644 index 7f2f8a760..000000000 --- a/packages/reserved-names/__tests__/reserved-names.test.ts +++ /dev/null @@ -1,222 +0,0 @@ -import { getConnections, PgTestClient } from 'pgsql-test'; - -let pg: PgTestClient; -let db: PgTestClient; -let teardown: () => Promise; - -beforeAll(async () => { - ({ pg, db, teardown } = await getConnections()); -}); - -afterAll(async () => { - await teardown(); -}); - -beforeEach(async () => { - await pg.beforeEach(); - await db.beforeEach(); -}); - -afterEach(async () => { - await db.afterEach(); - await pg.afterEach(); -}); - -const isReserved = async (client: PgTestClient, kind: string, name: string) => { - const { is_reserved } = await client.one( - `SELECT reserved_names.is_reserved($1, $2) AS is_reserved`, - [kind, name] - ); - return is_reserved; -}; - -describe('reserved_names.is_reserved', () => { - it.each(['login', 'admin', 'www', 'status', 'LOGIN', 'Admin'])( - 'reserves the exact subdomain %s, in any case', - async (name) => { - expect(await isReserved(pg, 'subdomain', name)).toBe(true); - } - ); - - it.each(['mystore', 'login2', 'my-login', 'api-docs', 'administrators'])( - 'leaves %s free', - async (name) => { - expect(await isReserved(pg, 'subdomain', name)).toBe(false); - } - ); - - it('reserves every punycode label through the xn-- prefix entry', async () => { - expect(await isReserved(pg, 'subdomain', 'xn--pple-43d')).toBe(true); - expect(await isReserved(pg, 'subdomain', 'XN--80ak6aa92e')).toBe(true); - }); - - it('matches the kind in any case', async () => { - expect(await isReserved(pg, 'Subdomain', 'login')).toBe(true); - }); - - it('keeps kinds apart', async () => { - expect(await isReserved(pg, 'username', 'login')).toBe(false); - - await pg.query( - `INSERT INTO reserved_names.names (kind, name, reason) VALUES ('username', 'support', 'platform')` - ); - expect(await isReserved(pg, 'username', 'Support')).toBe(true); - expect(await isReserved(pg, 'subdomain', 'support')).toBe(true); - expect(await isReserved(pg, 'slug', 'support')).toBe(false); - }); - - it('reserves every name ending in a suffix entry', async () => { - await pg.query(` - INSERT INTO reserved_names.names (kind, name, match, reason) VALUES - ('domain', 'constructive.io', 'exact', 'brand'), - ('domain', '.constructive.io', 'suffix', 'brand') - `); - expect(await isReserved(pg, 'domain', 'constructive.io')).toBe(true); - expect(await isReserved(pg, 'domain', 'shop.Constructive.io')).toBe(true); - expect(await isReserved(pg, 'domain', 'notconstructive.io')).toBe(false); - expect(await isReserved(pg, 'domain', 'constructive.io.evil.com')).toBe(false); - }); - - it('picks up a newly added name and prefix at once', async () => { - expect(await isReserved(pg, 'subdomain', 'www2')).toBe(false); - expect(await isReserved(pg, 'subdomain', 'staff-east')).toBe(false); - - await pg.query(` - INSERT INTO reserved_names.names (kind, name, match, reason) VALUES - ('subdomain', 'www2', 'exact', 'platform'), - ('subdomain', 'staff-', 'prefix', 'platform') - `); - - expect(await isReserved(pg, 'subdomain', 'www2')).toBe(true); - expect(await isReserved(pg, 'subdomain', 'staff-east')).toBe(true); - expect(await isReserved(pg, 'subdomain', 'staff')).toBe(false); - }); - - it('treats a NULL name or kind as not reserved', async () => { - expect(await isReserved(pg, 'subdomain', null as unknown as string)).toBe(false); - expect(await isReserved(pg, null as unknown as string, 'login')).toBe(false); - }); -}); - -describe('reserved_names.reserved_by', () => { - it('says which entries reserve a name and why', async () => { - const rows = await pg.any( - `SELECT name, match, reason FROM reserved_names.reserved_by('subdomain', 'xn--pple-43d')` - ); - expect(rows).toEqual([{ name: 'xn--', match: 'prefix', reason: 'lookalike' }]); - }); - - it('returns nothing for a free name', async () => { - const rows = await pg.any(`SELECT * FROM reserved_names.reserved_by('subdomain', 'mystore')`); - expect(rows).toEqual([]); - }); -}); - -describe('the starter data', () => { - it('has the four kinds and four reasons', async () => { - const kinds = await pg.any(`SELECT kind FROM reserved_names.kinds ORDER BY kind`); - expect(kinds.map((r) => r.kind)).toEqual(['domain', 'slug', 'subdomain', 'username']); - const reasons = await pg.any(`SELECT reason FROM reserved_names.reasons ORDER BY reason`); - expect(reasons.map((r) => r.reason)).toEqual(['abuse', 'brand', 'lookalike', 'platform']); - }); - - it('reserves no api- prefix', async () => { - expect(await isReserved(pg, 'subdomain', 'api-docs')).toBe(false); - expect(await isReserved(pg, 'subdomain', 'api')).toBe(true); - }); -}); - -describe('reserved_names.names', () => { - it('rejects names that are not lowercase', async () => { - await expect( - pg.query(`INSERT INTO reserved_names.names (kind, name, reason) VALUES ('subdomain', 'Shop', 'platform')`) - ).rejects.toThrow(/names_name_check/); - }); - - it('rejects an empty name', async () => { - await expect( - pg.query(`INSERT INTO reserved_names.names (kind, name, reason) VALUES ('subdomain', '', 'platform')`) - ).rejects.toThrow(/names_name_check/); - }); - - it('rejects an unknown kind', async () => { - await expect( - pg.query(`INSERT INTO reserved_names.names (kind, name, reason) VALUES ('usrname', 'shop', 'platform')`) - ).rejects.toThrow(/names_kind_fkey/); - }); - - it('rejects an unknown reason', async () => { - await expect( - pg.query(`INSERT INTO reserved_names.names (kind, name, reason) VALUES ('subdomain', 'shop', 'because')`) - ).rejects.toThrow(/names_reason_fkey/); - }); - - it('requires a reason', async () => { - await expect( - pg.query(`INSERT INTO reserved_names.names (kind, name) VALUES ('subdomain', 'shop')`) - ).rejects.toThrow(/null value in column "reason"/); - }); - - it('rejects an unknown match type', async () => { - await expect( - pg.query(`INSERT INTO reserved_names.names (kind, name, match, reason) VALUES ('subdomain', 'shop', 'regex', 'platform')`) - ).rejects.toThrow(/names_match_check/); - }); - - it('rejects a duplicate entry', async () => { - await expect( - pg.query(`INSERT INTO reserved_names.names (kind, name, reason) VALUES ('subdomain', 'login', 'platform')`) - ).rejects.toThrow(/names_pkey/); - }); - - it('allows the same name as exact and as a prefix', async () => { - await pg.query( - `INSERT INTO reserved_names.names (kind, name, match, reason) VALUES ('subdomain', 'login', 'prefix', 'platform')` - ); - expect(await isReserved(pg, 'subdomain', 'login-now')).toBe(true); - }); -}); - -describe('reserved_names.kinds', () => { - it('rejects a malformed kind', async () => { - await expect( - pg.query(`INSERT INTO reserved_names.kinds (kind, description) VALUES ('Sub Domain', 'x')`) - ).rejects.toThrow(/kinds_kind_check/); - }); - - it('takes a new kind for later use', async () => { - await pg.query(`INSERT INTO reserved_names.kinds (kind, description) VALUES ('team_slug', 'A team handle')`); - await pg.query( - `INSERT INTO reserved_names.names (kind, name, reason) VALUES ('team_slug', 'staff', 'platform')` - ); - expect(await isReserved(pg, 'team_slug', 'staff')).toBe(true); - }); -}); - -describe.each(['anonymous', 'authenticated'])('as %s', (role) => { - beforeEach(() => { - db.setContext({ role }); - }); - - it('can check a name and read the lists', async () => { - expect(await isReserved(db, 'subdomain', 'login')).toBe(true); - for (const table of ['names', 'kinds', 'reasons']) { - const { count } = await db.one(`SELECT count(*)::int AS count FROM reserved_names.${table}`); - expect(count).toBeGreaterThan(0); - } - const rows = await db.any(`SELECT reason FROM reserved_names.reserved_by('subdomain', 'login')`); - expect(rows).toEqual([{ reason: 'platform' }]); - }); - - it.each([ - ['names', `INSERT INTO reserved_names.names (kind, name, reason) VALUES ('subdomain', 'mine', 'platform')`], - ['names', `UPDATE reserved_names.names SET reason = 'brand' WHERE name = 'login'`], - ['names', `DELETE FROM reserved_names.names WHERE name = 'login'`], - ['kinds', `INSERT INTO reserved_names.kinds (kind, description) VALUES ('mine', 'x')`], - ['kinds', `DELETE FROM reserved_names.kinds WHERE kind = 'slug'`], - ['reasons', `INSERT INTO reserved_names.reasons (reason, description) VALUES ('mine', 'x')`], - ['reasons', `DELETE FROM reserved_names.reasons WHERE reason = 'abuse'`] - ])('cannot change %s: %s', async (table, sql) => { - await expect(db.query(sql)).rejects.toThrow(new RegExp(`permission denied for table ${table}`)); - }); -}); diff --git a/packages/reserved-names/deploy/schemas/reserved_names/procedures/is_reserved.sql b/packages/reserved-names/deploy/schemas/reserved_names/procedures/is_reserved.sql deleted file mode 100644 index e06cfe41c..000000000 --- a/packages/reserved-names/deploy/schemas/reserved_names/procedures/is_reserved.sql +++ /dev/null @@ -1,16 +0,0 @@ --- Deploy schemas/reserved_names/procedures/is_reserved to pg - --- requires: schemas/reserved_names/schema --- requires: schemas/reserved_names/procedures/reserved_by - -BEGIN; - -CREATE FUNCTION reserved_names.is_reserved(kind text, name text) RETURNS boolean AS $$ - SELECT EXISTS (SELECT 1 FROM reserved_names.reserved_by(is_reserved.kind, is_reserved.name)); -$$ LANGUAGE sql STABLE; - -COMMENT ON FUNCTION reserved_names.is_reserved(text, text) IS 'True when name (any case) is reserved for kind'; - -GRANT EXECUTE ON FUNCTION reserved_names.is_reserved(text, text) TO public; - -COMMIT; diff --git a/packages/reserved-names/deploy/schemas/reserved_names/procedures/reserved_by.sql b/packages/reserved-names/deploy/schemas/reserved_names/procedures/reserved_by.sql deleted file mode 100644 index a8b0b87bf..000000000 --- a/packages/reserved-names/deploy/schemas/reserved_names/procedures/reserved_by.sql +++ /dev/null @@ -1,23 +0,0 @@ --- Deploy schemas/reserved_names/procedures/reserved_by to pg - --- requires: schemas/reserved_names/schema --- requires: schemas/reserved_names/tables/names/table - -BEGIN; - -CREATE FUNCTION reserved_names.reserved_by(kind text, name text) RETURNS SETOF reserved_names.names AS $$ - SELECT n.* - FROM reserved_names.names n - WHERE n.kind = pg_catalog.lower(reserved_by.kind) - AND CASE n.match - WHEN 'exact' THEN n.name = pg_catalog.lower(reserved_by.name) - WHEN 'prefix' THEN pg_catalog.starts_with(pg_catalog.lower(reserved_by.name), n.name) - WHEN 'suffix' THEN pg_catalog.right(pg_catalog.lower(reserved_by.name), pg_catalog.length(n.name)) = n.name - END; -$$ LANGUAGE sql STABLE; - -COMMENT ON FUNCTION reserved_names.reserved_by(text, text) IS 'The entries (with their reason) that reserve name for kind; empty when it is free'; - -GRANT EXECUTE ON FUNCTION reserved_names.reserved_by(text, text) TO public; - -COMMIT; diff --git a/packages/reserved-names/deploy/schemas/reserved_names/schema.sql b/packages/reserved-names/deploy/schemas/reserved_names/schema.sql deleted file mode 100644 index 18e91bf50..000000000 --- a/packages/reserved-names/deploy/schemas/reserved_names/schema.sql +++ /dev/null @@ -1,9 +0,0 @@ --- Deploy schemas/reserved_names/schema to pg - -BEGIN; - -CREATE SCHEMA reserved_names; - -GRANT USAGE ON SCHEMA reserved_names TO public; - -COMMIT; diff --git a/packages/reserved-names/deploy/schemas/reserved_names/tables/kinds/fixtures/1792800000000_fixture.sql b/packages/reserved-names/deploy/schemas/reserved_names/tables/kinds/fixtures/1792800000000_fixture.sql deleted file mode 100644 index 23a82ae2d..000000000 --- a/packages/reserved-names/deploy/schemas/reserved_names/tables/kinds/fixtures/1792800000000_fixture.sql +++ /dev/null @@ -1,14 +0,0 @@ --- Deploy schemas/reserved_names/tables/kinds/fixtures/1792800000000_fixture to pg - --- requires: schemas/reserved_names/schema --- requires: schemas/reserved_names/tables/kinds/table - -BEGIN; - -INSERT INTO reserved_names.kinds (kind, description) VALUES - ('subdomain', 'A label under a shared domain, like login in login.example.com'), - ('username', 'A person''s handle'), - ('domain', 'A whole domain name, like example.com'), - ('slug', 'A name in a URL path, like an organization or app slug'); - -COMMIT; diff --git a/packages/reserved-names/deploy/schemas/reserved_names/tables/kinds/table.sql b/packages/reserved-names/deploy/schemas/reserved_names/tables/kinds/table.sql deleted file mode 100644 index f1bc498be..000000000 --- a/packages/reserved-names/deploy/schemas/reserved_names/tables/kinds/table.sql +++ /dev/null @@ -1,16 +0,0 @@ --- Deploy schemas/reserved_names/tables/kinds/table to pg - --- requires: schemas/reserved_names/schema - -BEGIN; - -CREATE TABLE reserved_names.kinds ( - kind text PRIMARY KEY CHECK (kind ~ '^[a-z][a-z0-9_]*$'), - description text NOT NULL -); - -COMMENT ON TABLE reserved_names.kinds IS 'Categories of names that can be reserved: subdomain, username, domain, slug, ...'; - -GRANT SELECT ON TABLE reserved_names.kinds TO public; - -COMMIT; diff --git a/packages/reserved-names/deploy/schemas/reserved_names/tables/names/fixtures/1792800000002_fixture.sql b/packages/reserved-names/deploy/schemas/reserved_names/tables/names/fixtures/1792800000002_fixture.sql deleted file mode 100644 index a6ca21c27..000000000 --- a/packages/reserved-names/deploy/schemas/reserved_names/tables/names/fixtures/1792800000002_fixture.sql +++ /dev/null @@ -1,72 +0,0 @@ --- Deploy schemas/reserved_names/tables/names/fixtures/1792800000002_fixture to pg - --- requires: schemas/reserved_names/schema --- requires: schemas/reserved_names/tables/names/table --- requires: schemas/reserved_names/tables/kinds/fixtures/1792800000000_fixture --- requires: schemas/reserved_names/tables/reasons/fixtures/1792800000001_fixture - -BEGIN; - -INSERT INTO reserved_names.names (kind, name, match, reason) VALUES - ('subdomain', 'www', 'exact', 'platform'), - ('subdomain', 'api', 'exact', 'platform'), - ('subdomain', 'auth', 'exact', 'platform'), - ('subdomain', 'login', 'exact', 'platform'), - ('subdomain', 'logout', 'exact', 'platform'), - ('subdomain', 'signin', 'exact', 'platform'), - ('subdomain', 'signup', 'exact', 'platform'), - ('subdomain', 'register', 'exact', 'platform'), - ('subdomain', 'admin', 'exact', 'platform'), - ('subdomain', 'administrator', 'exact', 'platform'), - ('subdomain', 'root', 'exact', 'platform'), - ('subdomain', 'app', 'exact', 'platform'), - ('subdomain', 'apps', 'exact', 'platform'), - ('subdomain', 'dashboard', 'exact', 'platform'), - ('subdomain', 'console', 'exact', 'platform'), - ('subdomain', 'account', 'exact', 'platform'), - ('subdomain', 'accounts', 'exact', 'platform'), - ('subdomain', 'billing', 'exact', 'platform'), - ('subdomain', 'pay', 'exact', 'platform'), - ('subdomain', 'payments', 'exact', 'platform'), - ('subdomain', 'checkout', 'exact', 'platform'), - ('subdomain', 'support', 'exact', 'platform'), - ('subdomain', 'help', 'exact', 'platform'), - ('subdomain', 'status', 'exact', 'platform'), - ('subdomain', 'docs', 'exact', 'platform'), - ('subdomain', 'mail', 'exact', 'platform'), - ('subdomain', 'email', 'exact', 'platform'), - ('subdomain', 'smtp', 'exact', 'platform'), - ('subdomain', 'imap', 'exact', 'platform'), - ('subdomain', 'ftp', 'exact', 'platform'), - ('subdomain', 'ns', 'exact', 'platform'), - ('subdomain', 'ns1', 'exact', 'platform'), - ('subdomain', 'ns2', 'exact', 'platform'), - ('subdomain', 'mx', 'exact', 'platform'), - ('subdomain', 'cdn', 'exact', 'platform'), - ('subdomain', 'static', 'exact', 'platform'), - ('subdomain', 'assets', 'exact', 'platform'), - ('subdomain', 'files', 'exact', 'platform'), - ('subdomain', 'storage', 'exact', 'platform'), - ('subdomain', 'media', 'exact', 'platform'), - ('subdomain', 'ws', 'exact', 'platform'), - ('subdomain', 'wss', 'exact', 'platform'), - ('subdomain', 'graphql', 'exact', 'platform'), - ('subdomain', 'modules', 'exact', 'platform'), - ('subdomain', 'agent', 'exact', 'platform'), - ('subdomain', 'compute', 'exact', 'platform'), - ('subdomain', 'machines', 'exact', 'platform'), - ('subdomain', 'cluster', 'exact', 'platform'), - ('subdomain', 'migrate', 'exact', 'platform'), - ('subdomain', 'internal', 'exact', 'platform'), - ('subdomain', 'system', 'exact', 'platform'), - ('subdomain', 'platform', 'exact', 'platform'), - ('subdomain', 'security', 'exact', 'platform'), - ('subdomain', 'sso', 'exact', 'platform'), - ('subdomain', 'oauth', 'exact', 'platform'), - ('subdomain', 'id', 'exact', 'platform'), - ('subdomain', 'identity', 'exact', 'platform'), - ('subdomain', 'verify', 'exact', 'platform'), - ('subdomain', 'secure', 'exact', 'platform'), - ('subdomain', 'xn--', 'prefix', 'lookalike'); - -COMMIT; diff --git a/packages/reserved-names/deploy/schemas/reserved_names/tables/names/indexes/names_reason_idx.sql b/packages/reserved-names/deploy/schemas/reserved_names/tables/names/indexes/names_reason_idx.sql deleted file mode 100644 index 21df67953..000000000 --- a/packages/reserved-names/deploy/schemas/reserved_names/tables/names/indexes/names_reason_idx.sql +++ /dev/null @@ -1,10 +0,0 @@ --- Deploy schemas/reserved_names/tables/names/indexes/names_reason_idx to pg - --- requires: schemas/reserved_names/schema --- requires: schemas/reserved_names/tables/names/table - -BEGIN; - -CREATE INDEX names_reason_idx ON reserved_names.names (reason); - -COMMIT; diff --git a/packages/reserved-names/deploy/schemas/reserved_names/tables/names/table.sql b/packages/reserved-names/deploy/schemas/reserved_names/tables/names/table.sql deleted file mode 100644 index 36ea07203..000000000 --- a/packages/reserved-names/deploy/schemas/reserved_names/tables/names/table.sql +++ /dev/null @@ -1,23 +0,0 @@ --- Deploy schemas/reserved_names/tables/names/table to pg - --- requires: schemas/reserved_names/schema --- requires: schemas/reserved_names/tables/kinds/table --- requires: schemas/reserved_names/tables/reasons/table - -BEGIN; - -CREATE TABLE reserved_names.names ( - kind text NOT NULL REFERENCES reserved_names.kinds (kind), - name text NOT NULL CHECK (name <> '' AND name = lower(name)), - match text NOT NULL DEFAULT 'exact' CHECK (match IN ('exact', 'prefix', 'suffix')), - reason text NOT NULL REFERENCES reserved_names.reasons (reason), - PRIMARY KEY (kind, name, match) -); - -COMMENT ON TABLE reserved_names.names IS 'Names nobody may claim, by kind. Changed only by migrations.'; -COMMENT ON COLUMN reserved_names.names.name IS 'The reserved name, lowercase'; -COMMENT ON COLUMN reserved_names.names.match IS 'exact: the name itself; prefix: every name starting with it; suffix: every name ending with it'; - -GRANT SELECT ON TABLE reserved_names.names TO public; - -COMMIT; diff --git a/packages/reserved-names/deploy/schemas/reserved_names/tables/reasons/fixtures/1792800000001_fixture.sql b/packages/reserved-names/deploy/schemas/reserved_names/tables/reasons/fixtures/1792800000001_fixture.sql deleted file mode 100644 index 31b1d9ef0..000000000 --- a/packages/reserved-names/deploy/schemas/reserved_names/tables/reasons/fixtures/1792800000001_fixture.sql +++ /dev/null @@ -1,14 +0,0 @@ --- Deploy schemas/reserved_names/tables/reasons/fixtures/1792800000001_fixture to pg - --- requires: schemas/reserved_names/schema --- requires: schemas/reserved_names/tables/reasons/table - -BEGIN; - -INSERT INTO reserved_names.reasons (reason, description) VALUES - ('platform', 'Reads as the platform''s own (login, admin, status, ...)'), - ('brand', 'Our brand or product names'), - ('lookalike', 'Can be made to look like another name, e.g. punycode'), - ('abuse', 'Offensive or used for abuse'); - -COMMIT; diff --git a/packages/reserved-names/deploy/schemas/reserved_names/tables/reasons/table.sql b/packages/reserved-names/deploy/schemas/reserved_names/tables/reasons/table.sql deleted file mode 100644 index 5f0b48f2f..000000000 --- a/packages/reserved-names/deploy/schemas/reserved_names/tables/reasons/table.sql +++ /dev/null @@ -1,16 +0,0 @@ --- Deploy schemas/reserved_names/tables/reasons/table to pg - --- requires: schemas/reserved_names/schema - -BEGIN; - -CREATE TABLE reserved_names.reasons ( - reason text PRIMARY KEY CHECK (reason ~ '^[a-z][a-z0-9_]*$'), - description text NOT NULL -); - -COMMENT ON TABLE reserved_names.reasons IS 'Why a name is reserved: platform, brand, lookalike, abuse, ...'; - -GRANT SELECT ON TABLE reserved_names.reasons TO public; - -COMMIT; diff --git a/packages/reserved-names/jest.config.js b/packages/reserved-names/jest.config.js deleted file mode 100644 index 4108cf46f..000000000 --- a/packages/reserved-names/jest.config.js +++ /dev/null @@ -1,16 +0,0 @@ -/** @type {import('ts-jest').JestConfigWithTsJest} */ -module.exports = { - forceExit: true, - preset: 'ts-jest', - testEnvironment: 'node', - - // Match both __tests__ and colocated test files - testMatch: ['**/?(*.)+(test|spec).{ts,tsx,js,jsx}'], - - // Ignore build artifacts and type declarations - testPathIgnorePatterns: ['/dist/', '\\.d\\.ts$'], - modulePathIgnorePatterns: ['/dist/'], - watchPathIgnorePatterns: ['/dist/'], - - moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'], -}; diff --git a/packages/reserved-names/package.json b/packages/reserved-names/package.json deleted file mode 100644 index 76517cfc6..000000000 --- a/packages/reserved-names/package.json +++ /dev/null @@ -1,38 +0,0 @@ -{ - "name": "@pgpm/reserved-names", - "version": "0.47.5", - "description": "Reserved names (subdomains, usernames, domains, slugs, ...) that nobody may claim, as tables checked live by reserved_names.is_reserved(kind, name)", - "author": "Dan Lynch ", - "contributors": [ - "Constructive " - ], - "keywords": [ - "postgresql", - "pgpm", - "reserved", - "names", - "subdomains" - ], - "publishConfig": { - "access": "public" - }, - "scripts": { - "bundle": "pgpm package", - "test": "jest", - "test:watch": "jest --watch" - }, - "dependencies": { - "@pgpm/verify": "workspace:*" - }, - "devDependencies": { - "pgpm": "^5" - }, - "repository": { - "type": "git", - "url": "https://github.com/constructive-io/pgpm-modules" - }, - "homepage": "https://github.com/constructive-io/pgpm-modules", - "bugs": { - "url": "https://github.com/constructive-io/pgpm-modules/issues" - } -} diff --git a/packages/reserved-names/pgpm-reserved-names.control b/packages/reserved-names/pgpm-reserved-names.control deleted file mode 100644 index c19d9863f..000000000 --- a/packages/reserved-names/pgpm-reserved-names.control +++ /dev/null @@ -1,7 +0,0 @@ -# pgpm-reserved-names extension -comment = 'pgpm-reserved-names extension' -default_version = '0.47.5' -module_pathname = '$libdir/pgpm-reserved-names' -requires = 'plpgsql,pgpm-verify' -relocatable = false -superuser = false diff --git a/packages/reserved-names/pgpm.plan b/packages/reserved-names/pgpm.plan deleted file mode 100644 index 1ad28cca4..000000000 --- a/packages/reserved-names/pgpm.plan +++ /dev/null @@ -1,14 +0,0 @@ -%syntax-version=1.0.0 -%project=pgpm-reserved-names -%uri=pgpm-reserved-names - -schemas/reserved_names/schema [pgpm-verify:procedures/assert_function] 2026-10-22T19:40:00Z devin # add schemas/reserved_names/schema -schemas/reserved_names/tables/kinds/table [schemas/reserved_names/schema] 2026-10-22T19:40:00Z devin # add schemas/reserved_names/tables/kinds/table -schemas/reserved_names/tables/reasons/table [schemas/reserved_names/schema] 2026-10-22T19:40:00Z devin # add schemas/reserved_names/tables/reasons/table -schemas/reserved_names/tables/names/table [schemas/reserved_names/schema schemas/reserved_names/tables/kinds/table schemas/reserved_names/tables/reasons/table] 2026-10-22T19:40:00Z devin # add schemas/reserved_names/tables/names/table -schemas/reserved_names/tables/names/indexes/names_reason_idx [schemas/reserved_names/schema schemas/reserved_names/tables/names/table] 2026-10-22T19:40:00Z devin # add schemas/reserved_names/tables/names/indexes/names_reason_idx -schemas/reserved_names/procedures/reserved_by [schemas/reserved_names/schema schemas/reserved_names/tables/names/table] 2026-10-22T19:40:00Z devin # add schemas/reserved_names/procedures/reserved_by -schemas/reserved_names/procedures/is_reserved [schemas/reserved_names/schema schemas/reserved_names/procedures/reserved_by] 2026-10-22T19:40:00Z devin # add schemas/reserved_names/procedures/is_reserved -schemas/reserved_names/tables/kinds/fixtures/1792800000000_fixture [schemas/reserved_names/schema schemas/reserved_names/tables/kinds/table] 2026-10-22T19:40:00Z devin # add schemas/reserved_names/tables/kinds/fixtures/1792800000000_fixture -schemas/reserved_names/tables/reasons/fixtures/1792800000001_fixture [schemas/reserved_names/schema schemas/reserved_names/tables/reasons/table] 2026-10-22T19:40:00Z devin # add schemas/reserved_names/tables/reasons/fixtures/1792800000001_fixture -schemas/reserved_names/tables/names/fixtures/1792800000002_fixture [schemas/reserved_names/schema schemas/reserved_names/tables/names/table schemas/reserved_names/tables/kinds/fixtures/1792800000000_fixture schemas/reserved_names/tables/reasons/fixtures/1792800000001_fixture] 2026-10-22T19:40:00Z devin # add schemas/reserved_names/tables/names/fixtures/1792800000002_fixture diff --git a/packages/reserved-names/revert/schemas/reserved_names/procedures/is_reserved.sql b/packages/reserved-names/revert/schemas/reserved_names/procedures/is_reserved.sql deleted file mode 100644 index 9f8f03787..000000000 --- a/packages/reserved-names/revert/schemas/reserved_names/procedures/is_reserved.sql +++ /dev/null @@ -1,7 +0,0 @@ --- Revert schemas/reserved_names/procedures/is_reserved from pg - -BEGIN; - -DROP FUNCTION reserved_names.is_reserved(text, text); - -COMMIT; diff --git a/packages/reserved-names/revert/schemas/reserved_names/procedures/reserved_by.sql b/packages/reserved-names/revert/schemas/reserved_names/procedures/reserved_by.sql deleted file mode 100644 index 32c580d59..000000000 --- a/packages/reserved-names/revert/schemas/reserved_names/procedures/reserved_by.sql +++ /dev/null @@ -1,7 +0,0 @@ --- Revert schemas/reserved_names/procedures/reserved_by from pg - -BEGIN; - -DROP FUNCTION reserved_names.reserved_by(text, text); - -COMMIT; diff --git a/packages/reserved-names/revert/schemas/reserved_names/schema.sql b/packages/reserved-names/revert/schemas/reserved_names/schema.sql deleted file mode 100644 index 583c93dcf..000000000 --- a/packages/reserved-names/revert/schemas/reserved_names/schema.sql +++ /dev/null @@ -1,7 +0,0 @@ --- Revert schemas/reserved_names/schema from pg - -BEGIN; - -DROP SCHEMA reserved_names; - -COMMIT; diff --git a/packages/reserved-names/revert/schemas/reserved_names/tables/kinds/fixtures/1792800000000_fixture.sql b/packages/reserved-names/revert/schemas/reserved_names/tables/kinds/fixtures/1792800000000_fixture.sql deleted file mode 100644 index f4e51b695..000000000 --- a/packages/reserved-names/revert/schemas/reserved_names/tables/kinds/fixtures/1792800000000_fixture.sql +++ /dev/null @@ -1,7 +0,0 @@ --- Revert schemas/reserved_names/tables/kinds/fixtures/1792800000000_fixture from pg - -BEGIN; - -DELETE FROM reserved_names.kinds WHERE kind IN ('subdomain', 'username', 'domain', 'slug'); - -COMMIT; diff --git a/packages/reserved-names/revert/schemas/reserved_names/tables/kinds/table.sql b/packages/reserved-names/revert/schemas/reserved_names/tables/kinds/table.sql deleted file mode 100644 index e79db39d3..000000000 --- a/packages/reserved-names/revert/schemas/reserved_names/tables/kinds/table.sql +++ /dev/null @@ -1,7 +0,0 @@ --- Revert schemas/reserved_names/tables/kinds/table from pg - -BEGIN; - -DROP TABLE reserved_names.kinds; - -COMMIT; diff --git a/packages/reserved-names/revert/schemas/reserved_names/tables/names/fixtures/1792800000002_fixture.sql b/packages/reserved-names/revert/schemas/reserved_names/tables/names/fixtures/1792800000002_fixture.sql deleted file mode 100644 index 9f766f966..000000000 --- a/packages/reserved-names/revert/schemas/reserved_names/tables/names/fixtures/1792800000002_fixture.sql +++ /dev/null @@ -1,7 +0,0 @@ --- Revert schemas/reserved_names/tables/names/fixtures/1792800000002_fixture from pg - -BEGIN; - -DELETE FROM reserved_names.names WHERE kind = 'subdomain'; - -COMMIT; diff --git a/packages/reserved-names/revert/schemas/reserved_names/tables/names/indexes/names_reason_idx.sql b/packages/reserved-names/revert/schemas/reserved_names/tables/names/indexes/names_reason_idx.sql deleted file mode 100644 index 26b44cbd1..000000000 --- a/packages/reserved-names/revert/schemas/reserved_names/tables/names/indexes/names_reason_idx.sql +++ /dev/null @@ -1,7 +0,0 @@ --- Revert schemas/reserved_names/tables/names/indexes/names_reason_idx from pg - -BEGIN; - -DROP INDEX reserved_names.names_reason_idx; - -COMMIT; diff --git a/packages/reserved-names/revert/schemas/reserved_names/tables/names/table.sql b/packages/reserved-names/revert/schemas/reserved_names/tables/names/table.sql deleted file mode 100644 index 7e60595e6..000000000 --- a/packages/reserved-names/revert/schemas/reserved_names/tables/names/table.sql +++ /dev/null @@ -1,7 +0,0 @@ --- Revert schemas/reserved_names/tables/names/table from pg - -BEGIN; - -DROP TABLE reserved_names.names; - -COMMIT; diff --git a/packages/reserved-names/revert/schemas/reserved_names/tables/reasons/fixtures/1792800000001_fixture.sql b/packages/reserved-names/revert/schemas/reserved_names/tables/reasons/fixtures/1792800000001_fixture.sql deleted file mode 100644 index 71cfd0c3d..000000000 --- a/packages/reserved-names/revert/schemas/reserved_names/tables/reasons/fixtures/1792800000001_fixture.sql +++ /dev/null @@ -1,7 +0,0 @@ --- Revert schemas/reserved_names/tables/reasons/fixtures/1792800000001_fixture from pg - -BEGIN; - -DELETE FROM reserved_names.reasons WHERE reason IN ('platform', 'brand', 'lookalike', 'abuse'); - -COMMIT; diff --git a/packages/reserved-names/revert/schemas/reserved_names/tables/reasons/table.sql b/packages/reserved-names/revert/schemas/reserved_names/tables/reasons/table.sql deleted file mode 100644 index 6f2d12728..000000000 --- a/packages/reserved-names/revert/schemas/reserved_names/tables/reasons/table.sql +++ /dev/null @@ -1,7 +0,0 @@ --- Revert schemas/reserved_names/tables/reasons/table from pg - -BEGIN; - -DROP TABLE reserved_names.reasons; - -COMMIT; diff --git a/packages/reserved-names/sql/pgpm-reserved-names--0.47.5.bundle.tar.gz b/packages/reserved-names/sql/pgpm-reserved-names--0.47.5.bundle.tar.gz deleted file mode 100644 index 366a03ee3bc6f86f270566fa9a0ec5fbf23406f6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5488 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 diff --git a/packages/reserved-names/sql/pgpm-reserved-names--0.47.5.sql b/packages/reserved-names/sql/pgpm-reserved-names--0.47.5.sql deleted file mode 100644 index cbb259678..000000000 --- a/packages/reserved-names/sql/pgpm-reserved-names--0.47.5.sql +++ /dev/null @@ -1,157 +0,0 @@ -\echo Use "CREATE EXTENSION pgpm-reserved-names" to load this file. \quit -CREATE SCHEMA reserved_names; - -GRANT USAGE ON SCHEMA reserved_names TO PUBLIC; - -CREATE TABLE reserved_names.kinds ( - kind text PRIMARY KEY CHECK (kind ~ '^[a-z][a-z0-9_]*$'), - description text NOT NULL -); - -COMMENT ON TABLE reserved_names.kinds IS 'Categories of names that can be reserved: subdomain, username, domain, slug, ...'; - -GRANT SELECT ON reserved_names.kinds TO PUBLIC; - -CREATE TABLE reserved_names.reasons ( - reason text PRIMARY KEY CHECK (reason ~ '^[a-z][a-z0-9_]*$'), - description text NOT NULL -); - -COMMENT ON TABLE reserved_names.reasons IS 'Why a name is reserved: platform, brand, lookalike, abuse, ...'; - -GRANT SELECT ON reserved_names.reasons TO PUBLIC; - -CREATE TABLE reserved_names.names ( - kind text NOT NULL REFERENCES reserved_names.kinds (kind), - name text NOT NULL CHECK ( - name <> '' - AND name = lower(name) - ), - match text NOT NULL DEFAULT 'exact' CHECK (match IN ('exact', 'prefix', 'suffix')), - reason text NOT NULL REFERENCES reserved_names.reasons (reason), - PRIMARY KEY (kind, name, match) -); - -COMMENT ON TABLE reserved_names.names IS 'Names nobody may claim, by kind. Changed only by migrations.'; - -COMMENT ON COLUMN reserved_names.names.name IS 'The reserved name, lowercase'; - -COMMENT ON COLUMN reserved_names.names.match IS 'exact: the name itself; prefix: every name starting with it; suffix: every name ending with it'; - -GRANT SELECT ON reserved_names.names TO PUBLIC; - -CREATE INDEX names_reason_idx ON reserved_names.names (reason); - -CREATE FUNCTION reserved_names.reserved_by( - kind text, - name text -) RETURNS SETOF reserved_names.names AS $EOFCODE$ - SELECT n.* - FROM reserved_names.names n - WHERE n.kind = pg_catalog.lower(reserved_by.kind) - AND CASE n.match - WHEN 'exact' THEN n.name = pg_catalog.lower(reserved_by.name) - WHEN 'prefix' THEN pg_catalog.starts_with(pg_catalog.lower(reserved_by.name), n.name) - WHEN 'suffix' THEN pg_catalog.right(pg_catalog.lower(reserved_by.name), pg_catalog.length(n.name)) = n.name - END; -$EOFCODE$ LANGUAGE sql STABLE; - -COMMENT ON FUNCTION reserved_names.reserved_by(text, text) IS 'The entries (with their reason) that reserve name for kind; empty when it is free'; - -GRANT EXECUTE ON FUNCTION reserved_names.reserved_by(text, text) TO PUBLIC; - -CREATE FUNCTION reserved_names.is_reserved( - kind text, - name text -) RETURNS boolean AS $EOFCODE$ - SELECT EXISTS (SELECT 1 FROM reserved_names.reserved_by(is_reserved.kind, is_reserved.name)); -$EOFCODE$ LANGUAGE sql STABLE; - -COMMENT ON FUNCTION reserved_names.is_reserved(text, text) IS 'True when name (any case) is reserved for kind'; - -GRANT EXECUTE ON FUNCTION reserved_names.is_reserved(text, text) TO PUBLIC; - -INSERT INTO reserved_names.kinds ( - kind, - description -) VALUES - ('subdomain', 'A label under a shared domain, like login in login.example.com'), - ('username', 'A person''s handle'), - ('domain', 'A whole domain name, like example.com'), - ('slug', 'A name in a URL path, like an organization or app slug'); - -INSERT INTO reserved_names.reasons ( - reason, - description -) VALUES - ('platform', 'Reads as the platform''s own (login, admin, status, ...)'), - ('brand', 'Our brand or product names'), - ('lookalike', 'Can be made to look like another name, e.g. punycode'), - ('abuse', 'Offensive or used for abuse'); - -INSERT INTO reserved_names.names ( - kind, - name, - match, - reason -) VALUES - ('subdomain', 'www', 'exact', 'platform'), - ('subdomain', 'api', 'exact', 'platform'), - ('subdomain', 'auth', 'exact', 'platform'), - ('subdomain', 'login', 'exact', 'platform'), - ('subdomain', 'logout', 'exact', 'platform'), - ('subdomain', 'signin', 'exact', 'platform'), - ('subdomain', 'signup', 'exact', 'platform'), - ('subdomain', 'register', 'exact', 'platform'), - ('subdomain', 'admin', 'exact', 'platform'), - ('subdomain', 'administrator', 'exact', 'platform'), - ('subdomain', 'root', 'exact', 'platform'), - ('subdomain', 'app', 'exact', 'platform'), - ('subdomain', 'apps', 'exact', 'platform'), - ('subdomain', 'dashboard', 'exact', 'platform'), - ('subdomain', 'console', 'exact', 'platform'), - ('subdomain', 'account', 'exact', 'platform'), - ('subdomain', 'accounts', 'exact', 'platform'), - ('subdomain', 'billing', 'exact', 'platform'), - ('subdomain', 'pay', 'exact', 'platform'), - ('subdomain', 'payments', 'exact', 'platform'), - ('subdomain', 'checkout', 'exact', 'platform'), - ('subdomain', 'support', 'exact', 'platform'), - ('subdomain', 'help', 'exact', 'platform'), - ('subdomain', 'status', 'exact', 'platform'), - ('subdomain', 'docs', 'exact', 'platform'), - ('subdomain', 'mail', 'exact', 'platform'), - ('subdomain', 'email', 'exact', 'platform'), - ('subdomain', 'smtp', 'exact', 'platform'), - ('subdomain', 'imap', 'exact', 'platform'), - ('subdomain', 'ftp', 'exact', 'platform'), - ('subdomain', 'ns', 'exact', 'platform'), - ('subdomain', 'ns1', 'exact', 'platform'), - ('subdomain', 'ns2', 'exact', 'platform'), - ('subdomain', 'mx', 'exact', 'platform'), - ('subdomain', 'cdn', 'exact', 'platform'), - ('subdomain', 'static', 'exact', 'platform'), - ('subdomain', 'assets', 'exact', 'platform'), - ('subdomain', 'files', 'exact', 'platform'), - ('subdomain', 'storage', 'exact', 'platform'), - ('subdomain', 'media', 'exact', 'platform'), - ('subdomain', 'ws', 'exact', 'platform'), - ('subdomain', 'wss', 'exact', 'platform'), - ('subdomain', 'graphql', 'exact', 'platform'), - ('subdomain', 'modules', 'exact', 'platform'), - ('subdomain', 'agent', 'exact', 'platform'), - ('subdomain', 'compute', 'exact', 'platform'), - ('subdomain', 'machines', 'exact', 'platform'), - ('subdomain', 'cluster', 'exact', 'platform'), - ('subdomain', 'migrate', 'exact', 'platform'), - ('subdomain', 'internal', 'exact', 'platform'), - ('subdomain', 'system', 'exact', 'platform'), - ('subdomain', 'platform', 'exact', 'platform'), - ('subdomain', 'security', 'exact', 'platform'), - ('subdomain', 'sso', 'exact', 'platform'), - ('subdomain', 'oauth', 'exact', 'platform'), - ('subdomain', 'id', 'exact', 'platform'), - ('subdomain', 'identity', 'exact', 'platform'), - ('subdomain', 'verify', 'exact', 'platform'), - ('subdomain', 'secure', 'exact', 'platform'), - ('subdomain', 'xn--', 'prefix', 'lookalike'); \ No newline at end of file diff --git a/packages/reserved-names/verify/schemas/reserved_names/procedures/is_reserved.sql b/packages/reserved-names/verify/schemas/reserved_names/procedures/is_reserved.sql deleted file mode 100644 index bae6eedb1..000000000 --- a/packages/reserved-names/verify/schemas/reserved_names/procedures/is_reserved.sql +++ /dev/null @@ -1,7 +0,0 @@ --- Verify schemas/reserved_names/procedures/is_reserved on pg - -BEGIN; - -SELECT assert_function('reserved_names.is_reserved(text, text)'::regprocedure); - -ROLLBACK; diff --git a/packages/reserved-names/verify/schemas/reserved_names/procedures/reserved_by.sql b/packages/reserved-names/verify/schemas/reserved_names/procedures/reserved_by.sql deleted file mode 100644 index d155b62b8..000000000 --- a/packages/reserved-names/verify/schemas/reserved_names/procedures/reserved_by.sql +++ /dev/null @@ -1,7 +0,0 @@ --- Verify schemas/reserved_names/procedures/reserved_by on pg - -BEGIN; - -SELECT assert_function('reserved_names.reserved_by(text, text)'::regprocedure); - -ROLLBACK; diff --git a/packages/reserved-names/verify/schemas/reserved_names/schema.sql b/packages/reserved-names/verify/schemas/reserved_names/schema.sql deleted file mode 100644 index 6e605ce0a..000000000 --- a/packages/reserved-names/verify/schemas/reserved_names/schema.sql +++ /dev/null @@ -1,7 +0,0 @@ --- Verify schemas/reserved_names/schema on pg - -BEGIN; - -SELECT assert_schema('reserved_names'::regnamespace); - -ROLLBACK; diff --git a/packages/reserved-names/verify/schemas/reserved_names/tables/kinds/fixtures/1792800000000_fixture.sql b/packages/reserved-names/verify/schemas/reserved_names/tables/kinds/fixtures/1792800000000_fixture.sql deleted file mode 100644 index f7fad4347..000000000 --- a/packages/reserved-names/verify/schemas/reserved_names/tables/kinds/fixtures/1792800000000_fixture.sql +++ /dev/null @@ -1,7 +0,0 @@ --- Verify schemas/reserved_names/tables/kinds/fixtures/1792800000000_fixture on pg - -BEGIN; - -SELECT 1/count(*) FROM reserved_names.kinds WHERE kind = 'subdomain'; - -ROLLBACK; diff --git a/packages/reserved-names/verify/schemas/reserved_names/tables/kinds/table.sql b/packages/reserved-names/verify/schemas/reserved_names/tables/kinds/table.sql deleted file mode 100644 index bec62dd16..000000000 --- a/packages/reserved-names/verify/schemas/reserved_names/tables/kinds/table.sql +++ /dev/null @@ -1,7 +0,0 @@ --- Verify schemas/reserved_names/tables/kinds/table on pg - -BEGIN; - -SELECT assert_table('reserved_names.kinds'::regclass); - -ROLLBACK; diff --git a/packages/reserved-names/verify/schemas/reserved_names/tables/names/fixtures/1792800000002_fixture.sql b/packages/reserved-names/verify/schemas/reserved_names/tables/names/fixtures/1792800000002_fixture.sql deleted file mode 100644 index 87b28e70a..000000000 --- a/packages/reserved-names/verify/schemas/reserved_names/tables/names/fixtures/1792800000002_fixture.sql +++ /dev/null @@ -1,7 +0,0 @@ --- Verify schemas/reserved_names/tables/names/fixtures/1792800000002_fixture on pg - -BEGIN; - -SELECT 1/count(*) FROM reserved_names.names WHERE kind = 'subdomain' AND name = 'login'; - -ROLLBACK; diff --git a/packages/reserved-names/verify/schemas/reserved_names/tables/names/indexes/names_reason_idx.sql b/packages/reserved-names/verify/schemas/reserved_names/tables/names/indexes/names_reason_idx.sql deleted file mode 100644 index 426d1c486..000000000 --- a/packages/reserved-names/verify/schemas/reserved_names/tables/names/indexes/names_reason_idx.sql +++ /dev/null @@ -1,7 +0,0 @@ --- Verify schemas/reserved_names/tables/names/indexes/names_reason_idx on pg - -BEGIN; - -SELECT assert_index('reserved_names.names_reason_idx'::regclass, 'reserved_names.names'::regclass); - -ROLLBACK; diff --git a/packages/reserved-names/verify/schemas/reserved_names/tables/names/table.sql b/packages/reserved-names/verify/schemas/reserved_names/tables/names/table.sql deleted file mode 100644 index 167030de4..000000000 --- a/packages/reserved-names/verify/schemas/reserved_names/tables/names/table.sql +++ /dev/null @@ -1,7 +0,0 @@ --- Verify schemas/reserved_names/tables/names/table on pg - -BEGIN; - -SELECT assert_table('reserved_names.names'::regclass); - -ROLLBACK; diff --git a/packages/reserved-names/verify/schemas/reserved_names/tables/reasons/fixtures/1792800000001_fixture.sql b/packages/reserved-names/verify/schemas/reserved_names/tables/reasons/fixtures/1792800000001_fixture.sql deleted file mode 100644 index 83280742f..000000000 --- a/packages/reserved-names/verify/schemas/reserved_names/tables/reasons/fixtures/1792800000001_fixture.sql +++ /dev/null @@ -1,7 +0,0 @@ --- Verify schemas/reserved_names/tables/reasons/fixtures/1792800000001_fixture on pg - -BEGIN; - -SELECT 1/count(*) FROM reserved_names.reasons WHERE reason = 'platform'; - -ROLLBACK; diff --git a/packages/reserved-names/verify/schemas/reserved_names/tables/reasons/table.sql b/packages/reserved-names/verify/schemas/reserved_names/tables/reasons/table.sql deleted file mode 100644 index 7481a6749..000000000 --- a/packages/reserved-names/verify/schemas/reserved_names/tables/reasons/table.sql +++ /dev/null @@ -1,7 +0,0 @@ --- Verify schemas/reserved_names/tables/reasons/table on pg - -BEGIN; - -SELECT assert_table('reserved_names.reasons'::regclass); - -ROLLBACK; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 5b4bbb30e..92051e6a4 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -338,16 +338,6 @@ importers: specifier: ^5 version: 5.8.0(@dataplan/json@1.0.0(grafast@1.0.2(graphql@16.13.0)))(@dataplan/pg@1.0.3(@dataplan/json@1.0.0(grafast@1.0.2(graphql@16.13.0)))(grafast@1.0.2(graphql@16.13.0))(graphile-config@1.0.1)(graphql@16.13.0)(pg-sql2@5.0.1)(pg@8.22.0))(@types/node@22.19.17)(grafserv@1.0.0(@types/node@22.19.17)(grafast@1.0.2(graphql@16.13.0))(graphile-config@1.0.1)(graphql@16.13.0)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(use-sync-external-store@1.6.0(react@19.2.5))(ws@8.20.0))(graphile-build@5.0.2(grafast@1.0.2(graphql@16.13.0))(graphile-config@1.0.1)(graphql@16.13.0))(pg-sql2@5.0.1)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(tamedevil@0.1.1)(use-sync-external-store@1.6.0(react@19.2.5))(ws@8.20.0) - packages/reserved-names: - dependencies: - "@pgpm/verify": - specifier: workspace:* - version: link:../verify - devDependencies: - pgpm: - specifier: ^5 - version: 5.8.0(@dataplan/json@1.0.0(grafast@1.0.2(graphql@16.13.0)))(@dataplan/pg@1.0.3(@dataplan/json@1.0.0(grafast@1.0.2(graphql@16.13.0)))(grafast@1.0.2(graphql@16.13.0))(graphile-config@1.0.1)(graphql@16.13.0)(pg-sql2@5.0.1)(pg@8.22.0))(@types/node@22.19.17)(grafserv@1.0.0(@types/node@22.19.17)(grafast@1.0.2(graphql@16.13.0))(graphile-config@1.0.1)(graphql@16.13.0)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(use-sync-external-store@1.6.0(react@19.2.5))(ws@8.20.0))(graphile-build@5.0.2(grafast@1.0.2(graphql@16.13.0))(graphile-config@1.0.1)(graphql@16.13.0))(pg-sql2@5.0.1)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(tamedevil@0.1.1)(use-sync-external-store@1.6.0(react@19.2.5))(ws@8.20.0) - packages/stamps: dependencies: "@pgpm/jwt-claims":