From 863212dde43f7541e33bb8452ae0b8e7486fc3a2 Mon Sep 17 00:00:00 2001 From: avallete Date: Wed, 4 Mar 2026 18:24:21 +0100 Subject: [PATCH 1/3] wip --- .gitignore | 2 + CONTRIBUTING.md | 3 + .../cluster/extensions/citext.sql | 1 + .../cluster/extensions/pg_cron.sql | 1 + .../cluster/extensions/pg_net.sql | 1 + .../cluster/extensions/pg_trgm.sql | 1 + .../schemas/app/domains/email_address.sql | 4 + .../schemas/app/domains/semver.sql | 2 + .../schemas/app/domains/valid_name.sql | 2 + .../schemas/app/functions/exception.sql | 10 + .../app/functions/is_handle_maintainer.sql | 31 + .../functions/is_organization_maintainer.sql | 21 + .../app/functions/is_package_maintainer.sql | 36 + .../is_package_version_maintainer.sql | 15 + .../schemas/app/functions/is_valid.sql | 13 + .../app/functions/register_account.sql | 23 + ...egister_organization_creator_as_member.sql | 12 + .../app/functions/semver_exception.sql | 11 + .../schemas/app/functions/semver_to_text.sql | 10 + .../schemas/app/functions/simulate_login.sql | 30 + .../schemas/app/functions/text_to_semver.sql | 23 + .../schemas/app/functions/to_package_name.sql | 10 + .../app/functions/update_avatar_id.sql | 32 + .../app/functions/version_text_to_handle.sql | 9 + .../version_text_to_package_partial_name.sql | 9 + declarative-schemas/schemas/app/schema.sql | 9 + .../schemas/app/tables/accounts.sql | 41 + .../schemas/app/tables/handle_registry.sql | 13 + .../schemas/app/tables/members.sql | 31 + .../schemas/app/tables/organizations.sql | 50 + .../schemas/app/tables/package_upgrades.sql | 28 + .../schemas/app/tables/package_versions.sql | 27 + .../schemas/app/tables/packages.sql | 33 + .../schemas/app/types/membership_role.sql | 3 + .../schemas/app/types/semver_struct.sql | 5 + .../public/functions/search_packages.sql | 18 + .../schemas/public/views/accounts.sql | 9 + .../schemas/public/views/members.sql | 5 + .../schemas/public/views/organizations.sql | 9 + .../schemas/public/views/package_upgrades.sql | 9 + .../schemas/public/views/package_versions.sql | 11 + .../schemas/public/views/packages.sql | 21 + docs/declarative-schema.md | 143 +++ package-lock.json | 1021 +++++++++++++++++ package.json | 9 + scripts/declarative-dbdev-init.sh | 143 +++ scripts/declarative-dbdev-update.sh | 177 +++ 47 files changed, 2127 insertions(+) create mode 100644 declarative-schemas/cluster/extensions/citext.sql create mode 100644 declarative-schemas/cluster/extensions/pg_cron.sql create mode 100644 declarative-schemas/cluster/extensions/pg_net.sql create mode 100644 declarative-schemas/cluster/extensions/pg_trgm.sql create mode 100644 declarative-schemas/schemas/app/domains/email_address.sql create mode 100644 declarative-schemas/schemas/app/domains/semver.sql create mode 100644 declarative-schemas/schemas/app/domains/valid_name.sql create mode 100644 declarative-schemas/schemas/app/functions/exception.sql create mode 100644 declarative-schemas/schemas/app/functions/is_handle_maintainer.sql create mode 100644 declarative-schemas/schemas/app/functions/is_organization_maintainer.sql create mode 100644 declarative-schemas/schemas/app/functions/is_package_maintainer.sql create mode 100644 declarative-schemas/schemas/app/functions/is_package_version_maintainer.sql create mode 100644 declarative-schemas/schemas/app/functions/is_valid.sql create mode 100644 declarative-schemas/schemas/app/functions/register_account.sql create mode 100644 declarative-schemas/schemas/app/functions/register_organization_creator_as_member.sql create mode 100644 declarative-schemas/schemas/app/functions/semver_exception.sql create mode 100644 declarative-schemas/schemas/app/functions/semver_to_text.sql create mode 100644 declarative-schemas/schemas/app/functions/simulate_login.sql create mode 100644 declarative-schemas/schemas/app/functions/text_to_semver.sql create mode 100644 declarative-schemas/schemas/app/functions/to_package_name.sql create mode 100644 declarative-schemas/schemas/app/functions/update_avatar_id.sql create mode 100644 declarative-schemas/schemas/app/functions/version_text_to_handle.sql create mode 100644 declarative-schemas/schemas/app/functions/version_text_to_package_partial_name.sql create mode 100644 declarative-schemas/schemas/app/schema.sql create mode 100644 declarative-schemas/schemas/app/tables/accounts.sql create mode 100644 declarative-schemas/schemas/app/tables/handle_registry.sql create mode 100644 declarative-schemas/schemas/app/tables/members.sql create mode 100644 declarative-schemas/schemas/app/tables/organizations.sql create mode 100644 declarative-schemas/schemas/app/tables/package_upgrades.sql create mode 100644 declarative-schemas/schemas/app/tables/package_versions.sql create mode 100644 declarative-schemas/schemas/app/tables/packages.sql create mode 100644 declarative-schemas/schemas/app/types/membership_role.sql create mode 100644 declarative-schemas/schemas/app/types/semver_struct.sql create mode 100644 declarative-schemas/schemas/public/functions/search_packages.sql create mode 100644 declarative-schemas/schemas/public/views/accounts.sql create mode 100644 declarative-schemas/schemas/public/views/members.sql create mode 100644 declarative-schemas/schemas/public/views/organizations.sql create mode 100644 declarative-schemas/schemas/public/views/package_upgrades.sql create mode 100644 declarative-schemas/schemas/public/views/package_versions.sql create mode 100644 declarative-schemas/schemas/public/views/packages.sql create mode 100644 docs/declarative-schema.md create mode 100644 package-lock.json create mode 100644 package.json create mode 100755 scripts/declarative-dbdev-init.sh create mode 100755 scripts/declarative-dbdev-update.sh diff --git a/.gitignore b/.gitignore index 4c09d6be..ebc47753 100644 --- a/.gitignore +++ b/.gitignore @@ -11,3 +11,5 @@ __pycache__/ *.pyc .DS_Store target/ +node_modules/ +baseline-catalog.json diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 54ae50fc..82e925f0 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -31,6 +31,9 @@ service_role key: KEY The *API URL* and *anon key* values will be used in the next section to setup environment variables. +### Schema management (declarative) + +The repo supports a **declarative schema** workflow using [pg-delta](https://github.com/supabase/pg-toolbelt/tree/main/packages/pg-delta) to export the database shape into version-controlled `.sql` files and generate migrations by diffing desired state against the running Supabase DB. For full details, prerequisites, and commands, see [docs/declarative-schema.md](docs/declarative-schema.md). ### Website (database.dev) diff --git a/declarative-schemas/cluster/extensions/citext.sql b/declarative-schemas/cluster/extensions/citext.sql new file mode 100644 index 00000000..62369b5d --- /dev/null +++ b/declarative-schemas/cluster/extensions/citext.sql @@ -0,0 +1 @@ +create extension citext with schema extensions; \ No newline at end of file diff --git a/declarative-schemas/cluster/extensions/pg_cron.sql b/declarative-schemas/cluster/extensions/pg_cron.sql new file mode 100644 index 00000000..a423154e --- /dev/null +++ b/declarative-schemas/cluster/extensions/pg_cron.sql @@ -0,0 +1 @@ +create extension pg_cron with schema pg_catalog; \ No newline at end of file diff --git a/declarative-schemas/cluster/extensions/pg_net.sql b/declarative-schemas/cluster/extensions/pg_net.sql new file mode 100644 index 00000000..c712499f --- /dev/null +++ b/declarative-schemas/cluster/extensions/pg_net.sql @@ -0,0 +1 @@ +create extension pg_net with schema extensions; \ No newline at end of file diff --git a/declarative-schemas/cluster/extensions/pg_trgm.sql b/declarative-schemas/cluster/extensions/pg_trgm.sql new file mode 100644 index 00000000..085d8ac9 --- /dev/null +++ b/declarative-schemas/cluster/extensions/pg_trgm.sql @@ -0,0 +1 @@ +create extension pg_trgm with schema extensions; \ No newline at end of file diff --git a/declarative-schemas/schemas/app/domains/email_address.sql b/declarative-schemas/schemas/app/domains/email_address.sql new file mode 100644 index 00000000..905df469 --- /dev/null +++ b/declarative-schemas/schemas/app/domains/email_address.sql @@ -0,0 +1,4 @@ +create domain app.email_address as extensions.citext + check + ((VALUE OPERATOR(extensions.~) + '^[a-zA-Z0-9.!#$%&''*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$'::extensions.citext)); \ No newline at end of file diff --git a/declarative-schemas/schemas/app/domains/semver.sql b/declarative-schemas/schemas/app/domains/semver.sql new file mode 100644 index 00000000..85ec6314 --- /dev/null +++ b/declarative-schemas/schemas/app/domains/semver.sql @@ -0,0 +1,2 @@ +create domain app.semver as app.semver_struct + check (app.is_valid(VALUE)); \ No newline at end of file diff --git a/declarative-schemas/schemas/app/domains/valid_name.sql b/declarative-schemas/schemas/app/domains/valid_name.sql new file mode 100644 index 00000000..9492971b --- /dev/null +++ b/declarative-schemas/schemas/app/domains/valid_name.sql @@ -0,0 +1,2 @@ +create domain app.valid_name as extensions.citext + check ((VALUE OPERATOR(extensions.~) '^[A-z][A-z0-9\_]{2,32}$'::extensions.citext)); \ No newline at end of file diff --git a/declarative-schemas/schemas/app/functions/exception.sql b/declarative-schemas/schemas/app/functions/exception.sql new file mode 100644 index 00000000..f8142d6e --- /dev/null +++ b/declarative-schemas/schemas/app/functions/exception.sql @@ -0,0 +1,10 @@ +create function app.exception ( + message text +) + returns text + language plpgsql + AS $function$ + begin + raise exception using errcode='22000', message=message; + end; + $function$; \ No newline at end of file diff --git a/declarative-schemas/schemas/app/functions/is_handle_maintainer.sql b/declarative-schemas/schemas/app/functions/is_handle_maintainer.sql new file mode 100644 index 00000000..14dfcc60 --- /dev/null +++ b/declarative-schemas/schemas/app/functions/is_handle_maintainer.sql @@ -0,0 +1,31 @@ +create function app.is_handle_maintainer ( + account_id uuid, + handle app.valid_name +) + returns boolean + language sql + stable + AS $function$ + select + exists( + select + 1 + from + app.accounts acc + where + acc.id = $1 + and acc.handle = $2 + ) + or exists( + select + 1 + from + app.organizations o + join app.members m + on o.id = m.organization_id + where + m.role = 'maintainer' + and m.account_id = $1 + and o.handle = $2 + ) +$function$; \ No newline at end of file diff --git a/declarative-schemas/schemas/app/functions/is_organization_maintainer.sql b/declarative-schemas/schemas/app/functions/is_organization_maintainer.sql new file mode 100644 index 00000000..01a7245d --- /dev/null +++ b/declarative-schemas/schemas/app/functions/is_organization_maintainer.sql @@ -0,0 +1,21 @@ +create function app.is_organization_maintainer ( + account_id uuid, + organization_id uuid +) + returns boolean + language sql + stable + AS $function$ + -- Does the currently authenticated user have permission to admin orgs and org members? + select + exists( + select + 1 + from + app.members m + where + m.account_id = $1 + and m.organization_id = $2 + and m.role = 'maintainer' + ) +$function$; \ No newline at end of file diff --git a/declarative-schemas/schemas/app/functions/is_package_maintainer.sql b/declarative-schemas/schemas/app/functions/is_package_maintainer.sql new file mode 100644 index 00000000..4d0fd169 --- /dev/null +++ b/declarative-schemas/schemas/app/functions/is_package_maintainer.sql @@ -0,0 +1,36 @@ +create function app.is_package_maintainer ( + account_id uuid, + package_id uuid +) + returns boolean + language sql + stable + AS $function$ + select + exists( + select + 1 + from + app.accounts acc + join app.packages p + on acc.handle = p.handle + where + acc.id = $1 + and p.id = $2 + ) + or exists( + -- current user is maintainer of org that owns the package + select + 1 + from + app.packages p + join app.organizations o + on p.handle = o.handle + join app.members m + on o.id = m.organization_id + where + m.role = 'maintainer' + and m.account_id = $1 + and p.id = $2 + ) +$function$; \ No newline at end of file diff --git a/declarative-schemas/schemas/app/functions/is_package_version_maintainer.sql b/declarative-schemas/schemas/app/functions/is_package_version_maintainer.sql new file mode 100644 index 00000000..6e52674a --- /dev/null +++ b/declarative-schemas/schemas/app/functions/is_package_version_maintainer.sql @@ -0,0 +1,15 @@ +create function app.is_package_version_maintainer ( + account_id uuid, + package_version_id uuid +) + returns boolean + language sql + stable + AS $function$ + select + app.is_package_maintainer($1, pv.package_id) + from + app.package_versions pv + where + pv.id = $2 +$function$; \ No newline at end of file diff --git a/declarative-schemas/schemas/app/functions/is_valid.sql b/declarative-schemas/schemas/app/functions/is_valid.sql new file mode 100644 index 00000000..365f31e2 --- /dev/null +++ b/declarative-schemas/schemas/app/functions/is_valid.sql @@ -0,0 +1,13 @@ +create function app.is_valid ( + app .semver_struct +) + returns boolean + language sql + immutable + AS $function$ + select ( + ($1).major is not null + and ($1).minor is not null + and ($1).patch is not null + ) +$function$; \ No newline at end of file diff --git a/declarative-schemas/schemas/app/functions/register_account.sql b/declarative-schemas/schemas/app/functions/register_account.sql new file mode 100644 index 00000000..4f0aacd3 --- /dev/null +++ b/declarative-schemas/schemas/app/functions/register_account.sql @@ -0,0 +1,23 @@ +create function app.register_account() + returns trigger + language plpgsql + security definer + AS $function$ + begin + insert into app.handle_registry (handle, is_organization) + values ( + new.raw_user_meta_data ->> 'handle', + false + ); + + insert into app.accounts (id, handle, display_name, bio, contact_email) + values ( + new.id, + new.raw_user_meta_data ->> 'handle', + new.raw_user_meta_data ->> 'display_name', + new.raw_user_meta_data ->> 'bio', + new.raw_user_meta_data ->> 'contact_email' + ); + return new; + end; + $function$; \ No newline at end of file diff --git a/declarative-schemas/schemas/app/functions/register_organization_creator_as_member.sql b/declarative-schemas/schemas/app/functions/register_organization_creator_as_member.sql new file mode 100644 index 00000000..e8335c5d --- /dev/null +++ b/declarative-schemas/schemas/app/functions/register_organization_creator_as_member.sql @@ -0,0 +1,12 @@ +create function app.register_organization_creator_as_member() + returns trigger + language plpgsql + security definer + AS $function$ + begin + insert into app.members(organization_id, account_id, role) + values (new.id, auth.uid(), 'maintainer'); + + return new; + end; + $function$; \ No newline at end of file diff --git a/declarative-schemas/schemas/app/functions/semver_exception.sql b/declarative-schemas/schemas/app/functions/semver_exception.sql new file mode 100644 index 00000000..31873eef --- /dev/null +++ b/declarative-schemas/schemas/app/functions/semver_exception.sql @@ -0,0 +1,11 @@ +create function app.semver_exception ( + version text +) + returns app.semver_struct + language plpgsql + immutable + AS $function$ +begin + raise exception using errcode='22000', message=format('Invalid semver %L', version); +end; +$function$; \ No newline at end of file diff --git a/declarative-schemas/schemas/app/functions/semver_to_text.sql b/declarative-schemas/schemas/app/functions/semver_to_text.sql new file mode 100644 index 00000000..8915040f --- /dev/null +++ b/declarative-schemas/schemas/app/functions/semver_to_text.sql @@ -0,0 +1,10 @@ +create function app.semver_to_text ( + app .semver +) + returns text + language sql + immutable + AS $function$ + select + format('%s.%s.%s', $1.major, $1.minor, $1.patch) +$function$; \ No newline at end of file diff --git a/declarative-schemas/schemas/app/functions/simulate_login.sql b/declarative-schemas/schemas/app/functions/simulate_login.sql new file mode 100644 index 00000000..04c1bada --- /dev/null +++ b/declarative-schemas/schemas/app/functions/simulate_login.sql @@ -0,0 +1,30 @@ +create function app.simulate_login ( + email extensions.citext +) + returns void + language sql + AS $function$ + /* + Simulated JWT of logged in user + */ + + select + set_config( + 'request.jwt.claims', + ( + select + json_build_object( + 'sub', + id, + 'role', + 'authenticated' + )::text + from + auth.users + where + email = $1 + ), + true + ), + set_config('role', 'authenticated', true) +$function$; \ No newline at end of file diff --git a/declarative-schemas/schemas/app/functions/text_to_semver.sql b/declarative-schemas/schemas/app/functions/text_to_semver.sql new file mode 100644 index 00000000..636d5c86 --- /dev/null +++ b/declarative-schemas/schemas/app/functions/text_to_semver.sql @@ -0,0 +1,23 @@ +create function app.text_to_semver ( + text +) + returns app.semver_struct + language sql + immutable + strict + AS $function$ + with s(version) as ( + select ( + split_part($1, '.', 1), + split_part($1, '.', 2), + split_part(split_part(split_part($1, '.', 3), '-', 1), '+', 1) + )::app.semver_struct + ) + select + case app.is_valid(s.version) + when true then s.version + else app.semver_exception($1) + end + from + s +$function$; \ No newline at end of file diff --git a/declarative-schemas/schemas/app/functions/to_package_name.sql b/declarative-schemas/schemas/app/functions/to_package_name.sql new file mode 100644 index 00000000..f6817e53 --- /dev/null +++ b/declarative-schemas/schemas/app/functions/to_package_name.sql @@ -0,0 +1,10 @@ +create function app.to_package_name ( + handle app.valid_name, + partial_name app.valid_name +) + returns text + language sql + immutable + AS $function$ + select format('%s-%s', $1, $2) +$function$; \ No newline at end of file diff --git a/declarative-schemas/schemas/app/functions/update_avatar_id.sql b/declarative-schemas/schemas/app/functions/update_avatar_id.sql new file mode 100644 index 00000000..3d49d7b6 --- /dev/null +++ b/declarative-schemas/schemas/app/functions/update_avatar_id.sql @@ -0,0 +1,32 @@ +create function app.update_avatar_id() + returns trigger + language plpgsql + security definer + AS $function$ + declare + v_handle app.valid_name; + v_affected_account app.accounts := null; + begin + select (string_to_array(new.name, '-'::text))[1]::app.valid_name into v_handle; + + update app.accounts + set avatar_id = new.id + where handle = v_handle + returning * into v_affected_account; + + if not v_affected_account is null then + update auth.users u + set + "raw_user_meta_data" = u.raw_user_meta_data || jsonb_build_object( + 'avatar_path', new.name + ) + where u.id = v_affected_account.id; + else + update app.organizations + set avatar_id = new.id + where handle = v_handle; + end if; + + return new; + end; + $function$; \ No newline at end of file diff --git a/declarative-schemas/schemas/app/functions/version_text_to_handle.sql b/declarative-schemas/schemas/app/functions/version_text_to_handle.sql new file mode 100644 index 00000000..385013cb --- /dev/null +++ b/declarative-schemas/schemas/app/functions/version_text_to_handle.sql @@ -0,0 +1,9 @@ +create function app.version_text_to_handle ( + version text +) + returns app.valid_name + language sql + immutable + AS $function$ + select split_part($1, '-', 1) +$function$; \ No newline at end of file diff --git a/declarative-schemas/schemas/app/functions/version_text_to_package_partial_name.sql b/declarative-schemas/schemas/app/functions/version_text_to_package_partial_name.sql new file mode 100644 index 00000000..fc30799a --- /dev/null +++ b/declarative-schemas/schemas/app/functions/version_text_to_package_partial_name.sql @@ -0,0 +1,9 @@ +create function app.version_text_to_package_partial_name ( + version text +) + returns app.valid_name + language sql + immutable + AS $function$ + select split_part($1, '--', 2) +$function$; \ No newline at end of file diff --git a/declarative-schemas/schemas/app/schema.sql b/declarative-schemas/schemas/app/schema.sql new file mode 100644 index 00000000..e42d98df --- /dev/null +++ b/declarative-schemas/schemas/app/schema.sql @@ -0,0 +1,9 @@ +create schema app authorization postgres; + +alter default privileges for role postgres in schema app grant select on tables to anon; + +alter default privileges for role postgres in schema app grant select on tables to authenticated; + +grant usage on schema app to anon; + +grant usage on schema app to authenticated; \ No newline at end of file diff --git a/declarative-schemas/schemas/app/tables/accounts.sql b/declarative-schemas/schemas/app/tables/accounts.sql new file mode 100644 index 00000000..f85f8fa0 --- /dev/null +++ b/declarative-schemas/schemas/app/tables/accounts.sql @@ -0,0 +1,41 @@ +create table app.accounts ( + id uuid not null, + handle app.valid_name not null, + is_organization boolean generated always as (false) stored, + avatar_id uuid, + display_name text, + bio text, + contact_email app.email_address, + created_at timestamp with time zone default now() not null +); + +create policy accounts_select_policy on app.accounts + for select + to authenticated + using (true); + +alter table app.accounts + enable row level security; + +alter table app.accounts + add constraint accounts_avatar_id_fkey foreign key (avatar_id) references storage.objects(id); + +alter table app.accounts + add constraint accounts_bio_check check (length(bio) <= 512); + +alter table app.accounts + add constraint accounts_display_name_check check (length(display_name) <= 128); + +alter table app.accounts + add constraint accounts_handle_key unique (handle); + +alter table app.accounts + add constraint accounts_id_fkey foreign key (id) references auth.users(id); + +alter table app.accounts + add constraint accounts_pkey primary key (id); + +alter table app.accounts + add constraint fk_handle_registry foreign key (handle, is_organization) references app.handle_registry(handle, is_organization); + +grant update (avatar_id, bio, contact_email, display_name) on app.accounts to authenticated; \ No newline at end of file diff --git a/declarative-schemas/schemas/app/tables/handle_registry.sql b/declarative-schemas/schemas/app/tables/handle_registry.sql new file mode 100644 index 00000000..8c9431a3 --- /dev/null +++ b/declarative-schemas/schemas/app/tables/handle_registry.sql @@ -0,0 +1,13 @@ +create table app.handle_registry ( + handle app.valid_name not null, + is_organization boolean not null, + created_at timestamp with time zone default now() not null +); + +alter table app.handle_registry + add constraint handle_registry_handle_is_organization_key unique (handle, is_organization); + +alter table app.handle_registry + add constraint handle_registry_pkey primary key (handle); + +grant insert (handle, is_organization) on app.handle_registry to authenticated; \ No newline at end of file diff --git a/declarative-schemas/schemas/app/tables/members.sql b/declarative-schemas/schemas/app/tables/members.sql new file mode 100644 index 00000000..b47e172b --- /dev/null +++ b/declarative-schemas/schemas/app/tables/members.sql @@ -0,0 +1,31 @@ +create table app.members ( + id uuid default extensions.uuid_generate_v4() not null, + organization_id uuid not null, + account_id uuid not null, + role app.membership_role not null, + created_at timestamp with time zone default now() not null +); + +create policy members_select_policy on app.members + for select + to authenticated + using (true); + +alter table app.members + enable row level security; + +alter table app.members + add constraint members_organization_id_account_id_key unique (organization_id, account_id); + +alter table app.members + add constraint members_pkey primary key (id); + +alter table app.members + add constraint members_account_id_fkey foreign key (account_id) references app.accounts(id); + +alter table app.members + add constraint members_organization_id_fkey foreign key (organization_id) references app.organizations(id); + +grant delete on app.members to authenticated; + +grant insert (account_id, organization_id, role) on app.members to authenticated; \ No newline at end of file diff --git a/declarative-schemas/schemas/app/tables/organizations.sql b/declarative-schemas/schemas/app/tables/organizations.sql new file mode 100644 index 00000000..49c0659b --- /dev/null +++ b/declarative-schemas/schemas/app/tables/organizations.sql @@ -0,0 +1,50 @@ +create table app.organizations ( + id uuid default gen_random_uuid() not null, + handle app.valid_name not null, + is_organization boolean generated always as (true) stored, + avatar_id uuid, + display_name text, + bio text, + contact_email app.email_address, + created_at timestamp with time zone default now() not null +); + +create trigger on_app_organization_created + after insert on app.organizations + for each row + execute function app.register_organization_creator_as_member(); + +create policy organizations_insert_policy on app.organizations + for insert + to authenticated + with check (true); + +create policy organizations_select_policy on app.organizations + for select + to authenticated + using (true); + +alter table app.organizations + enable row level security; + +alter table app.organizations + add constraint fk_handle_registry foreign key (handle, is_organization) references app.handle_registry(handle, is_organization); + +alter table app.organizations + add constraint organizations_avatar_id_fkey foreign key (avatar_id) references storage.objects(id); + +alter table app.organizations + add constraint organizations_bio_check check (length(bio) <= 512); + +alter table app.organizations + add constraint organizations_display_name_check check (length(display_name) <= 128); + +alter table app.organizations + add constraint organizations_handle_key unique (handle); + +alter table app.organizations + add constraint organizations_pkey primary key (id); + +grant insert (avatar_id, bio, contact_email, display_name, handle) on app.organizations to authenticated; + +grant update (avatar_id, bio, contact_email, display_name) on app.organizations to authenticated; \ No newline at end of file diff --git a/declarative-schemas/schemas/app/tables/package_upgrades.sql b/declarative-schemas/schemas/app/tables/package_upgrades.sql new file mode 100644 index 00000000..847bba95 --- /dev/null +++ b/declarative-schemas/schemas/app/tables/package_upgrades.sql @@ -0,0 +1,28 @@ +create table app.package_upgrades ( + id uuid default gen_random_uuid() not null, + package_id uuid not null, + from_version_struct app.semver not null, + from_version text generated always as (app.semver_to_text(from_version_struct)) stored not null, + to_version_struct app.semver not null, + to_version text generated always as (app.semver_to_text(to_version_struct)) stored not null, + sql character varying(250000), + created_at timestamp with time zone default now() not null +); + +create policy package_upgrades_select_policy on app.package_upgrades + for select + using (true); + +alter table app.package_upgrades + enable row level security; + +alter table app.package_upgrades + add constraint package_upgrades_package_id_from_version_struct_to_version__key unique (package_id, from_version_struct, to_version_struct); + +alter table app.package_upgrades + add constraint package_upgrades_pkey primary key (id); + +alter table app.package_upgrades + add constraint package_upgrades_package_id_fkey foreign key (package_id) references app.packages(id); + +grant insert (from_version_struct, package_id, sql, to_version_struct) on app.package_upgrades to authenticated; \ No newline at end of file diff --git a/declarative-schemas/schemas/app/tables/package_versions.sql b/declarative-schemas/schemas/app/tables/package_versions.sql new file mode 100644 index 00000000..782a3109 --- /dev/null +++ b/declarative-schemas/schemas/app/tables/package_versions.sql @@ -0,0 +1,27 @@ +create table app.package_versions ( + id uuid default gen_random_uuid() not null, + package_id uuid not null, + version_struct app.semver not null, + version text generated always as (app.semver_to_text(version_struct)) stored not null, + sql character varying(250000), + description_md character varying(250000), + created_at timestamp with time zone default now() not null +); + +create policy package_versions_select_policy on app.package_versions + for select + using (true); + +alter table app.package_versions + enable row level security; + +alter table app.package_versions + add constraint package_versions_package_id_version_struct_key unique (package_id, version_struct); + +alter table app.package_versions + add constraint package_versions_pkey primary key (id); + +alter table app.package_versions + add constraint package_versions_package_id_fkey foreign key (package_id) references app.packages(id); + +grant insert (description_md, package_id, sql, version_struct) on app.package_versions to authenticated; \ No newline at end of file diff --git a/declarative-schemas/schemas/app/tables/packages.sql b/declarative-schemas/schemas/app/tables/packages.sql new file mode 100644 index 00000000..674bb308 --- /dev/null +++ b/declarative-schemas/schemas/app/tables/packages.sql @@ -0,0 +1,33 @@ +create table app.packages ( + id uuid default gen_random_uuid() not null, + package_name text generated always as (app.to_package_name(handle, partial_name)) stored not null, + handle app.valid_name not null, + partial_name app.valid_name not null, + control_description character varying(1000), + control_relocatable boolean default false not null, + control_requires character varying(128)[] default '{}'::character varying(128)[], + created_at timestamp with time zone default now() not null +); + +create index packages_handle_search_idx on app.packages using gin (handle extensions.gin_trgm_ops); + +create index packages_partial_name_search_idx on app.packages using gin (partial_name extensions.gin_trgm_ops); + +create policy packages_select_policy on app.packages + for select + to authenticated + using (true); + +alter table app.packages + enable row level security; + +alter table app.packages + add constraint packages_handle_fkey foreign key (handle) references app.handle_registry(handle); + +alter table app.packages + add constraint packages_handle_partial_name_key unique (handle, partial_name); + +alter table app.packages + add constraint packages_pkey primary key (id); + +grant insert (handle, partial_name) on app.packages to authenticated; \ No newline at end of file diff --git a/declarative-schemas/schemas/app/types/membership_role.sql b/declarative-schemas/schemas/app/types/membership_role.sql new file mode 100644 index 00000000..5cf55ed0 --- /dev/null +++ b/declarative-schemas/schemas/app/types/membership_role.sql @@ -0,0 +1,3 @@ +create type app.membership_role as enum ( + 'maintainer' +); \ No newline at end of file diff --git a/declarative-schemas/schemas/app/types/semver_struct.sql b/declarative-schemas/schemas/app/types/semver_struct.sql new file mode 100644 index 00000000..d59d795b --- /dev/null +++ b/declarative-schemas/schemas/app/types/semver_struct.sql @@ -0,0 +1,5 @@ +create type app.semver_struct as ( + major smallint, + minor smallint, + patch smallint +); \ No newline at end of file diff --git a/declarative-schemas/schemas/public/functions/search_packages.sql b/declarative-schemas/schemas/public/functions/search_packages.sql new file mode 100644 index 00000000..6ba0b7e8 --- /dev/null +++ b/declarative-schemas/schemas/public/functions/search_packages.sql @@ -0,0 +1,18 @@ +create function public.search_packages ( + handle extensions.citext default null::extensions.citext, + partial_name extensions.citext default null::extensions.citext +) + returns SETOF public.packages + language sql + stable + AS $function$ + select * + from public.packages + where + ($1 is null or handle <% $1 or handle ~ $1) + and + ($2 is null or partial_name <% $2 or partial_name ~ $2) + order by + coalesce(extensions.similarity($1, handle), 0) + coalesce(extensions.similarity($2, partial_name), 0) desc, + created_at desc; +$function$; \ No newline at end of file diff --git a/declarative-schemas/schemas/public/views/accounts.sql b/declarative-schemas/schemas/public/views/accounts.sql new file mode 100644 index 00000000..663a63ff --- /dev/null +++ b/declarative-schemas/schemas/public/views/accounts.sql @@ -0,0 +1,9 @@ +create view public.accounts AS SELECT acc.id, + acc.handle, + obj.name AS avatar_path, + acc.display_name, + acc.bio, + acc.contact_email, + acc.created_at + FROM (app.accounts acc + LEFT JOIN storage.objects obj ON ((acc.avatar_id = obj.id))); \ No newline at end of file diff --git a/declarative-schemas/schemas/public/views/members.sql b/declarative-schemas/schemas/public/views/members.sql new file mode 100644 index 00000000..399a6652 --- /dev/null +++ b/declarative-schemas/schemas/public/views/members.sql @@ -0,0 +1,5 @@ +create view public.members AS SELECT aio.organization_id, + aio.account_id, + aio.role, + aio.created_at + FROM app.members aio; \ No newline at end of file diff --git a/declarative-schemas/schemas/public/views/organizations.sql b/declarative-schemas/schemas/public/views/organizations.sql new file mode 100644 index 00000000..f4f02e81 --- /dev/null +++ b/declarative-schemas/schemas/public/views/organizations.sql @@ -0,0 +1,9 @@ +create view public.organizations AS SELECT org.id, + org.handle, + obj.name AS avatar_path, + org.display_name, + org.bio, + org.contact_email, + org.created_at + FROM (app.organizations org + LEFT JOIN storage.objects obj ON ((org.avatar_id = obj.id))); \ No newline at end of file diff --git a/declarative-schemas/schemas/public/views/package_upgrades.sql b/declarative-schemas/schemas/public/views/package_upgrades.sql new file mode 100644 index 00000000..600534e4 --- /dev/null +++ b/declarative-schemas/schemas/public/views/package_upgrades.sql @@ -0,0 +1,9 @@ +create view public.package_upgrades AS SELECT pu.id, + pu.package_id, + pa.package_name, + pu.from_version, + pu.to_version, + pu.sql, + pu.created_at + FROM (app.packages pa + JOIN app.package_upgrades pu ON ((pa.id = pu.package_id))); \ No newline at end of file diff --git a/declarative-schemas/schemas/public/views/package_versions.sql b/declarative-schemas/schemas/public/views/package_versions.sql new file mode 100644 index 00000000..f81245e0 --- /dev/null +++ b/declarative-schemas/schemas/public/views/package_versions.sql @@ -0,0 +1,11 @@ +create view public.package_versions AS SELECT pv.id, + pv.package_id, + pa.package_name, + pv.version, + pv.sql, + pv.description_md, + pa.control_description, + pa.control_requires, + pv.created_at + FROM (app.packages pa + JOIN app.package_versions pv ON ((pa.id = pv.package_id))); \ No newline at end of file diff --git a/declarative-schemas/schemas/public/views/packages.sql b/declarative-schemas/schemas/public/views/packages.sql new file mode 100644 index 00000000..9ecff234 --- /dev/null +++ b/declarative-schemas/schemas/public/views/packages.sql @@ -0,0 +1,21 @@ +create view public.packages AS SELECT pa.id, + pa.package_name, + pa.handle, + pa.partial_name, + newest_ver.version AS latest_version, + newest_ver.description_md, + pa.control_description, + pa.control_requires, + pa.created_at + FROM app.packages pa, + LATERAL ( SELECT pv.id, + pv.package_id, + pv.version_struct, + pv.version, + pv.sql, + pv.description_md, + pv.created_at + FROM app.package_versions pv + WHERE (pv.package_id = pa.id) + ORDER BY pv.version_struct + LIMIT 1) newest_ver; \ No newline at end of file diff --git a/docs/declarative-schema.md b/docs/declarative-schema.md new file mode 100644 index 00000000..63a7de27 --- /dev/null +++ b/docs/declarative-schema.md @@ -0,0 +1,143 @@ +# Declarative schema workflow + +This document describes how the dbdev repo uses [pg-delta](https://github.com/supabase/pg-toolbelt/tree/main/packages/pg-delta) for a **declarative schema** workflow: exporting the database shape as version-controlled `.sql` files and generating migrations by diffing desired state against the running database. + +## What is declarative schema? + +**Declarative schema** means the desired database shape is described in files (under `declarative-schemas/`) rather than only in a linear migration history. pg-delta can: + +- **Export** the current database (minus a baseline) into those files. +- **Apply** those files to a temporary “shadow” database. +- **Plan** the diff between the running Supabase DB and the shadow DB to produce a migration script. + +So you can edit the declarative files (or re-export after manual DB changes), then run a script to generate a single migration that brings the real database in line with the desired state. + +This complements the normal **migration-based** workflow: `supabase/migrations/` remains how changes are applied; the declarative flow is a way to derive a migration from a desired-state snapshot. + +## How it fits this repo + +dbdev is a Supabase project with many migrations. The declarative flow: + +1. Uses a **shadow DB** (same Docker image as Supabase Postgres) so the real DB is not modified until you apply a migration. +2. Keeps desired state in `declarative-schemas/` (exported from the live DB, then editable). +3. Diffs that state against the running Supabase DB and writes a migration under `supabase/migrations/`. +4. You apply the migration with `psql` (or the script can do it), then use Supabase as usual. + +```mermaid +flowchart LR + subgraph init [Init or refresh] + A1[Shadow DB] --> A2[Baseline catalog] + A2 --> A3[supabase start] + A3 --> A4[Declarative export] + A4 --> A5[declarative-schemas] + A5 --> A6[Roundtrip verify] + end + subgraph update [After editing schema] + B1[Shadow DB] --> B2[Declarative apply] + B2 --> B3[plan: DB vs shadow] + B3 --> B4[Migration file] + B4 --> B5[Apply via psql] + B5 --> B6[Roundtrip verify] + end +``` + +## Prerequisites + +- **Node.js and npm** – for `npx pgdelta` (run `npm install` in the repo root). +- **Docker** – for the shadow DB and Supabase local stack. +- **Supabase CLI** – for `supabase start` / `supabase stop`. +- **psql** – for applying the generated migration (or use the script’s default apply step). + +From the repo root: + +```bash +npm install +npx pgdelta --help # sanity check +``` + +## Scripts and usage + +Both scripts must be run **from the dbdev repo root** so `npx pgdelta` resolves from `node_modules/`. + +### 1. Init (one-time or refresh): export declarative schema + +Initializes or refreshes `declarative-schemas/` from the running Supabase DB: + +1. Starts a shadow DB (Supabase Postgres image on port 6544). +2. Snapshots the clean shadow DB as a baseline catalog. +3. Starts the dbdev Supabase project (if not already running) on port 54322. +4. Exports the declarative schema (diff: baseline → Supabase DB) into `declarative-schemas/`. +5. Verifies roundtrip: applies the export to a fresh shadow DB and diffs against Supabase (expect 0 changes, or minor GRANT ordering differences). + +```bash +bash scripts/declarative-dbdev-init.sh +``` + +Optional env vars: + +| Variable | Default | Description | +|----------|---------|-------------| +| `SKIP_SUPABASE_START` | (unset) | Set to skip `supabase start` (e.g. DB already running). | +| `SKIP_VERIFY` | (unset) | Set to skip the roundtrip verification step. | +| `PGDELTA` | `npx pgdelta` | Override the pg-delta CLI command. | +| `SHADOW_IMAGE` | `supabase/postgres:15.6.1.143` | Docker image for the shadow DB. | +| `OUTPUT_DIR` | `./declarative-schemas` | Where to write the exported schema. | +| `BASELINE_SNAPSHOT` | `./baseline-catalog.json` | Path for the baseline catalog (not committed; in `.gitignore`). | + +### Changes made in Studio: re-export with init + +If you change the database through **Supabase Studio** (or any direct SQL), the declarative schema files will no longer match the running database. To pull those changes back into the repo: + +1. Leave the Supabase project running (or start it with the init script). +2. Re-run the init script from the repo root: + + ```bash + bash scripts/declarative-dbdev-init.sh + ``` + + The export step uses the **`--force`** flag, so existing files under `declarative-schemas/` are overwritten and the directory is updated to match the current database. You get a clean declarative snapshot of whatever is in the DB, including your Studio changes. + +3. Commit the updated `declarative-schemas/` so the desired state stays in version control. To also add a migration file that records the Studio changes in `supabase/migrations/`, use the Supabase CLI (e.g. `supabase db diff`) to generate a migration from the current DB state, or run the update script after the re-export if you have further edits to the declarative schema. + +You can skip the roundtrip verification when re-exporting after Studio changes by setting `SKIP_VERIFY=1` if the verification step is noisy or fails due to known export limitations. + +### 2. Update (after editing schema): generate and apply migration + +After you edit files under `declarative-schemas/`: + +1. Starts a shadow DB. +2. Applies the declarative schema to the shadow DB (desired state). +3. Runs `pgdelta plan` (source = Supabase DB, target = shadow) to generate a migration. +4. Saves the migration to `supabase/migrations/_.sql`. +5. Applies the migration to the Supabase DB with `psql`. +6. Verifies roundtrip (diff Supabase vs shadow; expect 0 changes). + +```bash +MIGRATION_NAME=my_change bash scripts/declarative-dbdev-update.sh +``` + +Optional env vars: + +| Variable | Default | Description | +|----------|---------|-------------| +| `MIGRATION_NAME` | `declarative_update` | Suffix for the migration filename. | +| `SKIP_APPLY` | (unset) | Set to only write the migration file; do not apply it. | +| `SKIP_VERIFY` | (unset) | Set to skip the roundtrip verification step. | +| `PGDELTA` | `npx pgdelta` | Override the pg-delta CLI command. | +| `SHADOW_IMAGE` | `supabase/postgres:15.6.1.143` | Docker image for the shadow DB. | +| `OUTPUT_DIR` | `./declarative-schemas` | Declarative schema directory. | + +## File layout + +- **`declarative-schemas/`** – Version-controlled desired schema (exported by init, edited by you, applied to shadow in update). + - **`cluster/`** – Cluster-level objects: extensions (`extensions/`), event triggers (`event_triggers.sql`). + - **`schemas/`** – Per-schema objects: `app/` (tables, functions, domains, types), `public/` (views, functions). +- **`supabase/migrations/`** – Supabase migration history; generated migrations are written here and applied via `psql` (or the script). +- **`baseline-catalog.json`** – Generated by the init script, used as the “clean” baseline for export; not committed (in `.gitignore`). + +## Troubleshooting + +- **Shadow image** – The shadow DB must use a `supabase/postgres` image (e.g. `15.6.1.143`) so system schemas (`auth`, `storage`, `extensions`) match. If you use a different Postgres major version, set `SHADOW_IMAGE` to a matching Supabase image tag. +- **Roundtrip fails** – If verification reports changes after a roundtrip, check that extension and domain ordering in the export is correct. Re-running the init script with the current pg-delta can refresh the export; if the tool was recently upgraded, a fresh export may fix serialization issues (e.g. domain base types). The roundtrip may also report **missing RLS policies** (policies that exist in the DB but were not captured in the export) or **GRANT differences** (due to `ALTER DEFAULT PRIVILEGES` ordering). You can skip verification for init with `SKIP_VERIFY=1` and still use the declarative schema for edit-and-migrate workflows. +- **Supabase not running** – The update script requires the Supabase DB on port 54322. Run `supabase start` from the repo root first, or use the init script once to start it. +- **`npx pgdelta` not found** – Run `npm install` from the repo root; the scripts expect to be run from the root so `npx` resolves the local `@supabase/pg-delta` dependency. diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 00000000..35c5cdf2 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,1021 @@ +{ + "name": "dbdev", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "dependencies": { + "@supabase/pg-delta": "https://pkg.pr.new/supabase/pg-toolbelt/@supabase/pg-delta@f56ff1e" + }, + "devDependencies": { + "supabase": "^2.76.16" + } + }, + "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==", + "license": "MIT", + "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/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==", + "license": "MIT", + "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/generator/node_modules/@babel/types": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.0.tgz", + "integrity": "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==", + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.27.1", + "@babel/helper-validator-identifier": "^7.28.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@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==", + "license": "MIT", + "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==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", + "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.0.tgz", + "integrity": "sha512-IyDgFV5GeDUVX4YdF/3CPULtVGSXXMLh1xVIgdCgxApktqnQV0r7/8Nqthg+8YLGaAtdyIlo2qIdZrbCv4+7ww==", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.29.0" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/parser/node_modules/@babel/types": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.0.tgz", + "integrity": "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==", + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.27.1", + "@babel/helper-validator-identifier": "^7.28.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@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==", + "license": "MIT", + "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/template/node_modules/@babel/types": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.0.tgz", + "integrity": "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==", + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.27.1", + "@babel/helper-validator-identifier": "^7.28.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.28.5.tgz", + "integrity": "sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.27.1", + "@babel/generator": "^7.28.5", + "@babel/helper-globals": "^7.28.0", + "@babel/parser": "^7.28.5", + "@babel/template": "^7.27.2", + "@babel/types": "^7.28.5", + "debug": "^4.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.5.tgz", + "integrity": "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==", + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.27.1", + "@babel/helper-validator-identifier": "^7.28.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@isaacs/fs-minipass": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@isaacs/fs-minipass/-/fs-minipass-4.0.1.tgz", + "integrity": "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^7.0.4" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "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==", + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@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==", + "license": "MIT", + "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==", + "license": "MIT" + }, + "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==", + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@launchql/protobufjs": { + "version": "7.2.6", + "resolved": "https://registry.npmjs.org/@launchql/protobufjs/-/protobufjs-7.2.6.tgz", + "integrity": "sha512-vwi1nG2/heVFsIMHQU1KxTjUp5c757CTtRAZn/jutApCkFlle1iv8tzM/DHlSZJKDldxaYqnNYTg0pTyp8Bbtg==", + "hasInstallScript": true, + "license": "BSD-3-Clause", + "dependencies": { + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/codegen": "^2.0.4", + "@protobufjs/eventemitter": "^1.1.0", + "@protobufjs/fetch": "^1.1.0", + "@protobufjs/float": "^1.0.2", + "@protobufjs/inquire": "^1.1.0", + "@protobufjs/path": "^1.1.2", + "@protobufjs/pool": "^1.1.0", + "@protobufjs/utf8": "^1.1.0", + "@types/node": ">=13.7.0", + "long": "^5.0.0" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/@libpg-query/parser": { + "version": "17.6.3", + "resolved": "https://registry.npmjs.org/@libpg-query/parser/-/parser-17.6.3.tgz", + "integrity": "sha512-AvbS7b9GJZfCzqt4tLMqTaYK7Css9pJRTA2dKWLoTlob/XO2VNc30Q3g9DmxNBmokVTrmibkn/dy9bw8hfosQQ==", + "license": "LICENSE IN LICENSE", + "dependencies": { + "@launchql/protobufjs": "7.2.6", + "@pgsql/types": "^17.6.0" + } + }, + "node_modules/@pgsql/quotes": { + "version": "17.1.0", + "resolved": "https://registry.npmjs.org/@pgsql/quotes/-/quotes-17.1.0.tgz", + "integrity": "sha512-J/H+LcrENBpYgL45WW6aTjb5Yk4tX4+AmB2/k8KZa+Zh3wiCtqmNIag+HZz5HmWaF6EZK9ZGC95NBD1fs+rUvg==", + "license": "MIT" + }, + "node_modules/@pgsql/traverse": { + "version": "17.2.4", + "resolved": "https://registry.npmjs.org/@pgsql/traverse/-/traverse-17.2.4.tgz", + "integrity": "sha512-7dnst2U3qXXSFbS+HvVktW/C4aVKe/niaRxZ1cfhmdy9E7SMYM0OukFO7gvoZb6I3dnKm/eTfpv23JPKq5z6DA==", + "license": "MIT", + "dependencies": { + "@pgsql/types": "^17.6.2", + "pg-proto-parser": "1.30.4" + } + }, + "node_modules/@pgsql/types": { + "version": "17.6.2", + "resolved": "https://registry.npmjs.org/@pgsql/types/-/types-17.6.2.tgz", + "integrity": "sha512-1UtbELdbqNdyOShhrVfSz3a1gDi0s9XXiQemx+6QqtsrXe62a6zOGU+vjb2GRfG5jeEokI1zBBcfD42enRv0Rw==", + "license": "MIT" + }, + "node_modules/@protobufjs/aspromise": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", + "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/base64": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", + "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/codegen": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", + "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/eventemitter": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", + "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/fetch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", + "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==", + "license": "BSD-3-Clause", + "dependencies": { + "@protobufjs/aspromise": "^1.1.1", + "@protobufjs/inquire": "^1.1.0" + } + }, + "node_modules/@protobufjs/float": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", + "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/inquire": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", + "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/path": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", + "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/pool": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", + "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/utf8": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", + "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==", + "license": "BSD-3-Clause" + }, + "node_modules/@stricli/core": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@stricli/core/-/core-1.2.6.tgz", + "integrity": "sha512-j5fa1wyOLrP9WJqqLFEJeQviqb3cK46K+FXTuISEkG/H5C820YfKDoVQ3CDVdM5WLhEx1ARdpiW6+hU4tYHjCQ==", + "license": "Apache-2.0" + }, + "node_modules/@supabase/pg-delta": { + "version": "1.0.0-alpha.4", + "resolved": "https://pkg.pr.new/supabase/pg-toolbelt/@supabase/pg-delta@f56ff1e", + "integrity": "sha512-NnDNTPDm8bGZtF/hIK6omIya7Xwe/NNaR4wRrxEv5m8KeVvH418cXkij1TCEWj2k39MOCLggqPzENcWYPCGMxQ==", + "license": "MIT", + "dependencies": { + "@stricli/core": "^1.2.4", + "@supabase/pg-topo": "https://pkg.pr.new/supabase/pg-toolbelt/@supabase/pg-topo@f56ff1e5c4ab379aaf8b3b2fe3f26a1d0a4f0621", + "@ts-safeql/sql-tag": "^0.2.0", + "chalk": "^5.6.2", + "debug": "^4.3.7", + "pg": "^8.17.2", + "zod": "^4.2.1" + }, + "bin": { + "pgdelta": "dist/cli/bin/cli.js" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@supabase/pg-topo": { + "version": "1.0.0-alpha.0", + "resolved": "https://pkg.pr.new/supabase/pg-toolbelt/@supabase/pg-topo@f56ff1e5c4ab379aaf8b3b2fe3f26a1d0a4f0621", + "integrity": "sha512-JMG0wmfZzF5H5lwK89c7Q68qfMHFI8GBMZEJqdaghHRqO00ZAztMAQaJuVdxJJg4hSZ2tpVNuEDCAq+4669chQ==", + "license": "MIT", + "dependencies": { + "@pgsql/traverse": "^17.2.4", + "plpgsql-parser": "^0.5.4" + } + }, + "node_modules/@ts-safeql/sql-tag": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/@ts-safeql/sql-tag/-/sql-tag-0.2.1.tgz", + "integrity": "sha512-TaDtQjobByWIn95dM2H2ucltJyL8w2B9mZdr6/1o1ZdbLRLS16XqzY6ssWkviHomQwIxB+CfK3Qz5a6AHDswsA==", + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "25.3.3", + "resolved": "https://registry.npmjs.org/@types/node/-/node-25.3.3.tgz", + "integrity": "sha512-DpzbrH7wIcBaJibpKo9nnSQL0MTRdnWttGyE5haGwK86xgMOkFLp7vEyfQPGLOJh5wNYiJ3V9PmUMDhV9u8kkQ==", + "license": "MIT", + "dependencies": { + "undici-types": "~7.18.0" + } + }, + "node_modules/agent-base": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", + "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14" + } + }, + "node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", + "license": "MIT", + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/bin-links": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/bin-links/-/bin-links-6.0.0.tgz", + "integrity": "sha512-X4CiKlcV2GjnCMwnKAfbVWpHa++65th9TuzAEYtZoATiOE2DQKhSp4CJlyLoTqdhBKlXjpXjCTYPNNFS33Fi6w==", + "dev": true, + "license": "ISC", + "dependencies": { + "cmd-shim": "^8.0.0", + "npm-normalize-package-bin": "^5.0.0", + "proc-log": "^6.0.0", + "read-cmd-shim": "^6.0.0", + "write-file-atomic": "^7.0.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/brace-expansion": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.4.tgz", + "integrity": "sha512-h+DEnpVvxmfVefa4jFbCf5HdH5YMDXRsmKflpf1pILZWRFlTbJpxeU55nJl4Smt5HQaGzg1o6RHFPJaOqnmBDg==", + "license": "MIT", + "dependencies": { + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/case": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/case/-/case-1.6.3.tgz", + "integrity": "sha512-mzDSXIPaFwVDvZAHqZ9VlbyF4yyXRuX6IvB06WvPYkqJVO24kX1PPhv9bfpKNFZyxYFmmgo03HUiD8iklmJYRQ==", + "license": "(MIT OR GPL-3.0-or-later)", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/chalk": { + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz", + "integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==", + "license": "MIT", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/chownr": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-3.0.0.tgz", + "integrity": "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=18" + } + }, + "node_modules/cmd-shim": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/cmd-shim/-/cmd-shim-8.0.0.tgz", + "integrity": "sha512-Jk/BK6NCapZ58BKUxlSI+ouKRbjH1NLZCgJkYoab+vEHUY3f6OzpNBN9u7HFSv9J6TRDGs4PLOHezoKGaFRSCA==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/data-uri-to-buffer": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz", + "integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 12" + } + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/deepmerge": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fetch-blob": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz", + "integrity": "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/jimmywarting" + }, + { + "type": "paypal", + "url": "https://paypal.me/jimmywarting" + } + ], + "license": "MIT", + "dependencies": { + "node-domexception": "^1.0.0", + "web-streams-polyfill": "^3.0.3" + }, + "engines": { + "node": "^12.20 || >= 14.13" + } + }, + "node_modules/formdata-polyfill": { + "version": "4.0.10", + "resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz", + "integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fetch-blob": "^3.1.2" + }, + "engines": { + "node": ">=12.20.0" + } + }, + "node_modules/https-proxy-agent": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", + "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, + "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==", + "license": "MIT" + }, + "node_modules/jsesc": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", + "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", + "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/long": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/long/-/long-5.3.2.tgz", + "integrity": "sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==", + "license": "Apache-2.0" + }, + "node_modules/minimatch": { + "version": "10.2.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.4.tgz", + "integrity": "sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg==", + "license": "BlueOak-1.0.0", + "dependencies": { + "brace-expansion": "^5.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/minipass": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.3.tgz", + "integrity": "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/minizlib": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-3.1.0.tgz", + "integrity": "sha512-KZxYo1BUkWD2TVFLr0MQoM8vUUigWD3LlD83a/75BqC+4qE0Hb1Vo5v1FgcfaNXvfXzr+5EhQ6ing/CaBijTlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "minipass": "^7.1.2" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, + "node_modules/nested-obj": { + "version": "0.1.10", + "resolved": "https://registry.npmjs.org/nested-obj/-/nested-obj-0.1.10.tgz", + "integrity": "sha512-5V2kUPrBee/tmoS2p0IJ35BcaJuW1p1yXF5GP8JpXIkDoPbaYeYypAHizUeZkAUxcC7Rago7izWmEq7qa8+Mhw==", + "license": "MIT" + }, + "node_modules/node-domexception": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", + "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==", + "deprecated": "Use your platform's native DOMException instead", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/jimmywarting" + }, + { + "type": "github", + "url": "https://paypal.me/jimmywarting" + } + ], + "license": "MIT", + "engines": { + "node": ">=10.5.0" + } + }, + "node_modules/node-fetch": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz", + "integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==", + "dev": true, + "license": "MIT", + "dependencies": { + "data-uri-to-buffer": "^4.0.0", + "fetch-blob": "^3.1.4", + "formdata-polyfill": "^4.0.10" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/node-fetch" + } + }, + "node_modules/npm-normalize-package-bin": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-5.0.0.tgz", + "integrity": "sha512-CJi3OS4JLsNMmr2u07OJlhcrPxCeOeP/4xq67aWNai6TNWWbTrlNDgl8NcFKVlcBKp18GPj+EzbNIgrBfZhsag==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/pg": { + "version": "8.19.0", + "resolved": "https://registry.npmjs.org/pg/-/pg-8.19.0.tgz", + "integrity": "sha512-QIcLGi508BAHkQ3pJNptsFz5WQMlpGbuBGBaIaXsWK8mel2kQ/rThYI+DbgjUvZrIr7MiuEuc9LcChJoEZK1xQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "pg-connection-string": "^2.11.0", + "pg-pool": "^3.12.0", + "pg-protocol": "^1.12.0", + "pg-types": "2.2.0", + "pgpass": "1.0.5" + }, + "engines": { + "node": ">= 16.0.0" + }, + "optionalDependencies": { + "pg-cloudflare": "^1.3.0" + }, + "peerDependencies": { + "pg-native": ">=3.0.1" + }, + "peerDependenciesMeta": { + "pg-native": { + "optional": true + } + } + }, + "node_modules/pg-cloudflare": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/pg-cloudflare/-/pg-cloudflare-1.3.0.tgz", + "integrity": "sha512-6lswVVSztmHiRtD6I8hw4qP/nDm1EJbKMRhf3HCYaqud7frGysPv7FYJ5noZQdhQtN2xJnimfMtvQq21pdbzyQ==", + "license": "MIT", + "optional": true + }, + "node_modules/pg-connection-string": { + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.11.0.tgz", + "integrity": "sha512-kecgoJwhOpxYU21rZjULrmrBJ698U2RxXofKVzOn5UDj61BPj/qMb7diYUR1nLScCDbrztQFl1TaQZT0t1EtzQ==", + "license": "MIT" + }, + "node_modules/pg-int8": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/pg-int8/-/pg-int8-1.0.1.tgz", + "integrity": "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==", + "license": "ISC", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/pg-pool": { + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.12.0.tgz", + "integrity": "sha512-eIJ0DES8BLaziFHW7VgJEBPi5hg3Nyng5iKpYtj3wbcAUV9A1wLgWiY7ajf/f/oO1wfxt83phXPY8Emztg7ITg==", + "license": "MIT", + "peerDependencies": { + "pg": ">=8.0" + } + }, + "node_modules/pg-proto-parser": { + "version": "1.30.4", + "resolved": "https://registry.npmjs.org/pg-proto-parser/-/pg-proto-parser-1.30.4.tgz", + "integrity": "sha512-+9/n8zfYQVNRc8KGhxxNXO8NA5OKni01IPtit6+C3sLMtcRVVFCj4W0XtrEGFivNjz2qwUtFmRhG8OGMTxs6hg==", + "license": "MIT", + "dependencies": { + "@babel/generator": "^7.23.6", + "@babel/parser": "^7.23.6", + "@babel/traverse": "7.28.5", + "@babel/types": "7.28.5", + "@launchql/protobufjs": "7.2.6", + "case": "1.6.3", + "deepmerge": "4.3.1", + "nested-obj": "^0.1.5", + "strfy-js": "^3.1.5" + } + }, + "node_modules/pg-protocol": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.12.0.tgz", + "integrity": "sha512-uOANXNRACNdElMXJ0tPz6RBM0XQ61nONGAwlt8da5zs/iUOOCLBQOHSXnrC6fMsvtjxbOJrZZl5IScGv+7mpbg==", + "license": "MIT" + }, + "node_modules/pg-types": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/pg-types/-/pg-types-2.2.0.tgz", + "integrity": "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==", + "license": "MIT", + "dependencies": { + "pg-int8": "1.0.1", + "postgres-array": "~2.0.0", + "postgres-bytea": "~1.0.0", + "postgres-date": "~1.0.4", + "postgres-interval": "^1.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/pgpass": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/pgpass/-/pgpass-1.0.5.tgz", + "integrity": "sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug==", + "license": "MIT", + "dependencies": { + "split2": "^4.1.0" + } + }, + "node_modules/pgsql-deparser": { + "version": "17.18.0", + "resolved": "https://registry.npmjs.org/pgsql-deparser/-/pgsql-deparser-17.18.0.tgz", + "integrity": "sha512-LFjdKKYHVo8lUPbOVfO6dRm5L28hBrfqnBrX3DhiC97k6Hsbi+7LXzvL30gahLUbN5dLai9MvsJ8Gbg/7joD1Q==", + "license": "MIT", + "dependencies": { + "@pgsql/quotes": "17.1.0", + "@pgsql/types": "^17.6.2" + } + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "license": "ISC" + }, + "node_modules/plpgsql-deparser": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/plpgsql-deparser/-/plpgsql-deparser-0.7.4.tgz", + "integrity": "sha512-XXCOVEUI1G+Teg1oZE6ZfSJqNSRKbei/7bVcc1uwQEWc2LxOk1Y6NN+UQQulnwLz0nvKueHrMAyL8/aam2fMWg==", + "license": "MIT", + "dependencies": { + "@pgsql/types": "^17.6.2", + "pgsql-deparser": "17.18.0" + } + }, + "node_modules/plpgsql-parser": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/plpgsql-parser/-/plpgsql-parser-0.5.5.tgz", + "integrity": "sha512-HgWqHTaOKiyNkO5EhpO7kugWYNmpgcCB6EJKlYm+wPiWpHTwpG52/3gGqm9NyAJ3kH0p1M4cBecNA7dDepmVgg==", + "license": "MIT", + "dependencies": { + "@libpg-query/parser": "^17.6.3", + "@pgsql/traverse": "17.2.4", + "@pgsql/types": "^17.6.2", + "pgsql-deparser": "17.18.0", + "plpgsql-deparser": "0.7.4" + } + }, + "node_modules/postgres-array": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz", + "integrity": "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/postgres-bytea": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.1.tgz", + "integrity": "sha512-5+5HqXnsZPE65IJZSMkZtURARZelel2oXUEO8rH83VS/hxH5vv1uHquPg5wZs8yMAfdv971IU+kcPUczi7NVBQ==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postgres-date": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-1.0.7.tgz", + "integrity": "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postgres-interval": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-1.2.0.tgz", + "integrity": "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==", + "license": "MIT", + "dependencies": { + "xtend": "^4.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/proc-log": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-6.1.0.tgz", + "integrity": "sha512-iG+GYldRf2BQ0UDUAd6JQ/RwzaQy6mXmsk/IzlYyal4A4SNFw54MeH4/tLkF4I5WoWG9SQwuqWzS99jaFQHBuQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/read-cmd-shim": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/read-cmd-shim/-/read-cmd-shim-6.0.0.tgz", + "integrity": "sha512-1zM5HuOfagXCBWMN83fuFI/x+T/UhZ7k+KIzhrHXcQoeX5+7gmaDYjELQHmmzIodumBHeByBJT4QYS7ufAgs7A==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/split2": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", + "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==", + "license": "ISC", + "engines": { + "node": ">= 10.x" + } + }, + "node_modules/strfy-js": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/strfy-js/-/strfy-js-3.2.1.tgz", + "integrity": "sha512-HSw2lkUJVPZ75I+E3HM7UqHMKvBCwjRt1MIAxPPNtLFjuqCrnDVKQQGfotdj/3qHxuhB6NDQ1rYmNjVpPBiNEA==", + "license": "MIT", + "dependencies": { + "minimatch": "^10.1.1" + } + }, + "node_modules/supabase": { + "version": "2.76.16", + "resolved": "https://registry.npmjs.org/supabase/-/supabase-2.76.16.tgz", + "integrity": "sha512-hZ1Kg88+pOlSAzvpas5RYLW6Op6a1OTUhOm8weP8vJf0emE/GO8rrou57irL3hopOwwSnye19VnxplW5+3g1zA==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "bin-links": "^6.0.0", + "https-proxy-agent": "^7.0.2", + "node-fetch": "^3.3.2", + "tar": "7.5.9" + }, + "bin": { + "supabase": "bin/supabase" + }, + "engines": { + "npm": ">=8" + } + }, + "node_modules/tar": { + "version": "7.5.9", + "resolved": "https://registry.npmjs.org/tar/-/tar-7.5.9.tgz", + "integrity": "sha512-BTLcK0xsDh2+PUe9F6c2TlRp4zOOBMTkoQHQIWSIzI0R7KG46uEwq4OPk2W7bZcprBMsuaeFsqwYr7pjh6CuHg==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/fs-minipass": "^4.0.0", + "chownr": "^3.0.0", + "minipass": "^7.1.2", + "minizlib": "^3.1.0", + "yallist": "^5.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/undici-types": { + "version": "7.18.2", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.18.2.tgz", + "integrity": "sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w==", + "license": "MIT" + }, + "node_modules/web-streams-polyfill": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz", + "integrity": "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/write-file-atomic": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-7.0.1.tgz", + "integrity": "sha512-OTIk8iR8/aCRWBqvxrzxR0hgxWpnYBblY1S5hDWBQfk/VFmJwzmJgQFN3WsoUKHISv2eAwe+PpbUzyL1CKTLXg==", + "dev": true, + "license": "ISC", + "dependencies": { + "signal-exit": "^4.0.1" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "license": "MIT", + "engines": { + "node": ">=0.4" + } + }, + "node_modules/yallist": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-5.0.0.tgz", + "integrity": "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=18" + } + }, + "node_modules/zod": { + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/zod/-/zod-4.3.6.tgz", + "integrity": "sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 00000000..5fcbd903 --- /dev/null +++ b/package.json @@ -0,0 +1,9 @@ +{ + "private": true, + "dependencies": { + "@supabase/pg-delta": "https://pkg.pr.new/supabase/pg-toolbelt/@supabase/pg-delta@f56ff1e" + }, + "devDependencies": { + "supabase": "^2.76.16" + } +} diff --git a/scripts/declarative-dbdev-init.sh b/scripts/declarative-dbdev-init.sh new file mode 100755 index 00000000..3f0ddd83 --- /dev/null +++ b/scripts/declarative-dbdev-init.sh @@ -0,0 +1,143 @@ +#!/bin/bash +set -e + +# ────────────────────────────────────────────────────────────── +# declarative-dbdev-init.sh +# +# Initializes a declarative schema from the dbdev supabase project. +# 1. Starts a shadow DB (supabase/postgres image) for the baseline +# 2. Snapshots the clean baseline catalog +# 3. Starts the dbdev supabase project (applies all migrations) +# 4. Exports the declarative schema (diff: baseline → supabase DB) +# 5. Verifies roundtrip: apply to fresh shadow DB, then diff +# +# Run from the dbdev repo root so npx pgdelta resolves from node_modules: +# bash scripts/declarative-dbdev-init.sh +# ────────────────────────────────────────────────────────────── + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +DBDEV_DIR="${DBDEV_DIR:-${SCRIPT_DIR}/..}" + +SHADOW_IMAGE="${SHADOW_IMAGE:-supabase/postgres:15.8.1.085}" +SHADOW_CONTAINER="pgdelta-dbdev-shadow" +SHADOW_PORT="${SHADOW_PORT:-6544}" +SHADOW_URL="postgres://postgres:postgres@localhost:${SHADOW_PORT}/postgres" + +SUPABASE_DB_PORT=54322 +SUPABASE_DB_URL="postgres://postgres:postgres@localhost:${SUPABASE_DB_PORT}/postgres" + +PGDELTA="${PGDELTA:-npx pgdelta}" +OUTPUT_DIR="${OUTPUT_DIR:-${DBDEV_DIR}/declarative-schemas}" +BASELINE_SNAPSHOT="${BASELINE_SNAPSHOT:-${DBDEV_DIR}/baseline-catalog.json}" +SKIP_SUPABASE_START="${SKIP_SUPABASE_START:-}" +SKIP_VERIFY="${SKIP_VERIFY:-}" + +FORMAT_OPTIONS='{"keywordCase":"lower","maxWidth":180,"indent":4}' + +cleanup_shadow() { + echo "Cleaning up shadow container..." + docker rm -f "$SHADOW_CONTAINER" >/dev/null 2>&1 || true + rm -f "$BASELINE_SNAPSHOT" +} + +start_shadow() { + echo "Starting shadow DB (${SHADOW_IMAGE}) on port ${SHADOW_PORT}..." + docker rm -f "$SHADOW_CONTAINER" 2>/dev/null || true + docker run -d --name "$SHADOW_CONTAINER" \ + -e POSTGRES_PASSWORD=postgres \ + -p "${SHADOW_PORT}:5432" \ + "$SHADOW_IMAGE" + + echo "Waiting for shadow DB to be ready..." + until docker exec "$SHADOW_CONTAINER" pg_isready -U postgres 2>/dev/null; do + sleep 1 + done + sleep 3 +} + +# ────────────────────────────────────────────────────────────── +# 1. Start shadow DB and snapshot baseline +# ────────────────────────────────────────────────────────────── +start_shadow + +echo "Snapshotting clean shadow DB as catalog baseline..." +$PGDELTA catalog-export --target "$SHADOW_URL" --output "$BASELINE_SNAPSHOT" + +# ────────────────────────────────────────────────────────────── +# 2. Start the dbdev supabase project +# ────────────────────────────────────────────────────────────── +if [ -z "$SKIP_SUPABASE_START" ]; then + echo "Starting dbdev supabase project..." + (cd "$DBDEV_DIR" && supabase start) +else + echo "Skipping supabase start (SKIP_SUPABASE_START is set)." + echo "Checking supabase DB is reachable..." + until pg_isready -h localhost -p "$SUPABASE_DB_PORT" -U postgres 2>/dev/null; do + echo " Waiting for supabase DB on port ${SUPABASE_DB_PORT}..." + sleep 2 + done +fi + +# ────────────────────────────────────────────────────────────── +# 3. Export declarative schema (baseline → supabase DB) +# ────────────────────────────────────────────────────────────── +EXPORT_OPTS=( + --source "$BASELINE_SNAPSHOT" + --target "$SUPABASE_DB_URL" + --output "$OUTPUT_DIR" + --integration supabase + --force + --format-options "$FORMAT_OPTIONS" +) + +echo "Exporting declarative schema..." +$PGDELTA declarative export "${EXPORT_OPTS[@]}" + +# ────────────────────────────────────────────────────────────── +# 4. Verify roundtrip: apply to fresh shadow DB, then diff +# ────────────────────────────────────────────────────────────── +if [ -z "$SKIP_VERIFY" ]; then + echo "" + echo "=== Roundtrip verification ===" + + echo "Resetting shadow DB for verification..." + docker rm -f "$SHADOW_CONTAINER" >/dev/null 2>&1 + start_shadow + + echo "Applying declarative schema to shadow DB..." + $PGDELTA declarative apply \ + --path "$OUTPUT_DIR" \ + --target "$SHADOW_URL" \ + --verbose + + echo "Verifying roundtrip: diff shadow DB vs supabase DB (expect 0 changes)..." + VERIFY_OPTS=( + --source "$SHADOW_URL" + --target "$SUPABASE_DB_URL" + --integration supabase + ) + VERIFY_OUTPUT=$($PGDELTA plan "${VERIFY_OPTS[@]}" 2>&1) || true + + if echo "$VERIFY_OUTPUT" | grep -q "No changes detected."; then + echo "Verification PASSED: 0 changes (declarative schema roundtrip OK)." + else + echo "$VERIFY_OUTPUT" + echo "" + echo "Writing full diff for debugging..." + $PGDELTA plan "${VERIFY_OPTS[@]}" --format sql || true + echo "" + echo "Verification FAILED: diff reported changes after roundtrip." + cleanup_shadow + exit 1 + fi +else + echo "Skipping verification (SKIP_VERIFY is set)." +fi + +# ────────────────────────────────────────────────────────────── +# 5. Cleanup +# ────────────────────────────────────────────────────────────── +cleanup_shadow +echo "" +echo "Done. Declarative schema written to: ${OUTPUT_DIR}" +echo "Supabase project is still running (use 'cd ${DBDEV_DIR} && supabase stop' to stop)." diff --git a/scripts/declarative-dbdev-update.sh b/scripts/declarative-dbdev-update.sh new file mode 100755 index 00000000..63cdee4c --- /dev/null +++ b/scripts/declarative-dbdev-update.sh @@ -0,0 +1,177 @@ +#!/bin/bash +set -e + +# ────────────────────────────────────────────────────────────── +# declarative-dbdev-update.sh +# +# After editing declarative schema files, this script: +# 1. Starts a shadow DB (supabase/postgres image) +# 2. Applies the declarative schema to the shadow DB (desired state) +# 3. Diffs the running supabase DB against the shadow DB +# 4. Generates a migration file from the diff +# 5. Applies the migration to the supabase project DB +# 6. Verifies the roundtrip (expect 0 remaining changes) +# +# Run from the dbdev repo root so npx pgdelta resolves from node_modules: +# MIGRATION_NAME=my_change bash scripts/declarative-dbdev-update.sh +# ────────────────────────────────────────────────────────────── + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +DBDEV_DIR="${DBDEV_DIR:-${SCRIPT_DIR}/..}" + +SHADOW_IMAGE="${SHADOW_IMAGE:-supabase/postgres:15.6.1.143}" +SHADOW_CONTAINER="pgdelta-dbdev-shadow" +SHADOW_PORT="${SHADOW_PORT:-6544}" +SHADOW_URL="postgres://postgres:postgres@localhost:${SHADOW_PORT}/postgres" + +SUPABASE_DB_PORT=54322 +SUPABASE_DB_URL="postgres://postgres:postgres@localhost:${SUPABASE_DB_PORT}/postgres" + +PGDELTA="${PGDELTA:-npx pgdelta}" +OUTPUT_DIR="${OUTPUT_DIR:-${DBDEV_DIR}/declarative-schemas}" +MIGRATION_NAME="${MIGRATION_NAME:-declarative_update}" +SKIP_APPLY="${SKIP_APPLY:-}" +SKIP_VERIFY="${SKIP_VERIFY:-}" + +MIGRATIONS_DIR="${DBDEV_DIR}/supabase/migrations" + +cleanup_shadow() { + echo "Cleaning up shadow container..." + docker rm -f "$SHADOW_CONTAINER" >/dev/null 2>&1 || true +} + +# ────────────────────────────────────────────────────────────── +# 0. Pre-flight checks +# ────────────────────────────────────────────────────────────── +if [ ! -d "$OUTPUT_DIR" ]; then + echo "Error: Declarative schema directory not found at ${OUTPUT_DIR}" + echo "Run declarative-dbdev-init.sh first." + exit 1 +fi + +echo "Checking supabase DB is reachable on port ${SUPABASE_DB_PORT}..." +if ! pg_isready -h localhost -p "$SUPABASE_DB_PORT" -U postgres 2>/dev/null; then + echo "Error: Supabase DB is not running on port ${SUPABASE_DB_PORT}." + echo "Start the dbdev project first: cd ${DBDEV_DIR} && supabase start" + exit 1 +fi + +# ────────────────────────────────────────────────────────────── +# 1. Start shadow DB +# ────────────────────────────────────────────────────────────── +echo "Starting shadow DB (${SHADOW_IMAGE}) on port ${SHADOW_PORT}..." +docker rm -f "$SHADOW_CONTAINER" 2>/dev/null || true +docker run -d --name "$SHADOW_CONTAINER" \ + -e POSTGRES_PASSWORD=postgres \ + -p "${SHADOW_PORT}:5432" \ + "$SHADOW_IMAGE" + +echo "Waiting for shadow DB to be ready..." +until docker exec "$SHADOW_CONTAINER" pg_isready -U postgres 2>/dev/null; do + sleep 1 +done +sleep 3 + +# ────────────────────────────────────────────────────────────── +# 2. Apply declarative schema to shadow DB (desired state) +# ────────────────────────────────────────────────────────────── +echo "Applying declarative schema to shadow DB..." +$PGDELTA declarative apply \ + --path "$OUTPUT_DIR" \ + --target "$SHADOW_URL" \ + --verbose + +# ────────────────────────────────────────────────────────────── +# 3. Generate migration: diff supabase DB → shadow DB +# ────────────────────────────────────────────────────────────── +TIMESTAMP=$(date +%Y%m%d%H%M%S) +MIGRATION_FILE="${MIGRATIONS_DIR}/${TIMESTAMP}_${MIGRATION_NAME}.sql" +TMP_MIGRATION="/tmp/pgdelta-dbdev-migration-${TIMESTAMP}.sql" + +echo "Generating migration (supabase DB → shadow DB)..." +rm -f "$TMP_MIGRATION" +PLAN_EXIT=0 +$PGDELTA plan \ + --source "$SUPABASE_DB_URL" \ + --target "$SHADOW_URL" \ + --integration supabase \ + --format sql \ + --output "$TMP_MIGRATION" || PLAN_EXIT=$? + +if [ "$PLAN_EXIT" -ne 0 ] && [ "$PLAN_EXIT" -ne 2 ]; then + echo "Error: pgdelta plan failed with exit code ${PLAN_EXIT}" + cleanup_shadow + exit 1 +fi + +if [ "$PLAN_EXIT" -eq 0 ]; then + echo "" + echo "No changes detected. Declarative schema matches the supabase DB." + cleanup_shadow + exit 0 +fi + +echo "" +echo "Changes detected. Migration preview:" +echo "──────────────────────────────────────" +cat "$TMP_MIGRATION" +echo "──────────────────────────────────────" +echo "" + +if [ -n "$SKIP_APPLY" ]; then + echo "Saving migration to: ${MIGRATION_FILE}" + mkdir -p "$MIGRATIONS_DIR" + mv "$TMP_MIGRATION" "$MIGRATION_FILE" + echo "Skipping apply (SKIP_APPLY is set). Apply manually with:" + echo " psql '${SUPABASE_DB_URL}' -f '${MIGRATION_FILE}'" + cleanup_shadow + exit 0 +fi + +# ────────────────────────────────────────────────────────────── +# 4. Save and apply migration to supabase DB +# ────────────────────────────────────────────────────────────── +echo "Saving migration to: ${MIGRATION_FILE}" +mkdir -p "$MIGRATIONS_DIR" +mv "$TMP_MIGRATION" "$MIGRATION_FILE" + +echo "Applying migration to supabase DB..." +psql "$SUPABASE_DB_URL" -f "$MIGRATION_FILE" + +# ────────────────────────────────────────────────────────────── +# 5. Verify roundtrip +# ────────────────────────────────────────────────────────────── +if [ -z "$SKIP_VERIFY" ]; then + echo "" + echo "=== Roundtrip verification ===" + echo "Verifying: diff supabase DB vs shadow DB (expect 0 changes)..." + + VERIFY_OPTS=( + --source "$SUPABASE_DB_URL" + --target "$SHADOW_URL" + --integration supabase + ) + VERIFY_OUTPUT=$($PGDELTA plan "${VERIFY_OPTS[@]}" 2>&1) || true + + if echo "$VERIFY_OUTPUT" | grep -q "No changes detected."; then + echo "Verification PASSED: 0 changes after migration." + else + echo "$VERIFY_OUTPUT" + echo "" + echo "Writing full diff for debugging..." + $PGDELTA plan "${VERIFY_OPTS[@]}" --format sql || true + echo "" + echo "Verification FAILED: diff still reports changes after applying migration." + cleanup_shadow + exit 1 + fi +else + echo "Skipping verification (SKIP_VERIFY is set)." +fi + +# ────────────────────────────────────────────────────────────── +# 6. Cleanup +# ────────────────────────────────────────────────────────────── +cleanup_shadow +echo "" +echo "Done. Migration applied: ${MIGRATION_FILE}" From 185b49f7bd506e1ac5724caed79e82cafea15485 Mon Sep 17 00:00:00 2001 From: avallete Date: Wed, 4 Mar 2026 19:55:23 +0100 Subject: [PATCH 2/3] wip: pg-delta and declarative schema --- .../cluster/extensions/citext.sql | 1 - .../cluster/extensions/pg_cron.sql | 1 - .../cluster/extensions/pg_net.sql | 1 - .../cluster/extensions/pg_trgm.sql | 1 - .../schemas/app/domains/email_address.sql | 4 - .../schemas/app/domains/semver.sql | 2 - .../schemas/app/domains/valid_name.sql | 2 - .../schemas/app/functions/exception.sql | 10 - .../app/functions/is_handle_maintainer.sql | 31 - .../functions/is_organization_maintainer.sql | 21 - .../app/functions/is_package_maintainer.sql | 36 - .../is_package_version_maintainer.sql | 15 - .../schemas/app/functions/is_valid.sql | 13 - .../app/functions/register_account.sql | 23 - ...egister_organization_creator_as_member.sql | 12 - .../app/functions/semver_exception.sql | 11 - .../schemas/app/functions/semver_to_text.sql | 10 - .../schemas/app/functions/simulate_login.sql | 30 - .../schemas/app/functions/text_to_semver.sql | 23 - .../schemas/app/functions/to_package_name.sql | 10 - .../app/functions/update_avatar_id.sql | 32 - .../app/functions/version_text_to_handle.sql | 9 - .../version_text_to_package_partial_name.sql | 9 - declarative-schemas/schemas/app/schema.sql | 9 - .../schemas/app/tables/accounts.sql | 41 - .../schemas/app/tables/handle_registry.sql | 13 - .../schemas/app/tables/members.sql | 31 - .../schemas/app/tables/organizations.sql | 50 - .../schemas/app/tables/package_upgrades.sql | 28 - .../schemas/app/tables/package_versions.sql | 27 - .../schemas/app/tables/packages.sql | 33 - .../schemas/app/types/membership_role.sql | 3 - .../schemas/app/types/semver_struct.sql | 5 - .../public/functions/search_packages.sql | 18 - .../schemas/public/views/accounts.sql | 9 - .../schemas/public/views/members.sql | 5 - .../schemas/public/views/organizations.sql | 9 - .../schemas/public/views/package_upgrades.sql | 9 - .../schemas/public/views/package_versions.sql | 11 - .../schemas/public/views/packages.sql | 21 - docs/declarative-schema.md | 21 + package-lock.json | 1130 +++++++---------- package.json | 2 +- scripts/declarative-dbdev-init.sh | 7 +- scripts/declarative-dbdev-update.sh | 2 +- 45 files changed, 503 insertions(+), 1288 deletions(-) delete mode 100644 declarative-schemas/cluster/extensions/citext.sql delete mode 100644 declarative-schemas/cluster/extensions/pg_cron.sql delete mode 100644 declarative-schemas/cluster/extensions/pg_net.sql delete mode 100644 declarative-schemas/cluster/extensions/pg_trgm.sql delete mode 100644 declarative-schemas/schemas/app/domains/email_address.sql delete mode 100644 declarative-schemas/schemas/app/domains/semver.sql delete mode 100644 declarative-schemas/schemas/app/domains/valid_name.sql delete mode 100644 declarative-schemas/schemas/app/functions/exception.sql delete mode 100644 declarative-schemas/schemas/app/functions/is_handle_maintainer.sql delete mode 100644 declarative-schemas/schemas/app/functions/is_organization_maintainer.sql delete mode 100644 declarative-schemas/schemas/app/functions/is_package_maintainer.sql delete mode 100644 declarative-schemas/schemas/app/functions/is_package_version_maintainer.sql delete mode 100644 declarative-schemas/schemas/app/functions/is_valid.sql delete mode 100644 declarative-schemas/schemas/app/functions/register_account.sql delete mode 100644 declarative-schemas/schemas/app/functions/register_organization_creator_as_member.sql delete mode 100644 declarative-schemas/schemas/app/functions/semver_exception.sql delete mode 100644 declarative-schemas/schemas/app/functions/semver_to_text.sql delete mode 100644 declarative-schemas/schemas/app/functions/simulate_login.sql delete mode 100644 declarative-schemas/schemas/app/functions/text_to_semver.sql delete mode 100644 declarative-schemas/schemas/app/functions/to_package_name.sql delete mode 100644 declarative-schemas/schemas/app/functions/update_avatar_id.sql delete mode 100644 declarative-schemas/schemas/app/functions/version_text_to_handle.sql delete mode 100644 declarative-schemas/schemas/app/functions/version_text_to_package_partial_name.sql delete mode 100644 declarative-schemas/schemas/app/schema.sql delete mode 100644 declarative-schemas/schemas/app/tables/accounts.sql delete mode 100644 declarative-schemas/schemas/app/tables/handle_registry.sql delete mode 100644 declarative-schemas/schemas/app/tables/members.sql delete mode 100644 declarative-schemas/schemas/app/tables/organizations.sql delete mode 100644 declarative-schemas/schemas/app/tables/package_upgrades.sql delete mode 100644 declarative-schemas/schemas/app/tables/package_versions.sql delete mode 100644 declarative-schemas/schemas/app/tables/packages.sql delete mode 100644 declarative-schemas/schemas/app/types/membership_role.sql delete mode 100644 declarative-schemas/schemas/app/types/semver_struct.sql delete mode 100644 declarative-schemas/schemas/public/functions/search_packages.sql delete mode 100644 declarative-schemas/schemas/public/views/accounts.sql delete mode 100644 declarative-schemas/schemas/public/views/members.sql delete mode 100644 declarative-schemas/schemas/public/views/organizations.sql delete mode 100644 declarative-schemas/schemas/public/views/package_upgrades.sql delete mode 100644 declarative-schemas/schemas/public/views/package_versions.sql delete mode 100644 declarative-schemas/schemas/public/views/packages.sql diff --git a/declarative-schemas/cluster/extensions/citext.sql b/declarative-schemas/cluster/extensions/citext.sql deleted file mode 100644 index 62369b5d..00000000 --- a/declarative-schemas/cluster/extensions/citext.sql +++ /dev/null @@ -1 +0,0 @@ -create extension citext with schema extensions; \ No newline at end of file diff --git a/declarative-schemas/cluster/extensions/pg_cron.sql b/declarative-schemas/cluster/extensions/pg_cron.sql deleted file mode 100644 index a423154e..00000000 --- a/declarative-schemas/cluster/extensions/pg_cron.sql +++ /dev/null @@ -1 +0,0 @@ -create extension pg_cron with schema pg_catalog; \ No newline at end of file diff --git a/declarative-schemas/cluster/extensions/pg_net.sql b/declarative-schemas/cluster/extensions/pg_net.sql deleted file mode 100644 index c712499f..00000000 --- a/declarative-schemas/cluster/extensions/pg_net.sql +++ /dev/null @@ -1 +0,0 @@ -create extension pg_net with schema extensions; \ No newline at end of file diff --git a/declarative-schemas/cluster/extensions/pg_trgm.sql b/declarative-schemas/cluster/extensions/pg_trgm.sql deleted file mode 100644 index 085d8ac9..00000000 --- a/declarative-schemas/cluster/extensions/pg_trgm.sql +++ /dev/null @@ -1 +0,0 @@ -create extension pg_trgm with schema extensions; \ No newline at end of file diff --git a/declarative-schemas/schemas/app/domains/email_address.sql b/declarative-schemas/schemas/app/domains/email_address.sql deleted file mode 100644 index 905df469..00000000 --- a/declarative-schemas/schemas/app/domains/email_address.sql +++ /dev/null @@ -1,4 +0,0 @@ -create domain app.email_address as extensions.citext - check - ((VALUE OPERATOR(extensions.~) - '^[a-zA-Z0-9.!#$%&''*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$'::extensions.citext)); \ No newline at end of file diff --git a/declarative-schemas/schemas/app/domains/semver.sql b/declarative-schemas/schemas/app/domains/semver.sql deleted file mode 100644 index 85ec6314..00000000 --- a/declarative-schemas/schemas/app/domains/semver.sql +++ /dev/null @@ -1,2 +0,0 @@ -create domain app.semver as app.semver_struct - check (app.is_valid(VALUE)); \ No newline at end of file diff --git a/declarative-schemas/schemas/app/domains/valid_name.sql b/declarative-schemas/schemas/app/domains/valid_name.sql deleted file mode 100644 index 9492971b..00000000 --- a/declarative-schemas/schemas/app/domains/valid_name.sql +++ /dev/null @@ -1,2 +0,0 @@ -create domain app.valid_name as extensions.citext - check ((VALUE OPERATOR(extensions.~) '^[A-z][A-z0-9\_]{2,32}$'::extensions.citext)); \ No newline at end of file diff --git a/declarative-schemas/schemas/app/functions/exception.sql b/declarative-schemas/schemas/app/functions/exception.sql deleted file mode 100644 index f8142d6e..00000000 --- a/declarative-schemas/schemas/app/functions/exception.sql +++ /dev/null @@ -1,10 +0,0 @@ -create function app.exception ( - message text -) - returns text - language plpgsql - AS $function$ - begin - raise exception using errcode='22000', message=message; - end; - $function$; \ No newline at end of file diff --git a/declarative-schemas/schemas/app/functions/is_handle_maintainer.sql b/declarative-schemas/schemas/app/functions/is_handle_maintainer.sql deleted file mode 100644 index 14dfcc60..00000000 --- a/declarative-schemas/schemas/app/functions/is_handle_maintainer.sql +++ /dev/null @@ -1,31 +0,0 @@ -create function app.is_handle_maintainer ( - account_id uuid, - handle app.valid_name -) - returns boolean - language sql - stable - AS $function$ - select - exists( - select - 1 - from - app.accounts acc - where - acc.id = $1 - and acc.handle = $2 - ) - or exists( - select - 1 - from - app.organizations o - join app.members m - on o.id = m.organization_id - where - m.role = 'maintainer' - and m.account_id = $1 - and o.handle = $2 - ) -$function$; \ No newline at end of file diff --git a/declarative-schemas/schemas/app/functions/is_organization_maintainer.sql b/declarative-schemas/schemas/app/functions/is_organization_maintainer.sql deleted file mode 100644 index 01a7245d..00000000 --- a/declarative-schemas/schemas/app/functions/is_organization_maintainer.sql +++ /dev/null @@ -1,21 +0,0 @@ -create function app.is_organization_maintainer ( - account_id uuid, - organization_id uuid -) - returns boolean - language sql - stable - AS $function$ - -- Does the currently authenticated user have permission to admin orgs and org members? - select - exists( - select - 1 - from - app.members m - where - m.account_id = $1 - and m.organization_id = $2 - and m.role = 'maintainer' - ) -$function$; \ No newline at end of file diff --git a/declarative-schemas/schemas/app/functions/is_package_maintainer.sql b/declarative-schemas/schemas/app/functions/is_package_maintainer.sql deleted file mode 100644 index 4d0fd169..00000000 --- a/declarative-schemas/schemas/app/functions/is_package_maintainer.sql +++ /dev/null @@ -1,36 +0,0 @@ -create function app.is_package_maintainer ( - account_id uuid, - package_id uuid -) - returns boolean - language sql - stable - AS $function$ - select - exists( - select - 1 - from - app.accounts acc - join app.packages p - on acc.handle = p.handle - where - acc.id = $1 - and p.id = $2 - ) - or exists( - -- current user is maintainer of org that owns the package - select - 1 - from - app.packages p - join app.organizations o - on p.handle = o.handle - join app.members m - on o.id = m.organization_id - where - m.role = 'maintainer' - and m.account_id = $1 - and p.id = $2 - ) -$function$; \ No newline at end of file diff --git a/declarative-schemas/schemas/app/functions/is_package_version_maintainer.sql b/declarative-schemas/schemas/app/functions/is_package_version_maintainer.sql deleted file mode 100644 index 6e52674a..00000000 --- a/declarative-schemas/schemas/app/functions/is_package_version_maintainer.sql +++ /dev/null @@ -1,15 +0,0 @@ -create function app.is_package_version_maintainer ( - account_id uuid, - package_version_id uuid -) - returns boolean - language sql - stable - AS $function$ - select - app.is_package_maintainer($1, pv.package_id) - from - app.package_versions pv - where - pv.id = $2 -$function$; \ No newline at end of file diff --git a/declarative-schemas/schemas/app/functions/is_valid.sql b/declarative-schemas/schemas/app/functions/is_valid.sql deleted file mode 100644 index 365f31e2..00000000 --- a/declarative-schemas/schemas/app/functions/is_valid.sql +++ /dev/null @@ -1,13 +0,0 @@ -create function app.is_valid ( - app .semver_struct -) - returns boolean - language sql - immutable - AS $function$ - select ( - ($1).major is not null - and ($1).minor is not null - and ($1).patch is not null - ) -$function$; \ No newline at end of file diff --git a/declarative-schemas/schemas/app/functions/register_account.sql b/declarative-schemas/schemas/app/functions/register_account.sql deleted file mode 100644 index 4f0aacd3..00000000 --- a/declarative-schemas/schemas/app/functions/register_account.sql +++ /dev/null @@ -1,23 +0,0 @@ -create function app.register_account() - returns trigger - language plpgsql - security definer - AS $function$ - begin - insert into app.handle_registry (handle, is_organization) - values ( - new.raw_user_meta_data ->> 'handle', - false - ); - - insert into app.accounts (id, handle, display_name, bio, contact_email) - values ( - new.id, - new.raw_user_meta_data ->> 'handle', - new.raw_user_meta_data ->> 'display_name', - new.raw_user_meta_data ->> 'bio', - new.raw_user_meta_data ->> 'contact_email' - ); - return new; - end; - $function$; \ No newline at end of file diff --git a/declarative-schemas/schemas/app/functions/register_organization_creator_as_member.sql b/declarative-schemas/schemas/app/functions/register_organization_creator_as_member.sql deleted file mode 100644 index e8335c5d..00000000 --- a/declarative-schemas/schemas/app/functions/register_organization_creator_as_member.sql +++ /dev/null @@ -1,12 +0,0 @@ -create function app.register_organization_creator_as_member() - returns trigger - language plpgsql - security definer - AS $function$ - begin - insert into app.members(organization_id, account_id, role) - values (new.id, auth.uid(), 'maintainer'); - - return new; - end; - $function$; \ No newline at end of file diff --git a/declarative-schemas/schemas/app/functions/semver_exception.sql b/declarative-schemas/schemas/app/functions/semver_exception.sql deleted file mode 100644 index 31873eef..00000000 --- a/declarative-schemas/schemas/app/functions/semver_exception.sql +++ /dev/null @@ -1,11 +0,0 @@ -create function app.semver_exception ( - version text -) - returns app.semver_struct - language plpgsql - immutable - AS $function$ -begin - raise exception using errcode='22000', message=format('Invalid semver %L', version); -end; -$function$; \ No newline at end of file diff --git a/declarative-schemas/schemas/app/functions/semver_to_text.sql b/declarative-schemas/schemas/app/functions/semver_to_text.sql deleted file mode 100644 index 8915040f..00000000 --- a/declarative-schemas/schemas/app/functions/semver_to_text.sql +++ /dev/null @@ -1,10 +0,0 @@ -create function app.semver_to_text ( - app .semver -) - returns text - language sql - immutable - AS $function$ - select - format('%s.%s.%s', $1.major, $1.minor, $1.patch) -$function$; \ No newline at end of file diff --git a/declarative-schemas/schemas/app/functions/simulate_login.sql b/declarative-schemas/schemas/app/functions/simulate_login.sql deleted file mode 100644 index 04c1bada..00000000 --- a/declarative-schemas/schemas/app/functions/simulate_login.sql +++ /dev/null @@ -1,30 +0,0 @@ -create function app.simulate_login ( - email extensions.citext -) - returns void - language sql - AS $function$ - /* - Simulated JWT of logged in user - */ - - select - set_config( - 'request.jwt.claims', - ( - select - json_build_object( - 'sub', - id, - 'role', - 'authenticated' - )::text - from - auth.users - where - email = $1 - ), - true - ), - set_config('role', 'authenticated', true) -$function$; \ No newline at end of file diff --git a/declarative-schemas/schemas/app/functions/text_to_semver.sql b/declarative-schemas/schemas/app/functions/text_to_semver.sql deleted file mode 100644 index 636d5c86..00000000 --- a/declarative-schemas/schemas/app/functions/text_to_semver.sql +++ /dev/null @@ -1,23 +0,0 @@ -create function app.text_to_semver ( - text -) - returns app.semver_struct - language sql - immutable - strict - AS $function$ - with s(version) as ( - select ( - split_part($1, '.', 1), - split_part($1, '.', 2), - split_part(split_part(split_part($1, '.', 3), '-', 1), '+', 1) - )::app.semver_struct - ) - select - case app.is_valid(s.version) - when true then s.version - else app.semver_exception($1) - end - from - s -$function$; \ No newline at end of file diff --git a/declarative-schemas/schemas/app/functions/to_package_name.sql b/declarative-schemas/schemas/app/functions/to_package_name.sql deleted file mode 100644 index f6817e53..00000000 --- a/declarative-schemas/schemas/app/functions/to_package_name.sql +++ /dev/null @@ -1,10 +0,0 @@ -create function app.to_package_name ( - handle app.valid_name, - partial_name app.valid_name -) - returns text - language sql - immutable - AS $function$ - select format('%s-%s', $1, $2) -$function$; \ No newline at end of file diff --git a/declarative-schemas/schemas/app/functions/update_avatar_id.sql b/declarative-schemas/schemas/app/functions/update_avatar_id.sql deleted file mode 100644 index 3d49d7b6..00000000 --- a/declarative-schemas/schemas/app/functions/update_avatar_id.sql +++ /dev/null @@ -1,32 +0,0 @@ -create function app.update_avatar_id() - returns trigger - language plpgsql - security definer - AS $function$ - declare - v_handle app.valid_name; - v_affected_account app.accounts := null; - begin - select (string_to_array(new.name, '-'::text))[1]::app.valid_name into v_handle; - - update app.accounts - set avatar_id = new.id - where handle = v_handle - returning * into v_affected_account; - - if not v_affected_account is null then - update auth.users u - set - "raw_user_meta_data" = u.raw_user_meta_data || jsonb_build_object( - 'avatar_path', new.name - ) - where u.id = v_affected_account.id; - else - update app.organizations - set avatar_id = new.id - where handle = v_handle; - end if; - - return new; - end; - $function$; \ No newline at end of file diff --git a/declarative-schemas/schemas/app/functions/version_text_to_handle.sql b/declarative-schemas/schemas/app/functions/version_text_to_handle.sql deleted file mode 100644 index 385013cb..00000000 --- a/declarative-schemas/schemas/app/functions/version_text_to_handle.sql +++ /dev/null @@ -1,9 +0,0 @@ -create function app.version_text_to_handle ( - version text -) - returns app.valid_name - language sql - immutable - AS $function$ - select split_part($1, '-', 1) -$function$; \ No newline at end of file diff --git a/declarative-schemas/schemas/app/functions/version_text_to_package_partial_name.sql b/declarative-schemas/schemas/app/functions/version_text_to_package_partial_name.sql deleted file mode 100644 index fc30799a..00000000 --- a/declarative-schemas/schemas/app/functions/version_text_to_package_partial_name.sql +++ /dev/null @@ -1,9 +0,0 @@ -create function app.version_text_to_package_partial_name ( - version text -) - returns app.valid_name - language sql - immutable - AS $function$ - select split_part($1, '--', 2) -$function$; \ No newline at end of file diff --git a/declarative-schemas/schemas/app/schema.sql b/declarative-schemas/schemas/app/schema.sql deleted file mode 100644 index e42d98df..00000000 --- a/declarative-schemas/schemas/app/schema.sql +++ /dev/null @@ -1,9 +0,0 @@ -create schema app authorization postgres; - -alter default privileges for role postgres in schema app grant select on tables to anon; - -alter default privileges for role postgres in schema app grant select on tables to authenticated; - -grant usage on schema app to anon; - -grant usage on schema app to authenticated; \ No newline at end of file diff --git a/declarative-schemas/schemas/app/tables/accounts.sql b/declarative-schemas/schemas/app/tables/accounts.sql deleted file mode 100644 index f85f8fa0..00000000 --- a/declarative-schemas/schemas/app/tables/accounts.sql +++ /dev/null @@ -1,41 +0,0 @@ -create table app.accounts ( - id uuid not null, - handle app.valid_name not null, - is_organization boolean generated always as (false) stored, - avatar_id uuid, - display_name text, - bio text, - contact_email app.email_address, - created_at timestamp with time zone default now() not null -); - -create policy accounts_select_policy on app.accounts - for select - to authenticated - using (true); - -alter table app.accounts - enable row level security; - -alter table app.accounts - add constraint accounts_avatar_id_fkey foreign key (avatar_id) references storage.objects(id); - -alter table app.accounts - add constraint accounts_bio_check check (length(bio) <= 512); - -alter table app.accounts - add constraint accounts_display_name_check check (length(display_name) <= 128); - -alter table app.accounts - add constraint accounts_handle_key unique (handle); - -alter table app.accounts - add constraint accounts_id_fkey foreign key (id) references auth.users(id); - -alter table app.accounts - add constraint accounts_pkey primary key (id); - -alter table app.accounts - add constraint fk_handle_registry foreign key (handle, is_organization) references app.handle_registry(handle, is_organization); - -grant update (avatar_id, bio, contact_email, display_name) on app.accounts to authenticated; \ No newline at end of file diff --git a/declarative-schemas/schemas/app/tables/handle_registry.sql b/declarative-schemas/schemas/app/tables/handle_registry.sql deleted file mode 100644 index 8c9431a3..00000000 --- a/declarative-schemas/schemas/app/tables/handle_registry.sql +++ /dev/null @@ -1,13 +0,0 @@ -create table app.handle_registry ( - handle app.valid_name not null, - is_organization boolean not null, - created_at timestamp with time zone default now() not null -); - -alter table app.handle_registry - add constraint handle_registry_handle_is_organization_key unique (handle, is_organization); - -alter table app.handle_registry - add constraint handle_registry_pkey primary key (handle); - -grant insert (handle, is_organization) on app.handle_registry to authenticated; \ No newline at end of file diff --git a/declarative-schemas/schemas/app/tables/members.sql b/declarative-schemas/schemas/app/tables/members.sql deleted file mode 100644 index b47e172b..00000000 --- a/declarative-schemas/schemas/app/tables/members.sql +++ /dev/null @@ -1,31 +0,0 @@ -create table app.members ( - id uuid default extensions.uuid_generate_v4() not null, - organization_id uuid not null, - account_id uuid not null, - role app.membership_role not null, - created_at timestamp with time zone default now() not null -); - -create policy members_select_policy on app.members - for select - to authenticated - using (true); - -alter table app.members - enable row level security; - -alter table app.members - add constraint members_organization_id_account_id_key unique (organization_id, account_id); - -alter table app.members - add constraint members_pkey primary key (id); - -alter table app.members - add constraint members_account_id_fkey foreign key (account_id) references app.accounts(id); - -alter table app.members - add constraint members_organization_id_fkey foreign key (organization_id) references app.organizations(id); - -grant delete on app.members to authenticated; - -grant insert (account_id, organization_id, role) on app.members to authenticated; \ No newline at end of file diff --git a/declarative-schemas/schemas/app/tables/organizations.sql b/declarative-schemas/schemas/app/tables/organizations.sql deleted file mode 100644 index 49c0659b..00000000 --- a/declarative-schemas/schemas/app/tables/organizations.sql +++ /dev/null @@ -1,50 +0,0 @@ -create table app.organizations ( - id uuid default gen_random_uuid() not null, - handle app.valid_name not null, - is_organization boolean generated always as (true) stored, - avatar_id uuid, - display_name text, - bio text, - contact_email app.email_address, - created_at timestamp with time zone default now() not null -); - -create trigger on_app_organization_created - after insert on app.organizations - for each row - execute function app.register_organization_creator_as_member(); - -create policy organizations_insert_policy on app.organizations - for insert - to authenticated - with check (true); - -create policy organizations_select_policy on app.organizations - for select - to authenticated - using (true); - -alter table app.organizations - enable row level security; - -alter table app.organizations - add constraint fk_handle_registry foreign key (handle, is_organization) references app.handle_registry(handle, is_organization); - -alter table app.organizations - add constraint organizations_avatar_id_fkey foreign key (avatar_id) references storage.objects(id); - -alter table app.organizations - add constraint organizations_bio_check check (length(bio) <= 512); - -alter table app.organizations - add constraint organizations_display_name_check check (length(display_name) <= 128); - -alter table app.organizations - add constraint organizations_handle_key unique (handle); - -alter table app.organizations - add constraint organizations_pkey primary key (id); - -grant insert (avatar_id, bio, contact_email, display_name, handle) on app.organizations to authenticated; - -grant update (avatar_id, bio, contact_email, display_name) on app.organizations to authenticated; \ No newline at end of file diff --git a/declarative-schemas/schemas/app/tables/package_upgrades.sql b/declarative-schemas/schemas/app/tables/package_upgrades.sql deleted file mode 100644 index 847bba95..00000000 --- a/declarative-schemas/schemas/app/tables/package_upgrades.sql +++ /dev/null @@ -1,28 +0,0 @@ -create table app.package_upgrades ( - id uuid default gen_random_uuid() not null, - package_id uuid not null, - from_version_struct app.semver not null, - from_version text generated always as (app.semver_to_text(from_version_struct)) stored not null, - to_version_struct app.semver not null, - to_version text generated always as (app.semver_to_text(to_version_struct)) stored not null, - sql character varying(250000), - created_at timestamp with time zone default now() not null -); - -create policy package_upgrades_select_policy on app.package_upgrades - for select - using (true); - -alter table app.package_upgrades - enable row level security; - -alter table app.package_upgrades - add constraint package_upgrades_package_id_from_version_struct_to_version__key unique (package_id, from_version_struct, to_version_struct); - -alter table app.package_upgrades - add constraint package_upgrades_pkey primary key (id); - -alter table app.package_upgrades - add constraint package_upgrades_package_id_fkey foreign key (package_id) references app.packages(id); - -grant insert (from_version_struct, package_id, sql, to_version_struct) on app.package_upgrades to authenticated; \ No newline at end of file diff --git a/declarative-schemas/schemas/app/tables/package_versions.sql b/declarative-schemas/schemas/app/tables/package_versions.sql deleted file mode 100644 index 782a3109..00000000 --- a/declarative-schemas/schemas/app/tables/package_versions.sql +++ /dev/null @@ -1,27 +0,0 @@ -create table app.package_versions ( - id uuid default gen_random_uuid() not null, - package_id uuid not null, - version_struct app.semver not null, - version text generated always as (app.semver_to_text(version_struct)) stored not null, - sql character varying(250000), - description_md character varying(250000), - created_at timestamp with time zone default now() not null -); - -create policy package_versions_select_policy on app.package_versions - for select - using (true); - -alter table app.package_versions - enable row level security; - -alter table app.package_versions - add constraint package_versions_package_id_version_struct_key unique (package_id, version_struct); - -alter table app.package_versions - add constraint package_versions_pkey primary key (id); - -alter table app.package_versions - add constraint package_versions_package_id_fkey foreign key (package_id) references app.packages(id); - -grant insert (description_md, package_id, sql, version_struct) on app.package_versions to authenticated; \ No newline at end of file diff --git a/declarative-schemas/schemas/app/tables/packages.sql b/declarative-schemas/schemas/app/tables/packages.sql deleted file mode 100644 index 674bb308..00000000 --- a/declarative-schemas/schemas/app/tables/packages.sql +++ /dev/null @@ -1,33 +0,0 @@ -create table app.packages ( - id uuid default gen_random_uuid() not null, - package_name text generated always as (app.to_package_name(handle, partial_name)) stored not null, - handle app.valid_name not null, - partial_name app.valid_name not null, - control_description character varying(1000), - control_relocatable boolean default false not null, - control_requires character varying(128)[] default '{}'::character varying(128)[], - created_at timestamp with time zone default now() not null -); - -create index packages_handle_search_idx on app.packages using gin (handle extensions.gin_trgm_ops); - -create index packages_partial_name_search_idx on app.packages using gin (partial_name extensions.gin_trgm_ops); - -create policy packages_select_policy on app.packages - for select - to authenticated - using (true); - -alter table app.packages - enable row level security; - -alter table app.packages - add constraint packages_handle_fkey foreign key (handle) references app.handle_registry(handle); - -alter table app.packages - add constraint packages_handle_partial_name_key unique (handle, partial_name); - -alter table app.packages - add constraint packages_pkey primary key (id); - -grant insert (handle, partial_name) on app.packages to authenticated; \ No newline at end of file diff --git a/declarative-schemas/schemas/app/types/membership_role.sql b/declarative-schemas/schemas/app/types/membership_role.sql deleted file mode 100644 index 5cf55ed0..00000000 --- a/declarative-schemas/schemas/app/types/membership_role.sql +++ /dev/null @@ -1,3 +0,0 @@ -create type app.membership_role as enum ( - 'maintainer' -); \ No newline at end of file diff --git a/declarative-schemas/schemas/app/types/semver_struct.sql b/declarative-schemas/schemas/app/types/semver_struct.sql deleted file mode 100644 index d59d795b..00000000 --- a/declarative-schemas/schemas/app/types/semver_struct.sql +++ /dev/null @@ -1,5 +0,0 @@ -create type app.semver_struct as ( - major smallint, - minor smallint, - patch smallint -); \ No newline at end of file diff --git a/declarative-schemas/schemas/public/functions/search_packages.sql b/declarative-schemas/schemas/public/functions/search_packages.sql deleted file mode 100644 index 6ba0b7e8..00000000 --- a/declarative-schemas/schemas/public/functions/search_packages.sql +++ /dev/null @@ -1,18 +0,0 @@ -create function public.search_packages ( - handle extensions.citext default null::extensions.citext, - partial_name extensions.citext default null::extensions.citext -) - returns SETOF public.packages - language sql - stable - AS $function$ - select * - from public.packages - where - ($1 is null or handle <% $1 or handle ~ $1) - and - ($2 is null or partial_name <% $2 or partial_name ~ $2) - order by - coalesce(extensions.similarity($1, handle), 0) + coalesce(extensions.similarity($2, partial_name), 0) desc, - created_at desc; -$function$; \ No newline at end of file diff --git a/declarative-schemas/schemas/public/views/accounts.sql b/declarative-schemas/schemas/public/views/accounts.sql deleted file mode 100644 index 663a63ff..00000000 --- a/declarative-schemas/schemas/public/views/accounts.sql +++ /dev/null @@ -1,9 +0,0 @@ -create view public.accounts AS SELECT acc.id, - acc.handle, - obj.name AS avatar_path, - acc.display_name, - acc.bio, - acc.contact_email, - acc.created_at - FROM (app.accounts acc - LEFT JOIN storage.objects obj ON ((acc.avatar_id = obj.id))); \ No newline at end of file diff --git a/declarative-schemas/schemas/public/views/members.sql b/declarative-schemas/schemas/public/views/members.sql deleted file mode 100644 index 399a6652..00000000 --- a/declarative-schemas/schemas/public/views/members.sql +++ /dev/null @@ -1,5 +0,0 @@ -create view public.members AS SELECT aio.organization_id, - aio.account_id, - aio.role, - aio.created_at - FROM app.members aio; \ No newline at end of file diff --git a/declarative-schemas/schemas/public/views/organizations.sql b/declarative-schemas/schemas/public/views/organizations.sql deleted file mode 100644 index f4f02e81..00000000 --- a/declarative-schemas/schemas/public/views/organizations.sql +++ /dev/null @@ -1,9 +0,0 @@ -create view public.organizations AS SELECT org.id, - org.handle, - obj.name AS avatar_path, - org.display_name, - org.bio, - org.contact_email, - org.created_at - FROM (app.organizations org - LEFT JOIN storage.objects obj ON ((org.avatar_id = obj.id))); \ No newline at end of file diff --git a/declarative-schemas/schemas/public/views/package_upgrades.sql b/declarative-schemas/schemas/public/views/package_upgrades.sql deleted file mode 100644 index 600534e4..00000000 --- a/declarative-schemas/schemas/public/views/package_upgrades.sql +++ /dev/null @@ -1,9 +0,0 @@ -create view public.package_upgrades AS SELECT pu.id, - pu.package_id, - pa.package_name, - pu.from_version, - pu.to_version, - pu.sql, - pu.created_at - FROM (app.packages pa - JOIN app.package_upgrades pu ON ((pa.id = pu.package_id))); \ No newline at end of file diff --git a/declarative-schemas/schemas/public/views/package_versions.sql b/declarative-schemas/schemas/public/views/package_versions.sql deleted file mode 100644 index f81245e0..00000000 --- a/declarative-schemas/schemas/public/views/package_versions.sql +++ /dev/null @@ -1,11 +0,0 @@ -create view public.package_versions AS SELECT pv.id, - pv.package_id, - pa.package_name, - pv.version, - pv.sql, - pv.description_md, - pa.control_description, - pa.control_requires, - pv.created_at - FROM (app.packages pa - JOIN app.package_versions pv ON ((pa.id = pv.package_id))); \ No newline at end of file diff --git a/declarative-schemas/schemas/public/views/packages.sql b/declarative-schemas/schemas/public/views/packages.sql deleted file mode 100644 index 9ecff234..00000000 --- a/declarative-schemas/schemas/public/views/packages.sql +++ /dev/null @@ -1,21 +0,0 @@ -create view public.packages AS SELECT pa.id, - pa.package_name, - pa.handle, - pa.partial_name, - newest_ver.version AS latest_version, - newest_ver.description_md, - pa.control_description, - pa.control_requires, - pa.created_at - FROM app.packages pa, - LATERAL ( SELECT pv.id, - pv.package_id, - pv.version_struct, - pv.version, - pv.sql, - pv.description_md, - pv.created_at - FROM app.package_versions pv - WHERE (pv.package_id = pa.id) - ORDER BY pv.version_struct - LIMIT 1) newest_ver; \ No newline at end of file diff --git a/docs/declarative-schema.md b/docs/declarative-schema.md index 63a7de27..ba3d33a1 100644 --- a/docs/declarative-schema.md +++ b/docs/declarative-schema.md @@ -127,6 +127,27 @@ Optional env vars: | `SHADOW_IMAGE` | `supabase/postgres:15.6.1.143` | Docker image for the shadow DB. | | `OUTPUT_DIR` | `./declarative-schemas` | Declarative schema directory. | +### 3. Squash: one migration for full schema + +Generates a **single migration** that brings an empty DB (clean shadow) to the current state—equivalent to squashing all existing migrations into one file. Useful for greenfield deploys or new projects. + +1. Starts a shadow DB (clean baseline, no migrations applied). +2. Runs `pgdelta plan` (source = shadow, target = Supabase DB). +3. Writes the SQL to `supabase/migrations/_.sql`. + +```bash +bash scripts/declarative-dbdev-squash.sh +MIGRATION_NAME=initial_schema bash scripts/declarative-dbdev-squash.sh +``` + +The script does **not** apply the migration (your running DB is already current). Use the generated file for new environments or to replace a long migration history with one file. + +| Variable | Default | Description | +|----------|---------|-------------| +| `MIGRATION_NAME` | `squashed` | Suffix for the migration filename. | +| `PGDELTA` | `npx pgdelta` | Override the pg-delta CLI command. | +| `SHADOW_IMAGE` | `supabase/postgres:15.6.1.143` | Docker image for the shadow DB. | + ## File layout - **`declarative-schemas/`** – Version-controlled desired schema (exported by init, edited by you, applied to shadow in update). diff --git a/package-lock.json b/package-lock.json index 35c5cdf2..5a2f0bd3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5,350 +5,428 @@ "packages": { "": { "dependencies": { - "@supabase/pg-delta": "https://pkg.pr.new/supabase/pg-toolbelt/@supabase/pg-delta@f56ff1e" + "@supabase/pg-delta": "file:/Users/avallete/Documents/Programming/Supa/pg-toolbelt/packages/pg-delta" }, "devDependencies": { "supabase": "^2.76.16" } }, - "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==", + "../pg-toolbelt/node_modules/.bun/@pgsql+traverse@17.2.4/node_modules/@pgsql/traverse": { + "version": "17.2.4", "license": "MIT", "dependencies": { - "@babel/helper-validator-identifier": "^7.28.5", - "js-tokens": "^4.0.0", - "picocolors": "^1.1.1" + "@pgsql/types": "^17.6.2", + "pg-proto-parser": "1.30.4" }, - "engines": { - "node": ">=6.9.0" + "devDependencies": { + "makage": "^0.1.8" } }, - "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==", + "../pg-toolbelt/node_modules/.bun/@stricli+core@1.2.5/node_modules/@stricli/core": { + "version": "1.2.5", + "license": "Apache-2.0", + "devDependencies": { + "@types/chai": "^4.3.11", + "@types/fs-extra": "^11.0.4", + "@types/sinon": "^17.0.2", + "@typescript-eslint/eslint-plugin": "^8.2.0", + "@typescript-eslint/parser": "^8.2.0", + "eslint": "^8.57.0", + "eslint-plugin-header": "^3.1.1", + "eslint-plugin-import": "^2.29.1", + "eslint-plugin-prettier": "^5.1.3", + "fs-extra": "^11.2.0", + "prettier": "^3.2.5", + "sinon": "^17.0.1", + "tsup": "^8.0.1", + "tsx": "^4.8.2", + "typescript": "5.6.x" + } + }, + "../pg-toolbelt/node_modules/.bun/@testcontainers+postgresql@11.11.0/node_modules/@testcontainers/postgresql": { + "version": "11.11.0", + "dev": true, "license": "MIT", "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" + "testcontainers": "^11.11.0" }, - "engines": { - "node": ">=6.9.0" + "devDependencies": { + "@types/pg": "^8.16.0", + "pg": "^8.16.3" } }, - "node_modules/@babel/generator/node_modules/@babel/types": { - "version": "7.29.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.0.tgz", - "integrity": "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==", + "../pg-toolbelt/node_modules/.bun/@ts-safeql+sql-tag@0.2.1/node_modules/@ts-safeql/sql-tag": { + "version": "0.2.1", "license": "MIT", - "dependencies": { - "@babel/helper-string-parser": "^7.27.1", - "@babel/helper-validator-identifier": "^7.28.5" - }, - "engines": { - "node": ">=6.9.0" + "devDependencies": { + "@types/node": "^18.15.11", + "@typescript-eslint/eslint-plugin": "^7.8.0", + "@typescript-eslint/parser": "^7.8.0", + "eslint": "^8.57.0", + "typescript": "^5.4.5", + "unbuild": "^2.0.0", + "vitest": "^1.6.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==", - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } + "../pg-toolbelt/node_modules/.bun/@tsconfig+node-ts@23.6.4/node_modules/@tsconfig/node-ts": { + "version": "23.6.4", + "dev": true, + "license": "MIT" }, - "node_modules/@babel/helper-string-parser": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", - "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } + "../pg-toolbelt/node_modules/.bun/@tsconfig+node24@24.0.4/node_modules/@tsconfig/node24": { + "version": "24.0.4", + "dev": true, + "license": "MIT" }, - "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==", + "../pg-toolbelt/node_modules/.bun/@types+bun@1.3.9/node_modules/@types/bun": { + "version": "1.3.9", + "dev": true, "license": "MIT", - "engines": { - "node": ">=6.9.0" + "dependencies": { + "bun-types": "1.3.9" } }, - "node_modules/@babel/parser": { - "version": "7.29.0", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.0.tgz", - "integrity": "sha512-IyDgFV5GeDUVX4YdF/3CPULtVGSXXMLh1xVIgdCgxApktqnQV0r7/8Nqthg+8YLGaAtdyIlo2qIdZrbCv4+7ww==", + "../pg-toolbelt/node_modules/.bun/@types+debug@4.1.12/node_modules/@types/debug": { + "version": "4.1.12", + "dev": true, "license": "MIT", "dependencies": { - "@babel/types": "^7.29.0" - }, - "bin": { - "parser": "bin/babel-parser.js" - }, - "engines": { - "node": ">=6.0.0" + "@types/ms": "*" } }, - "node_modules/@babel/parser/node_modules/@babel/types": { - "version": "7.29.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.0.tgz", - "integrity": "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==", + "../pg-toolbelt/node_modules/.bun/@types+node@24.10.13/node_modules/@types/node": { + "version": "24.10.13", + "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-string-parser": "^7.27.1", - "@babel/helper-validator-identifier": "^7.28.5" - }, - "engines": { - "node": ">=6.9.0" + "undici-types": "~7.16.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==", + "../pg-toolbelt/node_modules/.bun/@types+pg@8.16.0/node_modules/@types/pg": { + "version": "8.16.0", + "dev": true, "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.28.6", - "@babel/parser": "^7.28.6", - "@babel/types": "^7.28.6" - }, - "engines": { - "node": ">=6.9.0" + "@types/node": "*", + "pg-protocol": "*", + "pg-types": "^2.2.0" } }, - "node_modules/@babel/template/node_modules/@babel/types": { - "version": "7.29.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.0.tgz", - "integrity": "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==", + "../pg-toolbelt/node_modules/.bun/chalk@5.6.2/node_modules/chalk": { + "version": "5.6.2", "license": "MIT", - "dependencies": { - "@babel/helper-string-parser": "^7.27.1", - "@babel/helper-validator-identifier": "^7.28.5" + "devDependencies": { + "@types/node": "^16.11.10", + "ava": "^3.15.0", + "c8": "^7.10.0", + "color-convert": "^2.0.1", + "execa": "^6.0.0", + "log-update": "^5.0.0", + "matcha": "^0.7.0", + "tsd": "^0.19.0", + "xo": "^0.57.0", + "yoctodelay": "^2.0.0" }, "engines": { - "node": ">=6.9.0" + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/@babel/traverse": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.28.5.tgz", - "integrity": "sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ==", + "../pg-toolbelt/node_modules/.bun/debug@4.4.3/node_modules/debug": { + "version": "4.4.3", "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.27.1", - "@babel/generator": "^7.28.5", - "@babel/helper-globals": "^7.28.0", - "@babel/parser": "^7.28.5", - "@babel/template": "^7.27.2", - "@babel/types": "^7.28.5", - "debug": "^4.3.1" + "ms": "^2.1.3" + }, + "devDependencies": { + "brfs": "^2.0.1", + "browserify": "^16.2.3", + "coveralls": "^3.0.2", + "karma": "^3.1.4", + "karma-browserify": "^6.0.0", + "karma-chrome-launcher": "^2.2.0", + "karma-mocha": "^1.3.0", + "mocha": "^5.2.0", + "mocha-lcov-reporter": "^1.2.0", + "sinon": "^14.0.0", + "xo": "^0.23.0" }, "engines": { - "node": ">=6.9.0" + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } } }, - "node_modules/@babel/types": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.5.tgz", - "integrity": "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==", + "../pg-toolbelt/node_modules/.bun/dedent@1.7.1/node_modules/dedent": { + "version": "1.7.1", + "dev": true, "license": "MIT", - "dependencies": { - "@babel/helper-string-parser": "^7.27.1", - "@babel/helper-validator-identifier": "^7.28.5" + "devDependencies": { + "@babel/cli": "^7.21.5", + "@babel/preset-env": "^7.23.3", + "@babel/preset-typescript": "^7.23.3", + "@release-it/conventional-changelog": "^8.0.1", + "@types/babel-plugin-macros": "^3.1.0", + "@types/bun": "^1.3.4", + "@types/eslint": "^8.44.7", + "@types/jest": "^29.5.3", + "@typescript-eslint/eslint-plugin": "^6.10.0", + "@typescript-eslint/parser": "^6.10.0", + "babel-plugin-add-module-exports": "^1.0.4", + "babel-plugin-tester": "^11.0.4", + "console-fail-test": "^0.2.3", + "cspell": "^8.0.0", + "eslint": "^8.53.0", + "eslint-plugin-deprecation": "^2.0.0", + "eslint-plugin-eslint-comments": "^3.2.0", + "eslint-plugin-jest": "^27.6.0", + "eslint-plugin-jsdoc": "^46.9.0", + "eslint-plugin-jsonc": "^2.10.0", + "eslint-plugin-markdown": "^3.0.1", + "eslint-plugin-n": "^16.3.1", + "eslint-plugin-no-only-tests": "^3.1.0", + "eslint-plugin-perfectionist": "^2.3.0", + "eslint-plugin-regexp": "^2.1.1", + "eslint-plugin-yml": "^1.10.0", + "husky": "^8.0.3", + "jest": "^29.7.0", + "jsonc-eslint-parser": "^2.4.0", + "knip": "^5.75.0", + "lint-staged": "^15.1.0", + "markdownlint": "^0.31.1", + "markdownlint-cli": "^0.37.0", + "npm-package-json-lint": "^7.1.0", + "npm-package-json-lint-config-default": "^6.0.0", + "prettier": "^3.0.3", + "prettier-plugin-curly": "^0.1.3", + "prettier-plugin-packagejson": "^2.4.6", + "release-it": "^17.0.0", + "should-semantic-release": "^0.2.1", + "tsup": "^7.2.0", + "typescript": "^5.2.2", + "yaml-eslint-parser": "^1.2.2" }, - "engines": { - "node": ">=6.9.0" + "peerDependencies": { + "babel-plugin-macros": "^3.1.0" + }, + "peerDependenciesMeta": { + "babel-plugin-macros": { + "optional": true + } } }, - "node_modules/@isaacs/fs-minipass": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@isaacs/fs-minipass/-/fs-minipass-4.0.1.tgz", - "integrity": "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==", + "../pg-toolbelt/node_modules/.bun/knip@5.83.1+9cdfcf6afadfcf55/node_modules/knip": { + "version": "5.83.1", "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/webpro" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/knip" + } + ], "license": "ISC", "dependencies": { - "minipass": "^7.0.4" + "@nodelib/fs.walk": "^1.2.3", + "fast-glob": "^3.3.3", + "formatly": "^0.3.0", + "jiti": "^2.6.0", + "js-yaml": "^4.1.1", + "minimist": "^1.2.8", + "oxc-resolver": "^11.15.0", + "picocolors": "^1.1.1", + "picomatch": "^4.0.1", + "smol-toml": "^1.5.2", + "strip-json-comments": "5.0.3", + "zod": "^4.1.11" + }, + "bin": { + "knip": "bin/knip.js", + "knip-bun": "bin/knip-bun.js" + }, + "devDependencies": { + "@jest/types": "^29.6.3", + "@types/bun": "^1.3.3", + "@types/js-yaml": "^4.0.9", + "@types/minimist": "^1.2.5", + "@types/picomatch": "^4.0.1", + "@types/webpack": "^5.28.5", + "@wdio/types": "^9.20.0", + "codeclimate-types": "^0.3.1", + "glob-bin": "^1.0.0", + "tsx": "^4.20.3", + "typescript": "^5.5.2" }, "engines": { - "node": ">=18.0.0" + "node": ">=18.18.0" + }, + "peerDependencies": { + "@types/node": ">=18", + "typescript": ">=5.0.4 <7" } }, - "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==", + "../pg-toolbelt/node_modules/.bun/pg@8.18.0+32ccf17b773ffb11/node_modules/pg": { + "version": "8.18.0", "license": "MIT", "dependencies": { - "@jridgewell/sourcemap-codec": "^1.5.0", - "@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==", - "license": "MIT", + "pg-connection-string": "^2.11.0", + "pg-pool": "^3.11.0", + "pg-protocol": "^1.11.0", + "pg-types": "2.2.0", + "pgpass": "1.0.5" + }, + "devDependencies": { + "@cloudflare/vitest-pool-workers": "0.8.23", + "@cloudflare/workers-types": "^4.20230404.0", + "async": "2.6.4", + "bluebird": "3.7.2", + "co": "4.6.0", + "pg-copy-streams": "0.3.0", + "typescript": "^4.0.3", + "vitest": "~3.0.9", + "wrangler": "^3.x" + }, "engines": { - "node": ">=6.0.0" + "node": ">= 16.0.0" + }, + "optionalDependencies": { + "pg-cloudflare": "^1.3.0" + }, + "peerDependencies": { + "pg-native": ">=3.0.1" + }, + "peerDependenciesMeta": { + "pg-native": { + "optional": true + } } }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.5.5", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", - "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", - "license": "MIT" - }, - "node_modules/@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==", + "../pg-toolbelt/node_modules/.bun/plpgsql-parser@0.5.4/node_modules/plpgsql-parser": { + "version": "0.5.4", "license": "MIT", "dependencies": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" - } - }, - "node_modules/@launchql/protobufjs": { - "version": "7.2.6", - "resolved": "https://registry.npmjs.org/@launchql/protobufjs/-/protobufjs-7.2.6.tgz", - "integrity": "sha512-vwi1nG2/heVFsIMHQU1KxTjUp5c757CTtRAZn/jutApCkFlle1iv8tzM/DHlSZJKDldxaYqnNYTg0pTyp8Bbtg==", - "hasInstallScript": true, - "license": "BSD-3-Clause", - "dependencies": { - "@protobufjs/aspromise": "^1.1.2", - "@protobufjs/base64": "^1.1.2", - "@protobufjs/codegen": "^2.0.4", - "@protobufjs/eventemitter": "^1.1.0", - "@protobufjs/fetch": "^1.1.0", - "@protobufjs/float": "^1.0.2", - "@protobufjs/inquire": "^1.1.0", - "@protobufjs/path": "^1.1.2", - "@protobufjs/pool": "^1.1.0", - "@protobufjs/utf8": "^1.1.0", - "@types/node": ">=13.7.0", - "long": "^5.0.0" + "@libpg-query/parser": "^17.6.3", + "@pgsql/traverse": "17.2.4", + "@pgsql/types": "^17.6.2", + "pgsql-deparser": "17.17.2", + "plpgsql-deparser": "0.7.3" }, - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/@libpg-query/parser": { - "version": "17.6.3", - "resolved": "https://registry.npmjs.org/@libpg-query/parser/-/parser-17.6.3.tgz", - "integrity": "sha512-AvbS7b9GJZfCzqt4tLMqTaYK7Css9pJRTA2dKWLoTlob/XO2VNc30Q3g9DmxNBmokVTrmibkn/dy9bw8hfosQQ==", - "license": "LICENSE IN LICENSE", - "dependencies": { - "@launchql/protobufjs": "7.2.6", - "@pgsql/types": "^17.6.0" + "devDependencies": { + "makage": "^0.1.8" } }, - "node_modules/@pgsql/quotes": { - "version": "17.1.0", - "resolved": "https://registry.npmjs.org/@pgsql/quotes/-/quotes-17.1.0.tgz", - "integrity": "sha512-J/H+LcrENBpYgL45WW6aTjb5Yk4tX4+AmB2/k8KZa+Zh3wiCtqmNIag+HZz5HmWaF6EZK9ZGC95NBD1fs+rUvg==", - "license": "MIT" - }, - "node_modules/@pgsql/traverse": { - "version": "17.2.4", - "resolved": "https://registry.npmjs.org/@pgsql/traverse/-/traverse-17.2.4.tgz", - "integrity": "sha512-7dnst2U3qXXSFbS+HvVktW/C4aVKe/niaRxZ1cfhmdy9E7SMYM0OukFO7gvoZb6I3dnKm/eTfpv23JPKq5z6DA==", + "../pg-toolbelt/node_modules/.bun/testcontainers@11.11.0/node_modules/testcontainers": { + "version": "11.11.0", + "dev": true, "license": "MIT", "dependencies": { - "@pgsql/types": "^17.6.2", - "pg-proto-parser": "1.30.4" + "@balena/dockerignore": "^1.0.2", + "@types/dockerode": "^3.3.47", + "archiver": "^7.0.1", + "async-lock": "^1.4.1", + "byline": "^5.0.0", + "debug": "^4.4.3", + "docker-compose": "^1.3.0", + "dockerode": "^4.0.9", + "get-port": "^7.1.0", + "proper-lockfile": "^4.1.2", + "properties-reader": "^2.3.0", + "ssh-remote-port-forward": "^1.0.4", + "tar-fs": "^3.1.1", + "tmp": "^0.2.5", + "undici": "^7.16.0" + }, + "devDependencies": { + "@types/archiver": "^7.0.0", + "@types/async-lock": "^1.4.2", + "@types/byline": "^4.2.36", + "@types/debug": "^4.1.12", + "@types/proper-lockfile": "^4.1.4", + "@types/properties-reader": "^2.1.3", + "@types/tar-fs": "^2.0.4", + "@types/tmp": "^0.2.6" + } + }, + "../pg-toolbelt/node_modules/.bun/typescript@5.9.3/node_modules/typescript": { + "version": "5.9.3", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "devDependencies": { + "@dprint/formatter": "^0.4.1", + "@dprint/typescript": "0.93.4", + "@esfx/canceltoken": "^1.0.0", + "@eslint/js": "^9.20.0", + "@octokit/rest": "^21.1.1", + "@types/chai": "^4.3.20", + "@types/diff": "^7.0.1", + "@types/minimist": "^1.2.5", + "@types/mocha": "^10.0.10", + "@types/ms": "^0.7.34", + "@types/node": "latest", + "@types/source-map-support": "^0.5.10", + "@types/which": "^3.0.4", + "@typescript-eslint/rule-tester": "^8.24.1", + "@typescript-eslint/type-utils": "^8.24.1", + "@typescript-eslint/utils": "^8.24.1", + "azure-devops-node-api": "^14.1.0", + "c8": "^10.1.3", + "chai": "^4.5.0", + "chokidar": "^4.0.3", + "diff": "^7.0.0", + "dprint": "^0.49.0", + "esbuild": "^0.25.0", + "eslint": "^9.20.1", + "eslint-formatter-autolinkable-stylish": "^1.4.0", + "eslint-plugin-regexp": "^2.7.0", + "fast-xml-parser": "^4.5.2", + "glob": "^10.4.5", + "globals": "^15.15.0", + "hereby": "^1.10.0", + "jsonc-parser": "^3.3.1", + "knip": "^5.44.4", + "minimist": "^1.2.8", + "mocha": "^10.8.2", + "mocha-fivemat-progress-reporter": "^0.1.0", + "monocart-coverage-reports": "^2.12.1", + "ms": "^2.1.3", + "picocolors": "^1.1.1", + "playwright": "^1.50.1", + "source-map-support": "^0.5.21", + "tslib": "^2.8.1", + "typescript": "^5.7.3", + "typescript-eslint": "^8.24.1", + "which": "^3.0.1" + }, + "engines": { + "node": ">=14.17" + } + }, + "../pg-toolbelt/node_modules/.bun/zod@4.3.6/node_modules/zod": { + "version": "4.3.6", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" } }, - "node_modules/@pgsql/types": { - "version": "17.6.2", - "resolved": "https://registry.npmjs.org/@pgsql/types/-/types-17.6.2.tgz", - "integrity": "sha512-1UtbELdbqNdyOShhrVfSz3a1gDi0s9XXiQemx+6QqtsrXe62a6zOGU+vjb2GRfG5jeEokI1zBBcfD42enRv0Rw==", - "license": "MIT" - }, - "node_modules/@protobufjs/aspromise": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", - "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==", - "license": "BSD-3-Clause" - }, - "node_modules/@protobufjs/base64": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", - "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==", - "license": "BSD-3-Clause" - }, - "node_modules/@protobufjs/codegen": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", - "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==", - "license": "BSD-3-Clause" - }, - "node_modules/@protobufjs/eventemitter": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", - "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==", - "license": "BSD-3-Clause" - }, - "node_modules/@protobufjs/fetch": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", - "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==", - "license": "BSD-3-Clause", - "dependencies": { - "@protobufjs/aspromise": "^1.1.1", - "@protobufjs/inquire": "^1.1.0" - } - }, - "node_modules/@protobufjs/float": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", - "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==", - "license": "BSD-3-Clause" - }, - "node_modules/@protobufjs/inquire": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", - "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==", - "license": "BSD-3-Clause" - }, - "node_modules/@protobufjs/path": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", - "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==", - "license": "BSD-3-Clause" - }, - "node_modules/@protobufjs/pool": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", - "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==", - "license": "BSD-3-Clause" - }, - "node_modules/@protobufjs/utf8": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", - "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==", - "license": "BSD-3-Clause" - }, - "node_modules/@stricli/core": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/@stricli/core/-/core-1.2.6.tgz", - "integrity": "sha512-j5fa1wyOLrP9WJqqLFEJeQviqb3cK46K+FXTuISEkG/H5C820YfKDoVQ3CDVdM5WLhEx1ARdpiW6+hU4tYHjCQ==", - "license": "Apache-2.0" - }, - "node_modules/@supabase/pg-delta": { + "../pg-toolbelt/packages/pg-delta": { + "name": "@supabase/pg-delta", "version": "1.0.0-alpha.4", - "resolved": "https://pkg.pr.new/supabase/pg-toolbelt/@supabase/pg-delta@f56ff1e", - "integrity": "sha512-NnDNTPDm8bGZtF/hIK6omIya7Xwe/NNaR4wRrxEv5m8KeVvH418cXkij1TCEWj2k39MOCLggqPzENcWYPCGMxQ==", "license": "MIT", "dependencies": { "@stricli/core": "^1.2.4", - "@supabase/pg-topo": "https://pkg.pr.new/supabase/pg-toolbelt/@supabase/pg-topo@f56ff1e5c4ab379aaf8b3b2fe3f26a1d0a4f0621", + "@supabase/pg-topo": "workspace:*", "@ts-safeql/sql-tag": "^0.2.0", "chalk": "^5.6.2", "debug": "^4.3.7", @@ -358,58 +436,159 @@ "bin": { "pgdelta": "dist/cli/bin/cli.js" }, + "devDependencies": { + "@tsconfig/node-ts": "^23.6.2", + "@tsconfig/node24": "^24.0.3", + "@types/bun": "^1.3.9", + "@types/debug": "^4.1.12", + "@types/node": "^24.10.4", + "@types/pg": "^8.11.10", + "dedent": "^1.7.1", + "knip": "^5.75.2", + "testcontainers": "^11.10.0", + "typescript": "^5.9.3" + }, "engines": { "node": ">=20.0.0" } }, - "node_modules/@supabase/pg-topo": { + "../pg-toolbelt/packages/pg-delta/node_modules/@stricli/core": { + "resolved": "../pg-toolbelt/node_modules/.bun/@stricli+core@1.2.5/node_modules/@stricli/core", + "link": true + }, + "../pg-toolbelt/packages/pg-delta/node_modules/@supabase/pg-topo": { + "resolved": "../pg-toolbelt/packages/pg-topo", + "link": true + }, + "../pg-toolbelt/packages/pg-delta/node_modules/@ts-safeql/sql-tag": { + "resolved": "../pg-toolbelt/node_modules/.bun/@ts-safeql+sql-tag@0.2.1/node_modules/@ts-safeql/sql-tag", + "link": true + }, + "../pg-toolbelt/packages/pg-delta/node_modules/@tsconfig/node-ts": { + "resolved": "../pg-toolbelt/node_modules/.bun/@tsconfig+node-ts@23.6.4/node_modules/@tsconfig/node-ts", + "link": true + }, + "../pg-toolbelt/packages/pg-delta/node_modules/@tsconfig/node24": { + "resolved": "../pg-toolbelt/node_modules/.bun/@tsconfig+node24@24.0.4/node_modules/@tsconfig/node24", + "link": true + }, + "../pg-toolbelt/packages/pg-delta/node_modules/@types/bun": { + "resolved": "../pg-toolbelt/node_modules/.bun/@types+bun@1.3.9/node_modules/@types/bun", + "link": true + }, + "../pg-toolbelt/packages/pg-delta/node_modules/@types/debug": { + "resolved": "../pg-toolbelt/node_modules/.bun/@types+debug@4.1.12/node_modules/@types/debug", + "link": true + }, + "../pg-toolbelt/packages/pg-delta/node_modules/@types/node": { + "resolved": "../pg-toolbelt/node_modules/.bun/@types+node@24.10.13/node_modules/@types/node", + "link": true + }, + "../pg-toolbelt/packages/pg-delta/node_modules/@types/pg": { + "resolved": "../pg-toolbelt/node_modules/.bun/@types+pg@8.16.0/node_modules/@types/pg", + "link": true + }, + "../pg-toolbelt/packages/pg-delta/node_modules/chalk": { + "resolved": "../pg-toolbelt/node_modules/.bun/chalk@5.6.2/node_modules/chalk", + "link": true + }, + "../pg-toolbelt/packages/pg-delta/node_modules/debug": { + "resolved": "../pg-toolbelt/node_modules/.bun/debug@4.4.3/node_modules/debug", + "link": true + }, + "../pg-toolbelt/packages/pg-delta/node_modules/dedent": { + "resolved": "../pg-toolbelt/node_modules/.bun/dedent@1.7.1/node_modules/dedent", + "link": true + }, + "../pg-toolbelt/packages/pg-delta/node_modules/knip": { + "resolved": "../pg-toolbelt/node_modules/.bun/knip@5.83.1+9cdfcf6afadfcf55/node_modules/knip", + "link": true + }, + "../pg-toolbelt/packages/pg-delta/node_modules/pg": { + "resolved": "../pg-toolbelt/node_modules/.bun/pg@8.18.0+32ccf17b773ffb11/node_modules/pg", + "link": true + }, + "../pg-toolbelt/packages/pg-delta/node_modules/testcontainers": { + "resolved": "../pg-toolbelt/node_modules/.bun/testcontainers@11.11.0/node_modules/testcontainers", + "link": true + }, + "../pg-toolbelt/packages/pg-delta/node_modules/typescript": { + "resolved": "../pg-toolbelt/node_modules/.bun/typescript@5.9.3/node_modules/typescript", + "link": true + }, + "../pg-toolbelt/packages/pg-delta/node_modules/zod": { + "resolved": "../pg-toolbelt/node_modules/.bun/zod@4.3.6/node_modules/zod", + "link": true + }, + "../pg-toolbelt/packages/pg-topo": { + "name": "@supabase/pg-topo", "version": "1.0.0-alpha.0", - "resolved": "https://pkg.pr.new/supabase/pg-toolbelt/@supabase/pg-topo@f56ff1e5c4ab379aaf8b3b2fe3f26a1d0a4f0621", - "integrity": "sha512-JMG0wmfZzF5H5lwK89c7Q68qfMHFI8GBMZEJqdaghHRqO00ZAztMAQaJuVdxJJg4hSZ2tpVNuEDCAq+4669chQ==", "license": "MIT", "dependencies": { "@pgsql/traverse": "^17.2.4", "plpgsql-parser": "^0.5.4" + }, + "devDependencies": { + "@testcontainers/postgresql": "^11.11.0", + "@types/bun": "^1.3.9", + "knip": "^5.75.2", + "testcontainers": "^11.11.0", + "typescript": "^5.9.3" } }, - "node_modules/@ts-safeql/sql-tag": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/@ts-safeql/sql-tag/-/sql-tag-0.2.1.tgz", - "integrity": "sha512-TaDtQjobByWIn95dM2H2ucltJyL8w2B9mZdr6/1o1ZdbLRLS16XqzY6ssWkviHomQwIxB+CfK3Qz5a6AHDswsA==", - "license": "MIT" + "../pg-toolbelt/packages/pg-topo/node_modules/@pgsql/traverse": { + "resolved": "../pg-toolbelt/node_modules/.bun/@pgsql+traverse@17.2.4/node_modules/@pgsql/traverse", + "link": true }, - "node_modules/@types/node": { - "version": "25.3.3", - "resolved": "https://registry.npmjs.org/@types/node/-/node-25.3.3.tgz", - "integrity": "sha512-DpzbrH7wIcBaJibpKo9nnSQL0MTRdnWttGyE5haGwK86xgMOkFLp7vEyfQPGLOJh5wNYiJ3V9PmUMDhV9u8kkQ==", - "license": "MIT", + "../pg-toolbelt/packages/pg-topo/node_modules/@testcontainers/postgresql": { + "resolved": "../pg-toolbelt/node_modules/.bun/@testcontainers+postgresql@11.11.0/node_modules/@testcontainers/postgresql", + "link": true + }, + "../pg-toolbelt/packages/pg-topo/node_modules/@types/bun": { + "resolved": "../pg-toolbelt/node_modules/.bun/@types+bun@1.3.9/node_modules/@types/bun", + "link": true + }, + "../pg-toolbelt/packages/pg-topo/node_modules/knip": { + "resolved": "../pg-toolbelt/node_modules/.bun/knip@5.83.1+9cdfcf6afadfcf55/node_modules/knip", + "link": true + }, + "../pg-toolbelt/packages/pg-topo/node_modules/plpgsql-parser": { + "resolved": "../pg-toolbelt/node_modules/.bun/plpgsql-parser@0.5.4/node_modules/plpgsql-parser", + "link": true + }, + "../pg-toolbelt/packages/pg-topo/node_modules/testcontainers": { + "resolved": "../pg-toolbelt/node_modules/.bun/testcontainers@11.11.0/node_modules/testcontainers", + "link": true + }, + "../pg-toolbelt/packages/pg-topo/node_modules/typescript": { + "resolved": "../pg-toolbelt/node_modules/.bun/typescript@5.9.3/node_modules/typescript", + "link": true + }, + "node_modules/@isaacs/fs-minipass": { + "version": "4.0.1", + "dev": true, + "license": "ISC", "dependencies": { - "undici-types": "~7.18.0" + "minipass": "^7.0.4" + }, + "engines": { + "node": ">=18.0.0" } }, + "node_modules/@supabase/pg-delta": { + "resolved": "../pg-toolbelt/packages/pg-delta", + "link": true + }, "node_modules/agent-base": { "version": "7.1.4", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", - "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==", "dev": true, "license": "MIT", "engines": { "node": ">= 14" } }, - "node_modules/balanced-match": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", - "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", - "license": "MIT", - "engines": { - "node": "18 || 20 || >=22" - } - }, "node_modules/bin-links": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/bin-links/-/bin-links-6.0.0.tgz", - "integrity": "sha512-X4CiKlcV2GjnCMwnKAfbVWpHa++65th9TuzAEYtZoATiOE2DQKhSp4CJlyLoTqdhBKlXjpXjCTYPNNFS33Fi6w==", "dev": true, "license": "ISC", "dependencies": { @@ -423,43 +602,8 @@ "node": "^20.17.0 || >=22.9.0" } }, - "node_modules/brace-expansion": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.4.tgz", - "integrity": "sha512-h+DEnpVvxmfVefa4jFbCf5HdH5YMDXRsmKflpf1pILZWRFlTbJpxeU55nJl4Smt5HQaGzg1o6RHFPJaOqnmBDg==", - "license": "MIT", - "dependencies": { - "balanced-match": "^4.0.2" - }, - "engines": { - "node": "18 || 20 || >=22" - } - }, - "node_modules/case": { - "version": "1.6.3", - "resolved": "https://registry.npmjs.org/case/-/case-1.6.3.tgz", - "integrity": "sha512-mzDSXIPaFwVDvZAHqZ9VlbyF4yyXRuX6IvB06WvPYkqJVO24kX1PPhv9bfpKNFZyxYFmmgo03HUiD8iklmJYRQ==", - "license": "(MIT OR GPL-3.0-or-later)", - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/chalk": { - "version": "5.6.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz", - "integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==", - "license": "MIT", - "engines": { - "node": "^12.17.0 || ^14.13 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, "node_modules/chownr": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-3.0.0.tgz", - "integrity": "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==", "dev": true, "license": "BlueOak-1.0.0", "engines": { @@ -468,8 +612,6 @@ }, "node_modules/cmd-shim": { "version": "8.0.0", - "resolved": "https://registry.npmjs.org/cmd-shim/-/cmd-shim-8.0.0.tgz", - "integrity": "sha512-Jk/BK6NCapZ58BKUxlSI+ouKRbjH1NLZCgJkYoab+vEHUY3f6OzpNBN9u7HFSv9J6TRDGs4PLOHezoKGaFRSCA==", "dev": true, "license": "ISC", "engines": { @@ -478,8 +620,6 @@ }, "node_modules/data-uri-to-buffer": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz", - "integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==", "dev": true, "license": "MIT", "engines": { @@ -488,8 +628,7 @@ }, "node_modules/debug": { "version": "4.4.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", - "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "dev": true, "license": "MIT", "dependencies": { "ms": "^2.1.3" @@ -503,19 +642,8 @@ } } }, - "node_modules/deepmerge": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", - "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/fetch-blob": { "version": "3.2.0", - "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz", - "integrity": "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==", "dev": true, "funding": [ { @@ -538,8 +666,6 @@ }, "node_modules/formdata-polyfill": { "version": "4.0.10", - "resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz", - "integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==", "dev": true, "license": "MIT", "dependencies": { @@ -551,8 +677,6 @@ }, "node_modules/https-proxy-agent": { "version": "7.0.6", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", - "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", "dev": true, "license": "MIT", "dependencies": { @@ -563,49 +687,8 @@ "node": ">= 14" } }, - "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==", - "license": "MIT" - }, - "node_modules/jsesc": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", - "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", - "license": "MIT", - "bin": { - "jsesc": "bin/jsesc" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/long": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/long/-/long-5.3.2.tgz", - "integrity": "sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==", - "license": "Apache-2.0" - }, - "node_modules/minimatch": { - "version": "10.2.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.4.tgz", - "integrity": "sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg==", - "license": "BlueOak-1.0.0", - "dependencies": { - "brace-expansion": "^5.0.2" - }, - "engines": { - "node": "18 || 20 || >=22" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/minipass": { "version": "7.1.3", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.3.tgz", - "integrity": "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==", "dev": true, "license": "BlueOak-1.0.0", "engines": { @@ -614,8 +697,6 @@ }, "node_modules/minizlib": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-3.1.0.tgz", - "integrity": "sha512-KZxYo1BUkWD2TVFLr0MQoM8vUUigWD3LlD83a/75BqC+4qE0Hb1Vo5v1FgcfaNXvfXzr+5EhQ6ing/CaBijTlw==", "dev": true, "license": "MIT", "dependencies": { @@ -627,21 +708,11 @@ }, "node_modules/ms": { "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "license": "MIT" - }, - "node_modules/nested-obj": { - "version": "0.1.10", - "resolved": "https://registry.npmjs.org/nested-obj/-/nested-obj-0.1.10.tgz", - "integrity": "sha512-5V2kUPrBee/tmoS2p0IJ35BcaJuW1p1yXF5GP8JpXIkDoPbaYeYypAHizUeZkAUxcC7Rago7izWmEq7qa8+Mhw==", + "dev": true, "license": "MIT" }, "node_modules/node-domexception": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", - "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==", - "deprecated": "Use your platform's native DOMException instead", "dev": true, "funding": [ { @@ -660,8 +731,6 @@ }, "node_modules/node-fetch": { "version": "3.3.2", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz", - "integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==", "dev": true, "license": "MIT", "dependencies": { @@ -679,203 +748,14 @@ }, "node_modules/npm-normalize-package-bin": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-5.0.0.tgz", - "integrity": "sha512-CJi3OS4JLsNMmr2u07OJlhcrPxCeOeP/4xq67aWNai6TNWWbTrlNDgl8NcFKVlcBKp18GPj+EzbNIgrBfZhsag==", "dev": true, "license": "ISC", "engines": { "node": "^20.17.0 || >=22.9.0" } }, - "node_modules/pg": { - "version": "8.19.0", - "resolved": "https://registry.npmjs.org/pg/-/pg-8.19.0.tgz", - "integrity": "sha512-QIcLGi508BAHkQ3pJNptsFz5WQMlpGbuBGBaIaXsWK8mel2kQ/rThYI+DbgjUvZrIr7MiuEuc9LcChJoEZK1xQ==", - "license": "MIT", - "peer": true, - "dependencies": { - "pg-connection-string": "^2.11.0", - "pg-pool": "^3.12.0", - "pg-protocol": "^1.12.0", - "pg-types": "2.2.0", - "pgpass": "1.0.5" - }, - "engines": { - "node": ">= 16.0.0" - }, - "optionalDependencies": { - "pg-cloudflare": "^1.3.0" - }, - "peerDependencies": { - "pg-native": ">=3.0.1" - }, - "peerDependenciesMeta": { - "pg-native": { - "optional": true - } - } - }, - "node_modules/pg-cloudflare": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/pg-cloudflare/-/pg-cloudflare-1.3.0.tgz", - "integrity": "sha512-6lswVVSztmHiRtD6I8hw4qP/nDm1EJbKMRhf3HCYaqud7frGysPv7FYJ5noZQdhQtN2xJnimfMtvQq21pdbzyQ==", - "license": "MIT", - "optional": true - }, - "node_modules/pg-connection-string": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.11.0.tgz", - "integrity": "sha512-kecgoJwhOpxYU21rZjULrmrBJ698U2RxXofKVzOn5UDj61BPj/qMb7diYUR1nLScCDbrztQFl1TaQZT0t1EtzQ==", - "license": "MIT" - }, - "node_modules/pg-int8": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/pg-int8/-/pg-int8-1.0.1.tgz", - "integrity": "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==", - "license": "ISC", - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/pg-pool": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.12.0.tgz", - "integrity": "sha512-eIJ0DES8BLaziFHW7VgJEBPi5hg3Nyng5iKpYtj3wbcAUV9A1wLgWiY7ajf/f/oO1wfxt83phXPY8Emztg7ITg==", - "license": "MIT", - "peerDependencies": { - "pg": ">=8.0" - } - }, - "node_modules/pg-proto-parser": { - "version": "1.30.4", - "resolved": "https://registry.npmjs.org/pg-proto-parser/-/pg-proto-parser-1.30.4.tgz", - "integrity": "sha512-+9/n8zfYQVNRc8KGhxxNXO8NA5OKni01IPtit6+C3sLMtcRVVFCj4W0XtrEGFivNjz2qwUtFmRhG8OGMTxs6hg==", - "license": "MIT", - "dependencies": { - "@babel/generator": "^7.23.6", - "@babel/parser": "^7.23.6", - "@babel/traverse": "7.28.5", - "@babel/types": "7.28.5", - "@launchql/protobufjs": "7.2.6", - "case": "1.6.3", - "deepmerge": "4.3.1", - "nested-obj": "^0.1.5", - "strfy-js": "^3.1.5" - } - }, - "node_modules/pg-protocol": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.12.0.tgz", - "integrity": "sha512-uOANXNRACNdElMXJ0tPz6RBM0XQ61nONGAwlt8da5zs/iUOOCLBQOHSXnrC6fMsvtjxbOJrZZl5IScGv+7mpbg==", - "license": "MIT" - }, - "node_modules/pg-types": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/pg-types/-/pg-types-2.2.0.tgz", - "integrity": "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==", - "license": "MIT", - "dependencies": { - "pg-int8": "1.0.1", - "postgres-array": "~2.0.0", - "postgres-bytea": "~1.0.0", - "postgres-date": "~1.0.4", - "postgres-interval": "^1.1.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/pgpass": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/pgpass/-/pgpass-1.0.5.tgz", - "integrity": "sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug==", - "license": "MIT", - "dependencies": { - "split2": "^4.1.0" - } - }, - "node_modules/pgsql-deparser": { - "version": "17.18.0", - "resolved": "https://registry.npmjs.org/pgsql-deparser/-/pgsql-deparser-17.18.0.tgz", - "integrity": "sha512-LFjdKKYHVo8lUPbOVfO6dRm5L28hBrfqnBrX3DhiC97k6Hsbi+7LXzvL30gahLUbN5dLai9MvsJ8Gbg/7joD1Q==", - "license": "MIT", - "dependencies": { - "@pgsql/quotes": "17.1.0", - "@pgsql/types": "^17.6.2" - } - }, - "node_modules/picocolors": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", - "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", - "license": "ISC" - }, - "node_modules/plpgsql-deparser": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/plpgsql-deparser/-/plpgsql-deparser-0.7.4.tgz", - "integrity": "sha512-XXCOVEUI1G+Teg1oZE6ZfSJqNSRKbei/7bVcc1uwQEWc2LxOk1Y6NN+UQQulnwLz0nvKueHrMAyL8/aam2fMWg==", - "license": "MIT", - "dependencies": { - "@pgsql/types": "^17.6.2", - "pgsql-deparser": "17.18.0" - } - }, - "node_modules/plpgsql-parser": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/plpgsql-parser/-/plpgsql-parser-0.5.5.tgz", - "integrity": "sha512-HgWqHTaOKiyNkO5EhpO7kugWYNmpgcCB6EJKlYm+wPiWpHTwpG52/3gGqm9NyAJ3kH0p1M4cBecNA7dDepmVgg==", - "license": "MIT", - "dependencies": { - "@libpg-query/parser": "^17.6.3", - "@pgsql/traverse": "17.2.4", - "@pgsql/types": "^17.6.2", - "pgsql-deparser": "17.18.0", - "plpgsql-deparser": "0.7.4" - } - }, - "node_modules/postgres-array": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz", - "integrity": "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==", - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/postgres-bytea": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.1.tgz", - "integrity": "sha512-5+5HqXnsZPE65IJZSMkZtURARZelel2oXUEO8rH83VS/hxH5vv1uHquPg5wZs8yMAfdv971IU+kcPUczi7NVBQ==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/postgres-date": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-1.0.7.tgz", - "integrity": "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/postgres-interval": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-1.2.0.tgz", - "integrity": "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==", - "license": "MIT", - "dependencies": { - "xtend": "^4.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/proc-log": { "version": "6.1.0", - "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-6.1.0.tgz", - "integrity": "sha512-iG+GYldRf2BQ0UDUAd6JQ/RwzaQy6mXmsk/IzlYyal4A4SNFw54MeH4/tLkF4I5WoWG9SQwuqWzS99jaFQHBuQ==", "dev": true, "license": "ISC", "engines": { @@ -884,8 +764,6 @@ }, "node_modules/read-cmd-shim": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/read-cmd-shim/-/read-cmd-shim-6.0.0.tgz", - "integrity": "sha512-1zM5HuOfagXCBWMN83fuFI/x+T/UhZ7k+KIzhrHXcQoeX5+7gmaDYjELQHmmzIodumBHeByBJT4QYS7ufAgs7A==", "dev": true, "license": "ISC", "engines": { @@ -894,8 +772,6 @@ }, "node_modules/signal-exit": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", "dev": true, "license": "ISC", "engines": { @@ -905,28 +781,8 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/split2": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", - "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==", - "license": "ISC", - "engines": { - "node": ">= 10.x" - } - }, - "node_modules/strfy-js": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/strfy-js/-/strfy-js-3.2.1.tgz", - "integrity": "sha512-HSw2lkUJVPZ75I+E3HM7UqHMKvBCwjRt1MIAxPPNtLFjuqCrnDVKQQGfotdj/3qHxuhB6NDQ1rYmNjVpPBiNEA==", - "license": "MIT", - "dependencies": { - "minimatch": "^10.1.1" - } - }, "node_modules/supabase": { "version": "2.76.16", - "resolved": "https://registry.npmjs.org/supabase/-/supabase-2.76.16.tgz", - "integrity": "sha512-hZ1Kg88+pOlSAzvpas5RYLW6Op6a1OTUhOm8weP8vJf0emE/GO8rrou57irL3hopOwwSnye19VnxplW5+3g1zA==", "dev": true, "hasInstallScript": true, "license": "MIT", @@ -945,8 +801,6 @@ }, "node_modules/tar": { "version": "7.5.9", - "resolved": "https://registry.npmjs.org/tar/-/tar-7.5.9.tgz", - "integrity": "sha512-BTLcK0xsDh2+PUe9F6c2TlRp4zOOBMTkoQHQIWSIzI0R7KG46uEwq4OPk2W7bZcprBMsuaeFsqwYr7pjh6CuHg==", "dev": true, "license": "BlueOak-1.0.0", "dependencies": { @@ -960,16 +814,8 @@ "node": ">=18" } }, - "node_modules/undici-types": { - "version": "7.18.2", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.18.2.tgz", - "integrity": "sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w==", - "license": "MIT" - }, "node_modules/web-streams-polyfill": { "version": "3.3.3", - "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz", - "integrity": "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==", "dev": true, "license": "MIT", "engines": { @@ -978,8 +824,6 @@ }, "node_modules/write-file-atomic": { "version": "7.0.1", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-7.0.1.tgz", - "integrity": "sha512-OTIk8iR8/aCRWBqvxrzxR0hgxWpnYBblY1S5hDWBQfk/VFmJwzmJgQFN3WsoUKHISv2eAwe+PpbUzyL1CKTLXg==", "dev": true, "license": "ISC", "dependencies": { @@ -989,33 +833,13 @@ "node": "^20.17.0 || >=22.9.0" } }, - "node_modules/xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", - "license": "MIT", - "engines": { - "node": ">=0.4" - } - }, "node_modules/yallist": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-5.0.0.tgz", - "integrity": "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==", "dev": true, "license": "BlueOak-1.0.0", "engines": { "node": ">=18" } - }, - "node_modules/zod": { - "version": "4.3.6", - "resolved": "https://registry.npmjs.org/zod/-/zod-4.3.6.tgz", - "integrity": "sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/colinhacks" - } } } } diff --git a/package.json b/package.json index 5fcbd903..600cb9b0 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "private": true, "dependencies": { - "@supabase/pg-delta": "https://pkg.pr.new/supabase/pg-toolbelt/@supabase/pg-delta@f56ff1e" + "@supabase/pg-delta": "file:/Users/avallete/Documents/Programming/Supa/pg-toolbelt/packages/pg-delta" }, "devDependencies": { "supabase": "^2.76.16" diff --git a/scripts/declarative-dbdev-init.sh b/scripts/declarative-dbdev-init.sh index 3f0ddd83..3ac31149 100755 --- a/scripts/declarative-dbdev-init.sh +++ b/scripts/declarative-dbdev-init.sh @@ -21,10 +21,10 @@ DBDEV_DIR="${DBDEV_DIR:-${SCRIPT_DIR}/..}" SHADOW_IMAGE="${SHADOW_IMAGE:-supabase/postgres:15.8.1.085}" SHADOW_CONTAINER="pgdelta-dbdev-shadow" SHADOW_PORT="${SHADOW_PORT:-6544}" -SHADOW_URL="postgres://postgres:postgres@localhost:${SHADOW_PORT}/postgres" +SHADOW_URL="postgres://supabase_admin:postgres@localhost:${SHADOW_PORT}/postgres" SUPABASE_DB_PORT=54322 -SUPABASE_DB_URL="postgres://postgres:postgres@localhost:${SUPABASE_DB_PORT}/postgres" +SUPABASE_DB_URL="postgres://supabase_admin:postgres@localhost:${SUPABASE_DB_PORT}/postgres" PGDELTA="${PGDELTA:-npx pgdelta}" OUTPUT_DIR="${OUTPUT_DIR:-${DBDEV_DIR}/declarative-schemas}" @@ -107,8 +107,7 @@ if [ -z "$SKIP_VERIFY" ]; then echo "Applying declarative schema to shadow DB..." $PGDELTA declarative apply \ --path "$OUTPUT_DIR" \ - --target "$SHADOW_URL" \ - --verbose + --target "$SHADOW_URL" echo "Verifying roundtrip: diff shadow DB vs supabase DB (expect 0 changes)..." VERIFY_OPTS=( diff --git a/scripts/declarative-dbdev-update.sh b/scripts/declarative-dbdev-update.sh index 63cdee4c..9a9edce2 100755 --- a/scripts/declarative-dbdev-update.sh +++ b/scripts/declarative-dbdev-update.sh @@ -19,7 +19,7 @@ set -e SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" DBDEV_DIR="${DBDEV_DIR:-${SCRIPT_DIR}/..}" -SHADOW_IMAGE="${SHADOW_IMAGE:-supabase/postgres:15.6.1.143}" +SHADOW_IMAGE="${SHADOW_IMAGE:-supabase/postgres:15.8.1.085}" SHADOW_CONTAINER="pgdelta-dbdev-shadow" SHADOW_PORT="${SHADOW_PORT:-6544}" SHADOW_URL="postgres://postgres:postgres@localhost:${SHADOW_PORT}/postgres" From d6c2e4716217c73bde518726a2f016d37bc34224 Mon Sep 17 00:00:00 2001 From: avallete Date: Wed, 4 Mar 2026 20:19:56 +0100 Subject: [PATCH 3/3] wip: add PR package --- package-lock.json | 1081 +++++++++++++++++++++++++-------------------- package.json | 2 +- 2 files changed, 605 insertions(+), 478 deletions(-) diff --git a/package-lock.json b/package-lock.json index 5a2f0bd3..bcd0434f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5,428 +5,348 @@ "packages": { "": { "dependencies": { - "@supabase/pg-delta": "file:/Users/avallete/Documents/Programming/Supa/pg-toolbelt/packages/pg-delta" + "@supabase/pg-delta": "https://pkg.pr.new/supabase/pg-toolbelt/@supabase/pg-delta@7cb3a19" }, "devDependencies": { "supabase": "^2.76.16" } }, - "../pg-toolbelt/node_modules/.bun/@pgsql+traverse@17.2.4/node_modules/@pgsql/traverse": { - "version": "17.2.4", + "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==", "license": "MIT", "dependencies": { - "@pgsql/types": "^17.6.2", - "pg-proto-parser": "1.30.4" + "@babel/helper-validator-identifier": "^7.28.5", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" }, - "devDependencies": { - "makage": "^0.1.8" + "engines": { + "node": ">=6.9.0" } }, - "../pg-toolbelt/node_modules/.bun/@stricli+core@1.2.5/node_modules/@stricli/core": { - "version": "1.2.5", - "license": "Apache-2.0", - "devDependencies": { - "@types/chai": "^4.3.11", - "@types/fs-extra": "^11.0.4", - "@types/sinon": "^17.0.2", - "@typescript-eslint/eslint-plugin": "^8.2.0", - "@typescript-eslint/parser": "^8.2.0", - "eslint": "^8.57.0", - "eslint-plugin-header": "^3.1.1", - "eslint-plugin-import": "^2.29.1", - "eslint-plugin-prettier": "^5.1.3", - "fs-extra": "^11.2.0", - "prettier": "^3.2.5", - "sinon": "^17.0.1", - "tsup": "^8.0.1", - "tsx": "^4.8.2", - "typescript": "5.6.x" - } - }, - "../pg-toolbelt/node_modules/.bun/@testcontainers+postgresql@11.11.0/node_modules/@testcontainers/postgresql": { - "version": "11.11.0", - "dev": true, + "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==", "license": "MIT", "dependencies": { - "testcontainers": "^11.11.0" + "@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" }, - "devDependencies": { - "@types/pg": "^8.16.0", - "pg": "^8.16.3" + "engines": { + "node": ">=6.9.0" } }, - "../pg-toolbelt/node_modules/.bun/@ts-safeql+sql-tag@0.2.1/node_modules/@ts-safeql/sql-tag": { - "version": "0.2.1", + "node_modules/@babel/generator/node_modules/@babel/types": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.0.tgz", + "integrity": "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==", "license": "MIT", - "devDependencies": { - "@types/node": "^18.15.11", - "@typescript-eslint/eslint-plugin": "^7.8.0", - "@typescript-eslint/parser": "^7.8.0", - "eslint": "^8.57.0", - "typescript": "^5.4.5", - "unbuild": "^2.0.0", - "vitest": "^1.6.0" + "dependencies": { + "@babel/helper-string-parser": "^7.27.1", + "@babel/helper-validator-identifier": "^7.28.5" + }, + "engines": { + "node": ">=6.9.0" } }, - "../pg-toolbelt/node_modules/.bun/@tsconfig+node-ts@23.6.4/node_modules/@tsconfig/node-ts": { - "version": "23.6.4", - "dev": true, - "license": "MIT" + "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==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } }, - "../pg-toolbelt/node_modules/.bun/@tsconfig+node24@24.0.4/node_modules/@tsconfig/node24": { - "version": "24.0.4", - "dev": true, - "license": "MIT" + "node_modules/@babel/helper-string-parser": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", + "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } }, - "../pg-toolbelt/node_modules/.bun/@types+bun@1.3.9/node_modules/@types/bun": { - "version": "1.3.9", - "dev": true, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", + "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", "license": "MIT", - "dependencies": { - "bun-types": "1.3.9" + "engines": { + "node": ">=6.9.0" } }, - "../pg-toolbelt/node_modules/.bun/@types+debug@4.1.12/node_modules/@types/debug": { - "version": "4.1.12", - "dev": true, + "node_modules/@babel/parser": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.0.tgz", + "integrity": "sha512-IyDgFV5GeDUVX4YdF/3CPULtVGSXXMLh1xVIgdCgxApktqnQV0r7/8Nqthg+8YLGaAtdyIlo2qIdZrbCv4+7ww==", "license": "MIT", "dependencies": { - "@types/ms": "*" + "@babel/types": "^7.29.0" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" } }, - "../pg-toolbelt/node_modules/.bun/@types+node@24.10.13/node_modules/@types/node": { - "version": "24.10.13", - "dev": true, + "node_modules/@babel/parser/node_modules/@babel/types": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.0.tgz", + "integrity": "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==", "license": "MIT", "dependencies": { - "undici-types": "~7.16.0" + "@babel/helper-string-parser": "^7.27.1", + "@babel/helper-validator-identifier": "^7.28.5" + }, + "engines": { + "node": ">=6.9.0" } }, - "../pg-toolbelt/node_modules/.bun/@types+pg@8.16.0/node_modules/@types/pg": { - "version": "8.16.0", - "dev": true, + "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==", "license": "MIT", "dependencies": { - "@types/node": "*", - "pg-protocol": "*", - "pg-types": "^2.2.0" + "@babel/code-frame": "^7.28.6", + "@babel/parser": "^7.28.6", + "@babel/types": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" } }, - "../pg-toolbelt/node_modules/.bun/chalk@5.6.2/node_modules/chalk": { - "version": "5.6.2", + "node_modules/@babel/template/node_modules/@babel/types": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.0.tgz", + "integrity": "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==", "license": "MIT", - "devDependencies": { - "@types/node": "^16.11.10", - "ava": "^3.15.0", - "c8": "^7.10.0", - "color-convert": "^2.0.1", - "execa": "^6.0.0", - "log-update": "^5.0.0", - "matcha": "^0.7.0", - "tsd": "^0.19.0", - "xo": "^0.57.0", - "yoctodelay": "^2.0.0" + "dependencies": { + "@babel/helper-string-parser": "^7.27.1", + "@babel/helper-validator-identifier": "^7.28.5" }, "engines": { - "node": "^12.17.0 || ^14.13 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "node": ">=6.9.0" } }, - "../pg-toolbelt/node_modules/.bun/debug@4.4.3/node_modules/debug": { - "version": "4.4.3", + "node_modules/@babel/traverse": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.28.5.tgz", + "integrity": "sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ==", "license": "MIT", "dependencies": { - "ms": "^2.1.3" - }, - "devDependencies": { - "brfs": "^2.0.1", - "browserify": "^16.2.3", - "coveralls": "^3.0.2", - "karma": "^3.1.4", - "karma-browserify": "^6.0.0", - "karma-chrome-launcher": "^2.2.0", - "karma-mocha": "^1.3.0", - "mocha": "^5.2.0", - "mocha-lcov-reporter": "^1.2.0", - "sinon": "^14.0.0", - "xo": "^0.23.0" + "@babel/code-frame": "^7.27.1", + "@babel/generator": "^7.28.5", + "@babel/helper-globals": "^7.28.0", + "@babel/parser": "^7.28.5", + "@babel/template": "^7.27.2", + "@babel/types": "^7.28.5", + "debug": "^4.3.1" }, "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } + "node": ">=6.9.0" } }, - "../pg-toolbelt/node_modules/.bun/dedent@1.7.1/node_modules/dedent": { - "version": "1.7.1", - "dev": true, + "node_modules/@babel/types": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.5.tgz", + "integrity": "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==", "license": "MIT", - "devDependencies": { - "@babel/cli": "^7.21.5", - "@babel/preset-env": "^7.23.3", - "@babel/preset-typescript": "^7.23.3", - "@release-it/conventional-changelog": "^8.0.1", - "@types/babel-plugin-macros": "^3.1.0", - "@types/bun": "^1.3.4", - "@types/eslint": "^8.44.7", - "@types/jest": "^29.5.3", - "@typescript-eslint/eslint-plugin": "^6.10.0", - "@typescript-eslint/parser": "^6.10.0", - "babel-plugin-add-module-exports": "^1.0.4", - "babel-plugin-tester": "^11.0.4", - "console-fail-test": "^0.2.3", - "cspell": "^8.0.0", - "eslint": "^8.53.0", - "eslint-plugin-deprecation": "^2.0.0", - "eslint-plugin-eslint-comments": "^3.2.0", - "eslint-plugin-jest": "^27.6.0", - "eslint-plugin-jsdoc": "^46.9.0", - "eslint-plugin-jsonc": "^2.10.0", - "eslint-plugin-markdown": "^3.0.1", - "eslint-plugin-n": "^16.3.1", - "eslint-plugin-no-only-tests": "^3.1.0", - "eslint-plugin-perfectionist": "^2.3.0", - "eslint-plugin-regexp": "^2.1.1", - "eslint-plugin-yml": "^1.10.0", - "husky": "^8.0.3", - "jest": "^29.7.0", - "jsonc-eslint-parser": "^2.4.0", - "knip": "^5.75.0", - "lint-staged": "^15.1.0", - "markdownlint": "^0.31.1", - "markdownlint-cli": "^0.37.0", - "npm-package-json-lint": "^7.1.0", - "npm-package-json-lint-config-default": "^6.0.0", - "prettier": "^3.0.3", - "prettier-plugin-curly": "^0.1.3", - "prettier-plugin-packagejson": "^2.4.6", - "release-it": "^17.0.0", - "should-semantic-release": "^0.2.1", - "tsup": "^7.2.0", - "typescript": "^5.2.2", - "yaml-eslint-parser": "^1.2.2" - }, - "peerDependencies": { - "babel-plugin-macros": "^3.1.0" + "dependencies": { + "@babel/helper-string-parser": "^7.27.1", + "@babel/helper-validator-identifier": "^7.28.5" }, - "peerDependenciesMeta": { - "babel-plugin-macros": { - "optional": true - } + "engines": { + "node": ">=6.9.0" } }, - "../pg-toolbelt/node_modules/.bun/knip@5.83.1+9cdfcf6afadfcf55/node_modules/knip": { - "version": "5.83.1", + "node_modules/@isaacs/fs-minipass": { + "version": "4.0.1", "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/webpro" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/knip" - } - ], "license": "ISC", "dependencies": { - "@nodelib/fs.walk": "^1.2.3", - "fast-glob": "^3.3.3", - "formatly": "^0.3.0", - "jiti": "^2.6.0", - "js-yaml": "^4.1.1", - "minimist": "^1.2.8", - "oxc-resolver": "^11.15.0", - "picocolors": "^1.1.1", - "picomatch": "^4.0.1", - "smol-toml": "^1.5.2", - "strip-json-comments": "5.0.3", - "zod": "^4.1.11" - }, - "bin": { - "knip": "bin/knip.js", - "knip-bun": "bin/knip-bun.js" - }, - "devDependencies": { - "@jest/types": "^29.6.3", - "@types/bun": "^1.3.3", - "@types/js-yaml": "^4.0.9", - "@types/minimist": "^1.2.5", - "@types/picomatch": "^4.0.1", - "@types/webpack": "^5.28.5", - "@wdio/types": "^9.20.0", - "codeclimate-types": "^0.3.1", - "glob-bin": "^1.0.0", - "tsx": "^4.20.3", - "typescript": "^5.5.2" + "minipass": "^7.0.4" }, "engines": { - "node": ">=18.18.0" - }, - "peerDependencies": { - "@types/node": ">=18", - "typescript": ">=5.0.4 <7" + "node": ">=18.0.0" } }, - "../pg-toolbelt/node_modules/.bun/pg@8.18.0+32ccf17b773ffb11/node_modules/pg": { - "version": "8.18.0", + "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==", "license": "MIT", "dependencies": { - "pg-connection-string": "^2.11.0", - "pg-pool": "^3.11.0", - "pg-protocol": "^1.11.0", - "pg-types": "2.2.0", - "pgpass": "1.0.5" - }, - "devDependencies": { - "@cloudflare/vitest-pool-workers": "0.8.23", - "@cloudflare/workers-types": "^4.20230404.0", - "async": "2.6.4", - "bluebird": "3.7.2", - "co": "4.6.0", - "pg-copy-streams": "0.3.0", - "typescript": "^4.0.3", - "vitest": "~3.0.9", - "wrangler": "^3.x" - }, + "@jridgewell/sourcemap-codec": "^1.5.0", + "@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==", + "license": "MIT", "engines": { - "node": ">= 16.0.0" - }, - "optionalDependencies": { - "pg-cloudflare": "^1.3.0" - }, - "peerDependencies": { - "pg-native": ">=3.0.1" - }, - "peerDependenciesMeta": { - "pg-native": { - "optional": true - } + "node": ">=6.0.0" } }, - "../pg-toolbelt/node_modules/.bun/plpgsql-parser@0.5.4/node_modules/plpgsql-parser": { - "version": "0.5.4", + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "license": "MIT" + }, + "node_modules/@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==", "license": "MIT", "dependencies": { - "@libpg-query/parser": "^17.6.3", - "@pgsql/traverse": "17.2.4", - "@pgsql/types": "^17.6.2", - "pgsql-deparser": "17.17.2", - "plpgsql-deparser": "0.7.3" - }, - "devDependencies": { - "makage": "^0.1.8" + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" } }, - "../pg-toolbelt/node_modules/.bun/testcontainers@11.11.0/node_modules/testcontainers": { - "version": "11.11.0", - "dev": true, - "license": "MIT", + "node_modules/@launchql/protobufjs": { + "version": "7.2.6", + "resolved": "https://registry.npmjs.org/@launchql/protobufjs/-/protobufjs-7.2.6.tgz", + "integrity": "sha512-vwi1nG2/heVFsIMHQU1KxTjUp5c757CTtRAZn/jutApCkFlle1iv8tzM/DHlSZJKDldxaYqnNYTg0pTyp8Bbtg==", + "hasInstallScript": true, + "license": "BSD-3-Clause", "dependencies": { - "@balena/dockerignore": "^1.0.2", - "@types/dockerode": "^3.3.47", - "archiver": "^7.0.1", - "async-lock": "^1.4.1", - "byline": "^5.0.0", - "debug": "^4.4.3", - "docker-compose": "^1.3.0", - "dockerode": "^4.0.9", - "get-port": "^7.1.0", - "proper-lockfile": "^4.1.2", - "properties-reader": "^2.3.0", - "ssh-remote-port-forward": "^1.0.4", - "tar-fs": "^3.1.1", - "tmp": "^0.2.5", - "undici": "^7.16.0" - }, - "devDependencies": { - "@types/archiver": "^7.0.0", - "@types/async-lock": "^1.4.2", - "@types/byline": "^4.2.36", - "@types/debug": "^4.1.12", - "@types/proper-lockfile": "^4.1.4", - "@types/properties-reader": "^2.1.3", - "@types/tar-fs": "^2.0.4", - "@types/tmp": "^0.2.6" - } - }, - "../pg-toolbelt/node_modules/.bun/typescript@5.9.3/node_modules/typescript": { - "version": "5.9.3", - "dev": true, - "license": "Apache-2.0", - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/codegen": "^2.0.4", + "@protobufjs/eventemitter": "^1.1.0", + "@protobufjs/fetch": "^1.1.0", + "@protobufjs/float": "^1.0.2", + "@protobufjs/inquire": "^1.1.0", + "@protobufjs/path": "^1.1.2", + "@protobufjs/pool": "^1.1.0", + "@protobufjs/utf8": "^1.1.0", + "@types/node": ">=13.7.0", + "long": "^5.0.0" }, - "devDependencies": { - "@dprint/formatter": "^0.4.1", - "@dprint/typescript": "0.93.4", - "@esfx/canceltoken": "^1.0.0", - "@eslint/js": "^9.20.0", - "@octokit/rest": "^21.1.1", - "@types/chai": "^4.3.20", - "@types/diff": "^7.0.1", - "@types/minimist": "^1.2.5", - "@types/mocha": "^10.0.10", - "@types/ms": "^0.7.34", - "@types/node": "latest", - "@types/source-map-support": "^0.5.10", - "@types/which": "^3.0.4", - "@typescript-eslint/rule-tester": "^8.24.1", - "@typescript-eslint/type-utils": "^8.24.1", - "@typescript-eslint/utils": "^8.24.1", - "azure-devops-node-api": "^14.1.0", - "c8": "^10.1.3", - "chai": "^4.5.0", - "chokidar": "^4.0.3", - "diff": "^7.0.0", - "dprint": "^0.49.0", - "esbuild": "^0.25.0", - "eslint": "^9.20.1", - "eslint-formatter-autolinkable-stylish": "^1.4.0", - "eslint-plugin-regexp": "^2.7.0", - "fast-xml-parser": "^4.5.2", - "glob": "^10.4.5", - "globals": "^15.15.0", - "hereby": "^1.10.0", - "jsonc-parser": "^3.3.1", - "knip": "^5.44.4", - "minimist": "^1.2.8", - "mocha": "^10.8.2", - "mocha-fivemat-progress-reporter": "^0.1.0", - "monocart-coverage-reports": "^2.12.1", - "ms": "^2.1.3", - "picocolors": "^1.1.1", - "playwright": "^1.50.1", - "source-map-support": "^0.5.21", - "tslib": "^2.8.1", - "typescript": "^5.7.3", - "typescript-eslint": "^8.24.1", - "which": "^3.0.1" - }, - "engines": { - "node": ">=14.17" - } - }, - "../pg-toolbelt/node_modules/.bun/zod@4.3.6/node_modules/zod": { - "version": "4.3.6", + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/@libpg-query/parser": { + "version": "17.6.3", + "resolved": "https://registry.npmjs.org/@libpg-query/parser/-/parser-17.6.3.tgz", + "integrity": "sha512-AvbS7b9GJZfCzqt4tLMqTaYK7Css9pJRTA2dKWLoTlob/XO2VNc30Q3g9DmxNBmokVTrmibkn/dy9bw8hfosQQ==", + "license": "LICENSE IN LICENSE", + "dependencies": { + "@launchql/protobufjs": "7.2.6", + "@pgsql/types": "^17.6.0" + } + }, + "node_modules/@pgsql/quotes": { + "version": "17.1.0", + "resolved": "https://registry.npmjs.org/@pgsql/quotes/-/quotes-17.1.0.tgz", + "integrity": "sha512-J/H+LcrENBpYgL45WW6aTjb5Yk4tX4+AmB2/k8KZa+Zh3wiCtqmNIag+HZz5HmWaF6EZK9ZGC95NBD1fs+rUvg==", + "license": "MIT" + }, + "node_modules/@pgsql/traverse": { + "version": "17.2.4", + "resolved": "https://registry.npmjs.org/@pgsql/traverse/-/traverse-17.2.4.tgz", + "integrity": "sha512-7dnst2U3qXXSFbS+HvVktW/C4aVKe/niaRxZ1cfhmdy9E7SMYM0OukFO7gvoZb6I3dnKm/eTfpv23JPKq5z6DA==", "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/colinhacks" + "dependencies": { + "@pgsql/types": "^17.6.2", + "pg-proto-parser": "1.30.4" } }, - "../pg-toolbelt/packages/pg-delta": { - "name": "@supabase/pg-delta", + "node_modules/@pgsql/types": { + "version": "17.6.2", + "resolved": "https://registry.npmjs.org/@pgsql/types/-/types-17.6.2.tgz", + "integrity": "sha512-1UtbELdbqNdyOShhrVfSz3a1gDi0s9XXiQemx+6QqtsrXe62a6zOGU+vjb2GRfG5jeEokI1zBBcfD42enRv0Rw==", + "license": "MIT" + }, + "node_modules/@protobufjs/aspromise": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", + "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/base64": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", + "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/codegen": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", + "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/eventemitter": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", + "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/fetch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", + "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==", + "license": "BSD-3-Clause", + "dependencies": { + "@protobufjs/aspromise": "^1.1.1", + "@protobufjs/inquire": "^1.1.0" + } + }, + "node_modules/@protobufjs/float": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", + "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/inquire": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", + "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/path": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", + "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/pool": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", + "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/utf8": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", + "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==", + "license": "BSD-3-Clause" + }, + "node_modules/@stricli/core": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@stricli/core/-/core-1.2.6.tgz", + "integrity": "sha512-j5fa1wyOLrP9WJqqLFEJeQviqb3cK46K+FXTuISEkG/H5C820YfKDoVQ3CDVdM5WLhEx1ARdpiW6+hU4tYHjCQ==", + "license": "Apache-2.0" + }, + "node_modules/@supabase/pg-delta": { "version": "1.0.0-alpha.4", + "resolved": "https://pkg.pr.new/supabase/pg-toolbelt/@supabase/pg-delta@7cb3a19", + "integrity": "sha512-emPkV31AzayC2AxvBzNKMMQPb8VaJSyKGKKP/r6DmpKMtMbNku0MnEMSYTWYUixzniF/f3l0nL9Z4KMbpk/JHw==", "license": "MIT", "dependencies": { "@stricli/core": "^1.2.4", - "@supabase/pg-topo": "workspace:*", + "@supabase/pg-topo": "https://pkg.pr.new/supabase/pg-toolbelt/@supabase/pg-topo@7cb3a19bb27e78709cbc6a6d7e299a47e4d96371", "@ts-safeql/sql-tag": "^0.2.0", "chalk": "^5.6.2", "debug": "^4.3.7", @@ -436,149 +356,35 @@ "bin": { "pgdelta": "dist/cli/bin/cli.js" }, - "devDependencies": { - "@tsconfig/node-ts": "^23.6.2", - "@tsconfig/node24": "^24.0.3", - "@types/bun": "^1.3.9", - "@types/debug": "^4.1.12", - "@types/node": "^24.10.4", - "@types/pg": "^8.11.10", - "dedent": "^1.7.1", - "knip": "^5.75.2", - "testcontainers": "^11.10.0", - "typescript": "^5.9.3" - }, "engines": { "node": ">=20.0.0" } }, - "../pg-toolbelt/packages/pg-delta/node_modules/@stricli/core": { - "resolved": "../pg-toolbelt/node_modules/.bun/@stricli+core@1.2.5/node_modules/@stricli/core", - "link": true - }, - "../pg-toolbelt/packages/pg-delta/node_modules/@supabase/pg-topo": { - "resolved": "../pg-toolbelt/packages/pg-topo", - "link": true - }, - "../pg-toolbelt/packages/pg-delta/node_modules/@ts-safeql/sql-tag": { - "resolved": "../pg-toolbelt/node_modules/.bun/@ts-safeql+sql-tag@0.2.1/node_modules/@ts-safeql/sql-tag", - "link": true - }, - "../pg-toolbelt/packages/pg-delta/node_modules/@tsconfig/node-ts": { - "resolved": "../pg-toolbelt/node_modules/.bun/@tsconfig+node-ts@23.6.4/node_modules/@tsconfig/node-ts", - "link": true - }, - "../pg-toolbelt/packages/pg-delta/node_modules/@tsconfig/node24": { - "resolved": "../pg-toolbelt/node_modules/.bun/@tsconfig+node24@24.0.4/node_modules/@tsconfig/node24", - "link": true - }, - "../pg-toolbelt/packages/pg-delta/node_modules/@types/bun": { - "resolved": "../pg-toolbelt/node_modules/.bun/@types+bun@1.3.9/node_modules/@types/bun", - "link": true - }, - "../pg-toolbelt/packages/pg-delta/node_modules/@types/debug": { - "resolved": "../pg-toolbelt/node_modules/.bun/@types+debug@4.1.12/node_modules/@types/debug", - "link": true - }, - "../pg-toolbelt/packages/pg-delta/node_modules/@types/node": { - "resolved": "../pg-toolbelt/node_modules/.bun/@types+node@24.10.13/node_modules/@types/node", - "link": true - }, - "../pg-toolbelt/packages/pg-delta/node_modules/@types/pg": { - "resolved": "../pg-toolbelt/node_modules/.bun/@types+pg@8.16.0/node_modules/@types/pg", - "link": true - }, - "../pg-toolbelt/packages/pg-delta/node_modules/chalk": { - "resolved": "../pg-toolbelt/node_modules/.bun/chalk@5.6.2/node_modules/chalk", - "link": true - }, - "../pg-toolbelt/packages/pg-delta/node_modules/debug": { - "resolved": "../pg-toolbelt/node_modules/.bun/debug@4.4.3/node_modules/debug", - "link": true - }, - "../pg-toolbelt/packages/pg-delta/node_modules/dedent": { - "resolved": "../pg-toolbelt/node_modules/.bun/dedent@1.7.1/node_modules/dedent", - "link": true - }, - "../pg-toolbelt/packages/pg-delta/node_modules/knip": { - "resolved": "../pg-toolbelt/node_modules/.bun/knip@5.83.1+9cdfcf6afadfcf55/node_modules/knip", - "link": true - }, - "../pg-toolbelt/packages/pg-delta/node_modules/pg": { - "resolved": "../pg-toolbelt/node_modules/.bun/pg@8.18.0+32ccf17b773ffb11/node_modules/pg", - "link": true - }, - "../pg-toolbelt/packages/pg-delta/node_modules/testcontainers": { - "resolved": "../pg-toolbelt/node_modules/.bun/testcontainers@11.11.0/node_modules/testcontainers", - "link": true - }, - "../pg-toolbelt/packages/pg-delta/node_modules/typescript": { - "resolved": "../pg-toolbelt/node_modules/.bun/typescript@5.9.3/node_modules/typescript", - "link": true - }, - "../pg-toolbelt/packages/pg-delta/node_modules/zod": { - "resolved": "../pg-toolbelt/node_modules/.bun/zod@4.3.6/node_modules/zod", - "link": true - }, - "../pg-toolbelt/packages/pg-topo": { - "name": "@supabase/pg-topo", + "node_modules/@supabase/pg-topo": { "version": "1.0.0-alpha.0", + "resolved": "https://pkg.pr.new/supabase/pg-toolbelt/@supabase/pg-topo@7cb3a19bb27e78709cbc6a6d7e299a47e4d96371", + "integrity": "sha512-ku7OOhiIpS6DRRGTZwaWKfJ5MrTljCLZxuXVSkEWsJaZdnNaz9p0nbOmyGRppOOtSDuXM+S9aQTQFJBu/sG3aQ==", "license": "MIT", "dependencies": { "@pgsql/traverse": "^17.2.4", "plpgsql-parser": "^0.5.4" - }, - "devDependencies": { - "@testcontainers/postgresql": "^11.11.0", - "@types/bun": "^1.3.9", - "knip": "^5.75.2", - "testcontainers": "^11.11.0", - "typescript": "^5.9.3" } }, - "../pg-toolbelt/packages/pg-topo/node_modules/@pgsql/traverse": { - "resolved": "../pg-toolbelt/node_modules/.bun/@pgsql+traverse@17.2.4/node_modules/@pgsql/traverse", - "link": true - }, - "../pg-toolbelt/packages/pg-topo/node_modules/@testcontainers/postgresql": { - "resolved": "../pg-toolbelt/node_modules/.bun/@testcontainers+postgresql@11.11.0/node_modules/@testcontainers/postgresql", - "link": true - }, - "../pg-toolbelt/packages/pg-topo/node_modules/@types/bun": { - "resolved": "../pg-toolbelt/node_modules/.bun/@types+bun@1.3.9/node_modules/@types/bun", - "link": true - }, - "../pg-toolbelt/packages/pg-topo/node_modules/knip": { - "resolved": "../pg-toolbelt/node_modules/.bun/knip@5.83.1+9cdfcf6afadfcf55/node_modules/knip", - "link": true - }, - "../pg-toolbelt/packages/pg-topo/node_modules/plpgsql-parser": { - "resolved": "../pg-toolbelt/node_modules/.bun/plpgsql-parser@0.5.4/node_modules/plpgsql-parser", - "link": true - }, - "../pg-toolbelt/packages/pg-topo/node_modules/testcontainers": { - "resolved": "../pg-toolbelt/node_modules/.bun/testcontainers@11.11.0/node_modules/testcontainers", - "link": true - }, - "../pg-toolbelt/packages/pg-topo/node_modules/typescript": { - "resolved": "../pg-toolbelt/node_modules/.bun/typescript@5.9.3/node_modules/typescript", - "link": true + "node_modules/@ts-safeql/sql-tag": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/@ts-safeql/sql-tag/-/sql-tag-0.2.1.tgz", + "integrity": "sha512-TaDtQjobByWIn95dM2H2ucltJyL8w2B9mZdr6/1o1ZdbLRLS16XqzY6ssWkviHomQwIxB+CfK3Qz5a6AHDswsA==", + "license": "MIT" }, - "node_modules/@isaacs/fs-minipass": { - "version": "4.0.1", - "dev": true, - "license": "ISC", + "node_modules/@types/node": { + "version": "25.3.3", + "resolved": "https://registry.npmjs.org/@types/node/-/node-25.3.3.tgz", + "integrity": "sha512-DpzbrH7wIcBaJibpKo9nnSQL0MTRdnWttGyE5haGwK86xgMOkFLp7vEyfQPGLOJh5wNYiJ3V9PmUMDhV9u8kkQ==", + "license": "MIT", "dependencies": { - "minipass": "^7.0.4" - }, - "engines": { - "node": ">=18.0.0" + "undici-types": "~7.18.0" } }, - "node_modules/@supabase/pg-delta": { - "resolved": "../pg-toolbelt/packages/pg-delta", - "link": true - }, "node_modules/agent-base": { "version": "7.1.4", "dev": true, @@ -587,6 +393,15 @@ "node": ">= 14" } }, + "node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", + "license": "MIT", + "engines": { + "node": "18 || 20 || >=22" + } + }, "node_modules/bin-links": { "version": "6.0.0", "dev": true, @@ -602,6 +417,39 @@ "node": "^20.17.0 || >=22.9.0" } }, + "node_modules/brace-expansion": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.4.tgz", + "integrity": "sha512-h+DEnpVvxmfVefa4jFbCf5HdH5YMDXRsmKflpf1pILZWRFlTbJpxeU55nJl4Smt5HQaGzg1o6RHFPJaOqnmBDg==", + "license": "MIT", + "dependencies": { + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/case": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/case/-/case-1.6.3.tgz", + "integrity": "sha512-mzDSXIPaFwVDvZAHqZ9VlbyF4yyXRuX6IvB06WvPYkqJVO24kX1PPhv9bfpKNFZyxYFmmgo03HUiD8iklmJYRQ==", + "license": "(MIT OR GPL-3.0-or-later)", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/chalk": { + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz", + "integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==", + "license": "MIT", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, "node_modules/chownr": { "version": "3.0.0", "dev": true, @@ -628,7 +476,6 @@ }, "node_modules/debug": { "version": "4.4.3", - "dev": true, "license": "MIT", "dependencies": { "ms": "^2.1.3" @@ -642,6 +489,15 @@ } } }, + "node_modules/deepmerge": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/fetch-blob": { "version": "3.2.0", "dev": true, @@ -687,6 +543,45 @@ "node": ">= 14" } }, + "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==", + "license": "MIT" + }, + "node_modules/jsesc": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", + "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", + "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/long": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/long/-/long-5.3.2.tgz", + "integrity": "sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==", + "license": "Apache-2.0" + }, + "node_modules/minimatch": { + "version": "10.2.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.4.tgz", + "integrity": "sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg==", + "license": "BlueOak-1.0.0", + "dependencies": { + "brace-expansion": "^5.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/minipass": { "version": "7.1.3", "dev": true, @@ -708,7 +603,12 @@ }, "node_modules/ms": { "version": "2.1.3", - "dev": true, + "license": "MIT" + }, + "node_modules/nested-obj": { + "version": "0.1.10", + "resolved": "https://registry.npmjs.org/nested-obj/-/nested-obj-0.1.10.tgz", + "integrity": "sha512-5V2kUPrBee/tmoS2p0IJ35BcaJuW1p1yXF5GP8JpXIkDoPbaYeYypAHizUeZkAUxcC7Rago7izWmEq7qa8+Mhw==", "license": "MIT" }, "node_modules/node-domexception": { @@ -754,6 +654,191 @@ "node": "^20.17.0 || >=22.9.0" } }, + "node_modules/pg": { + "version": "8.19.0", + "resolved": "https://registry.npmjs.org/pg/-/pg-8.19.0.tgz", + "integrity": "sha512-QIcLGi508BAHkQ3pJNptsFz5WQMlpGbuBGBaIaXsWK8mel2kQ/rThYI+DbgjUvZrIr7MiuEuc9LcChJoEZK1xQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "pg-connection-string": "^2.11.0", + "pg-pool": "^3.12.0", + "pg-protocol": "^1.12.0", + "pg-types": "2.2.0", + "pgpass": "1.0.5" + }, + "engines": { + "node": ">= 16.0.0" + }, + "optionalDependencies": { + "pg-cloudflare": "^1.3.0" + }, + "peerDependencies": { + "pg-native": ">=3.0.1" + }, + "peerDependenciesMeta": { + "pg-native": { + "optional": true + } + } + }, + "node_modules/pg-cloudflare": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/pg-cloudflare/-/pg-cloudflare-1.3.0.tgz", + "integrity": "sha512-6lswVVSztmHiRtD6I8hw4qP/nDm1EJbKMRhf3HCYaqud7frGysPv7FYJ5noZQdhQtN2xJnimfMtvQq21pdbzyQ==", + "license": "MIT", + "optional": true + }, + "node_modules/pg-connection-string": { + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.11.0.tgz", + "integrity": "sha512-kecgoJwhOpxYU21rZjULrmrBJ698U2RxXofKVzOn5UDj61BPj/qMb7diYUR1nLScCDbrztQFl1TaQZT0t1EtzQ==", + "license": "MIT" + }, + "node_modules/pg-int8": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/pg-int8/-/pg-int8-1.0.1.tgz", + "integrity": "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==", + "license": "ISC", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/pg-pool": { + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.12.0.tgz", + "integrity": "sha512-eIJ0DES8BLaziFHW7VgJEBPi5hg3Nyng5iKpYtj3wbcAUV9A1wLgWiY7ajf/f/oO1wfxt83phXPY8Emztg7ITg==", + "license": "MIT", + "peerDependencies": { + "pg": ">=8.0" + } + }, + "node_modules/pg-proto-parser": { + "version": "1.30.4", + "resolved": "https://registry.npmjs.org/pg-proto-parser/-/pg-proto-parser-1.30.4.tgz", + "integrity": "sha512-+9/n8zfYQVNRc8KGhxxNXO8NA5OKni01IPtit6+C3sLMtcRVVFCj4W0XtrEGFivNjz2qwUtFmRhG8OGMTxs6hg==", + "license": "MIT", + "dependencies": { + "@babel/generator": "^7.23.6", + "@babel/parser": "^7.23.6", + "@babel/traverse": "7.28.5", + "@babel/types": "7.28.5", + "@launchql/protobufjs": "7.2.6", + "case": "1.6.3", + "deepmerge": "4.3.1", + "nested-obj": "^0.1.5", + "strfy-js": "^3.1.5" + } + }, + "node_modules/pg-protocol": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.12.0.tgz", + "integrity": "sha512-uOANXNRACNdElMXJ0tPz6RBM0XQ61nONGAwlt8da5zs/iUOOCLBQOHSXnrC6fMsvtjxbOJrZZl5IScGv+7mpbg==", + "license": "MIT" + }, + "node_modules/pg-types": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/pg-types/-/pg-types-2.2.0.tgz", + "integrity": "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==", + "license": "MIT", + "dependencies": { + "pg-int8": "1.0.1", + "postgres-array": "~2.0.0", + "postgres-bytea": "~1.0.0", + "postgres-date": "~1.0.4", + "postgres-interval": "^1.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/pgpass": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/pgpass/-/pgpass-1.0.5.tgz", + "integrity": "sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug==", + "license": "MIT", + "dependencies": { + "split2": "^4.1.0" + } + }, + "node_modules/pgsql-deparser": { + "version": "17.18.0", + "resolved": "https://registry.npmjs.org/pgsql-deparser/-/pgsql-deparser-17.18.0.tgz", + "integrity": "sha512-LFjdKKYHVo8lUPbOVfO6dRm5L28hBrfqnBrX3DhiC97k6Hsbi+7LXzvL30gahLUbN5dLai9MvsJ8Gbg/7joD1Q==", + "license": "MIT", + "dependencies": { + "@pgsql/quotes": "17.1.0", + "@pgsql/types": "^17.6.2" + } + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "license": "ISC" + }, + "node_modules/plpgsql-deparser": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/plpgsql-deparser/-/plpgsql-deparser-0.7.4.tgz", + "integrity": "sha512-XXCOVEUI1G+Teg1oZE6ZfSJqNSRKbei/7bVcc1uwQEWc2LxOk1Y6NN+UQQulnwLz0nvKueHrMAyL8/aam2fMWg==", + "license": "MIT", + "dependencies": { + "@pgsql/types": "^17.6.2", + "pgsql-deparser": "17.18.0" + } + }, + "node_modules/plpgsql-parser": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/plpgsql-parser/-/plpgsql-parser-0.5.5.tgz", + "integrity": "sha512-HgWqHTaOKiyNkO5EhpO7kugWYNmpgcCB6EJKlYm+wPiWpHTwpG52/3gGqm9NyAJ3kH0p1M4cBecNA7dDepmVgg==", + "license": "MIT", + "dependencies": { + "@libpg-query/parser": "^17.6.3", + "@pgsql/traverse": "17.2.4", + "@pgsql/types": "^17.6.2", + "pgsql-deparser": "17.18.0", + "plpgsql-deparser": "0.7.4" + } + }, + "node_modules/postgres-array": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz", + "integrity": "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/postgres-bytea": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.1.tgz", + "integrity": "sha512-5+5HqXnsZPE65IJZSMkZtURARZelel2oXUEO8rH83VS/hxH5vv1uHquPg5wZs8yMAfdv971IU+kcPUczi7NVBQ==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postgres-date": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-1.0.7.tgz", + "integrity": "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postgres-interval": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-1.2.0.tgz", + "integrity": "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==", + "license": "MIT", + "dependencies": { + "xtend": "^4.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/proc-log": { "version": "6.1.0", "dev": true, @@ -781,6 +866,24 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/split2": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", + "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==", + "license": "ISC", + "engines": { + "node": ">= 10.x" + } + }, + "node_modules/strfy-js": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/strfy-js/-/strfy-js-3.2.1.tgz", + "integrity": "sha512-HSw2lkUJVPZ75I+E3HM7UqHMKvBCwjRt1MIAxPPNtLFjuqCrnDVKQQGfotdj/3qHxuhB6NDQ1rYmNjVpPBiNEA==", + "license": "MIT", + "dependencies": { + "minimatch": "^10.1.1" + } + }, "node_modules/supabase": { "version": "2.76.16", "dev": true, @@ -814,6 +917,12 @@ "node": ">=18" } }, + "node_modules/undici-types": { + "version": "7.18.2", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.18.2.tgz", + "integrity": "sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w==", + "license": "MIT" + }, "node_modules/web-streams-polyfill": { "version": "3.3.3", "dev": true, @@ -833,6 +942,15 @@ "node": "^20.17.0 || >=22.9.0" } }, + "node_modules/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "license": "MIT", + "engines": { + "node": ">=0.4" + } + }, "node_modules/yallist": { "version": "5.0.0", "dev": true, @@ -840,6 +958,15 @@ "engines": { "node": ">=18" } + }, + "node_modules/zod": { + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/zod/-/zod-4.3.6.tgz", + "integrity": "sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } } } } diff --git a/package.json b/package.json index 600cb9b0..9dd2e8ca 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "private": true, "dependencies": { - "@supabase/pg-delta": "file:/Users/avallete/Documents/Programming/Supa/pg-toolbelt/packages/pg-delta" + "@supabase/pg-delta": "https://pkg.pr.new/supabase/pg-toolbelt/@supabase/pg-delta@7cb3a19" }, "devDependencies": { "supabase": "^2.76.16"