@homeflare/alchemy 0.46.0 → 0.47.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +10 -10
- package/dist/argocd/cluster.d.ts +5 -5
- package/dist/argocd/cluster.d.ts.map +1 -1
- package/dist/argocd/fake-argocd.d.ts +1 -1
- package/dist/argocd/fake-argocd.d.ts.map +1 -1
- package/dist/argocd/index.js.map +1 -1
- package/dist/argocd/providers.d.ts +1 -1
- package/dist/argocd/providers.d.ts.map +1 -1
- package/dist/argocd/repo-creds.d.ts +5 -5
- package/dist/argocd/repo-creds.d.ts.map +1 -1
- package/dist/argocd/repository.d.ts +5 -5
- package/dist/argocd/repository.d.ts.map +1 -1
- package/dist/argocd/resource.d.ts +1 -1
- package/dist/argocd/resource.d.ts.map +1 -1
- package/dist/caddy/admin.d.ts +1 -1
- package/dist/caddy/admin.d.ts.map +1 -1
- package/dist/caddy/caddy-http-client.d.ts +2 -2
- package/dist/caddy/caddy-http-client.d.ts.map +1 -1
- package/dist/caddy/format.d.ts +1 -1
- package/dist/caddy/format.d.ts.map +1 -1
- package/dist/caddy/index.js +6 -6
- package/dist/caddy/index.js.map +4 -4
- package/dist/ceph/auth-entity.d.ts +1 -1
- package/dist/ceph/auth-entity.d.ts.map +1 -1
- package/dist/ceph/ceph-auth-reconcile.d.ts +1 -1
- package/dist/ceph/ceph-auth-reconcile.d.ts.map +1 -1
- package/dist/ceph/index.js +5 -5
- package/dist/ceph/index.js.map +4 -4
- package/dist/cloudflare/fake-mesh.d.ts +2 -2
- package/dist/cloudflare/fake-mesh.d.ts.map +1 -1
- package/dist/cloudflare/fake-r2-lock.d.ts +1 -1
- package/dist/cloudflare/fake-r2-lock.d.ts.map +1 -1
- package/dist/cloudflare/index.js +3 -3
- package/dist/cloudflare/index.js.map +3 -3
- package/dist/cloudflare/mesh-node-token.d.ts +1 -1
- package/dist/cloudflare/mesh-node-token.d.ts.map +1 -1
- package/dist/cloudflare/mesh-node.d.ts +1 -1
- package/dist/cloudflare/mesh-node.d.ts.map +1 -1
- package/dist/cloudflare/providers.d.ts +1 -1
- package/dist/cloudflare/providers.d.ts.map +1 -1
- package/dist/cloudflare/r2-bucket-lock.d.ts +1 -1
- package/dist/cloudflare/r2-bucket-lock.d.ts.map +1 -1
- package/dist/discord/application-command.d.ts +6 -6
- package/dist/discord/application-command.d.ts.map +1 -1
- package/dist/discord/fake-discord.d.ts +1 -1
- package/dist/discord/fake-discord.d.ts.map +1 -1
- package/dist/discord/guild-application-command.d.ts +6 -6
- package/dist/discord/guild-application-command.d.ts.map +1 -1
- package/dist/discord/index.js.map +1 -1
- package/dist/discord/providers.d.ts +1 -1
- package/dist/discord/providers.d.ts.map +1 -1
- package/dist/discord/resource.d.ts +1 -1
- package/dist/discord/resource.d.ts.map +1 -1
- package/dist/forgejo/branch-protection.d.ts +5 -5
- package/dist/forgejo/branch-protection.d.ts.map +1 -1
- package/dist/forgejo/fake-forgejo.d.ts +1 -1
- package/dist/forgejo/fake-forgejo.d.ts.map +1 -1
- package/dist/forgejo/index.js.map +1 -1
- package/dist/forgejo/org-actions-secrets.d.ts +5 -5
- package/dist/forgejo/org-actions-secrets.d.ts.map +1 -1
- package/dist/forgejo/org-label.d.ts +5 -5
- package/dist/forgejo/org-label.d.ts.map +1 -1
- package/dist/forgejo/org-team.d.ts +5 -5
- package/dist/forgejo/org-team.d.ts.map +1 -1
- package/dist/forgejo/repo-webhook.d.ts +5 -5
- package/dist/forgejo/repo-webhook.d.ts.map +1 -1
- package/dist/forgejo/repository.d.ts +5 -5
- package/dist/forgejo/repository.d.ts.map +1 -1
- package/dist/forgejo/resource.d.ts +1 -1
- package/dist/forgejo/resource.d.ts.map +1 -1
- package/dist/forgejo/team-member.d.ts +5 -5
- package/dist/forgejo/team-member.d.ts.map +1 -1
- package/dist/github/repository-ruleset-providers.d.ts +1 -1
- package/dist/github/repository-ruleset-providers.d.ts.map +1 -1
- package/dist/google-workspace/domain-alias.d.ts +5 -5
- package/dist/google-workspace/domain-alias.d.ts.map +1 -1
- package/dist/google-workspace/fake-google-workspace.d.ts +1 -1
- package/dist/google-workspace/fake-google-workspace.d.ts.map +1 -1
- package/dist/google-workspace/group-member.d.ts +5 -5
- package/dist/google-workspace/group-member.d.ts.map +1 -1
- package/dist/google-workspace/group.d.ts +5 -5
- package/dist/google-workspace/group.d.ts.map +1 -1
- package/dist/google-workspace/index.js.map +1 -1
- package/dist/google-workspace/org-unit.d.ts +5 -5
- package/dist/google-workspace/org-unit.d.ts.map +1 -1
- package/dist/google-workspace/providers.d.ts +1 -1
- package/dist/google-workspace/providers.d.ts.map +1 -1
- package/dist/google-workspace/resource.d.ts +1 -1
- package/dist/google-workspace/resource.d.ts.map +1 -1
- package/dist/grafana/alert-rule-group.d.ts +4 -4
- package/dist/grafana/alert-rule-group.d.ts.map +1 -1
- package/dist/grafana/contact-point.d.ts +4 -4
- package/dist/grafana/dashboard.d.ts +4 -4
- package/dist/grafana/datasource.d.ts +4 -4
- package/dist/grafana/fake-grafana.d.ts +1 -1
- package/dist/grafana/fake-grafana.d.ts.map +1 -1
- package/dist/grafana/folder.d.ts +4 -4
- package/dist/grafana/message-template.d.ts +4 -4
- package/dist/grafana/mute-timing.d.ts +4 -4
- package/dist/grafana/notification-policy.d.ts +4 -4
- package/dist/grafana/notification-policy.d.ts.map +1 -1
- package/dist/grafana/providers.d.ts +1 -1
- package/dist/grafana/providers.d.ts.map +1 -1
- package/dist/litellm/access-group.d.ts +1 -1
- package/dist/litellm/budget-operations.d.ts +1 -1
- package/dist/litellm/budget-operations.d.ts.map +1 -1
- package/dist/litellm/budget.d.ts +2 -2
- package/dist/litellm/credential-errors.d.ts +1 -1
- package/dist/litellm/credential-errors.d.ts.map +1 -1
- package/dist/litellm/credential.d.ts +1 -1
- package/dist/litellm/index.js +26 -5
- package/dist/litellm/index.js.map +8 -8
- package/dist/litellm/key-errors.d.ts +1 -1
- package/dist/litellm/key-errors.d.ts.map +1 -1
- package/dist/litellm/key.d.ts +2 -2
- package/dist/litellm/mcp-server-locate.d.ts +1 -1
- package/dist/litellm/mcp-server-locate.d.ts.map +1 -1
- package/dist/litellm/mcp-server.d.ts +2 -2
- package/dist/litellm/model-operations.d.ts +1 -1
- package/dist/litellm/model-operations.d.ts.map +1 -1
- package/dist/litellm/model.d.ts +2 -2
- package/dist/litellm/operations.d.ts +1 -1
- package/dist/litellm/operations.d.ts.map +1 -1
- package/dist/litellm/policy-attachment.d.ts +1 -1
- package/dist/litellm/policy.d.ts +1 -1
- package/dist/litellm/providers.d.ts +1 -1
- package/dist/litellm/providers.d.ts.map +1 -1
- package/dist/litellm/team-operations.d.ts +1 -1
- package/dist/litellm/team-operations.d.ts.map +1 -1
- package/dist/litellm/team.d.ts +1 -1
- package/dist/litellm/tool-policy-operations.d.ts +1 -1
- package/dist/litellm/tool-policy-operations.d.ts.map +1 -1
- package/dist/litellm/tool-policy.d.ts +1 -1
- package/dist/litellm/toolset.d.ts +1 -1
- package/dist/netbox/fake-netbox.d.ts +1 -1
- package/dist/netbox/fake-netbox.d.ts.map +1 -1
- package/dist/netbox/index.js.map +1 -1
- package/dist/netbox/prefix.d.ts +5 -5
- package/dist/netbox/prefix.d.ts.map +1 -1
- package/dist/netbox/resource.d.ts +1 -1
- package/dist/netbox/resource.d.ts.map +1 -1
- package/dist/openbao/approle-login.d.ts +1 -1
- package/dist/openbao/approle-login.d.ts.map +1 -1
- package/dist/openbao/auth-method-reconcile.d.ts +1 -1
- package/dist/openbao/auth-method-reconcile.d.ts.map +1 -1
- package/dist/openbao/auth-method-wire.d.ts +4 -4
- package/dist/openbao/auth-method-wire.d.ts.map +1 -1
- package/dist/openbao/auth-method.d.ts +1 -1
- package/dist/openbao/auth-method.d.ts.map +1 -1
- package/dist/openbao/auth-role-identity.d.ts +1 -1
- package/dist/openbao/auth-role-identity.d.ts.map +1 -1
- package/dist/openbao/auth-role-wire.d.ts +4 -4
- package/dist/openbao/auth-role-wire.d.ts.map +1 -1
- package/dist/openbao/auth-role.d.ts +1 -1
- package/dist/openbao/auth-role.d.ts.map +1 -1
- package/dist/openbao/bao-http.d.ts +1 -1
- package/dist/openbao/bao-http.d.ts.map +1 -1
- package/dist/openbao/bao-identity.d.ts +1 -1
- package/dist/openbao/bao-identity.d.ts.map +1 -1
- package/dist/openbao/cloudflare-permission-groups.d.ts +1 -1
- package/dist/openbao/cloudflare-permission-groups.d.ts.map +1 -1
- package/dist/openbao/cloudflare-role-wire.d.ts +1 -1
- package/dist/openbao/cloudflare-role-wire.d.ts.map +1 -1
- package/dist/openbao/cloudflare-role.d.ts +1 -1
- package/dist/openbao/cloudflare-role.d.ts.map +1 -1
- package/dist/openbao/distilled.d.ts +1 -1
- package/dist/openbao/distilled.d.ts.map +1 -1
- package/dist/openbao/fake-bao.d.ts +1 -1
- package/dist/openbao/fake-bao.d.ts.map +1 -1
- package/dist/openbao/fake-core.d.ts +1 -1
- package/dist/openbao/fake-core.d.ts.map +1 -1
- package/dist/openbao/fake-engines.d.ts +1 -1
- package/dist/openbao/fake-engines.d.ts.map +1 -1
- package/dist/openbao/fake-families.d.ts +2 -2
- package/dist/openbao/fake-families.d.ts.map +1 -1
- package/dist/openbao/fake-stack.d.ts +5 -0
- package/dist/openbao/fake-stack.d.ts.map +1 -1
- package/dist/openbao/forgejo-bootstrap.d.ts +1 -1
- package/dist/openbao/forgejo-bootstrap.d.ts.map +1 -1
- package/dist/openbao/index.js +31 -10
- package/dist/openbao/index.js.map +31 -31
- package/dist/openbao/jwt-config.d.ts +1 -1
- package/dist/openbao/jwt-config.d.ts.map +1 -1
- package/dist/openbao/jwt-role.d.ts +1 -1
- package/dist/openbao/jwt-role.d.ts.map +1 -1
- package/dist/openbao/kubernetes-role.d.ts +1 -1
- package/dist/openbao/kubernetes-role.d.ts.map +1 -1
- package/dist/openbao/mfa-enforcement.d.ts +1 -1
- package/dist/openbao/mfa-enforcement.d.ts.map +1 -1
- package/dist/openbao/mfa-totp.d.ts +1 -1
- package/dist/openbao/mfa-totp.d.ts.map +1 -1
- package/dist/openbao/mfa-wire.d.ts +1 -1
- package/dist/openbao/mfa-wire.d.ts.map +1 -1
- package/dist/openbao/mount-move.d.ts +1 -1
- package/dist/openbao/mount-move.d.ts.map +1 -1
- package/dist/openbao/mount-reconcile.d.ts +1 -1
- package/dist/openbao/mount-reconcile.d.ts.map +1 -1
- package/dist/openbao/mount-wire.d.ts +4 -4
- package/dist/openbao/mount-wire.d.ts.map +1 -1
- package/dist/openbao/mount.d.ts +1 -1
- package/dist/openbao/mount.d.ts.map +1 -1
- package/dist/openbao/pki-role.d.ts +1 -1
- package/dist/openbao/pki-role.d.ts.map +1 -1
- package/dist/openbao/plugin-reconcile.d.ts +1 -1
- package/dist/openbao/plugin-reconcile.d.ts.map +1 -1
- package/dist/openbao/plugin-wire.d.ts +1 -1
- package/dist/openbao/plugin-wire.d.ts.map +1 -1
- package/dist/openbao/plugin.d.ts +1 -1
- package/dist/openbao/plugin.d.ts.map +1 -1
- package/dist/openbao/policy-identity.d.ts +1 -1
- package/dist/openbao/policy-identity.d.ts.map +1 -1
- package/dist/openbao/policy-wire.d.ts +4 -4
- package/dist/openbao/policy-wire.d.ts.map +1 -1
- package/dist/openbao/policy.d.ts +1 -1
- package/dist/openbao/policy.d.ts.map +1 -1
- package/dist/openbao/proxmox-role-wire.d.ts +1 -1
- package/dist/openbao/proxmox-role-wire.d.ts.map +1 -1
- package/dist/openbao/proxmox-role.d.ts +1 -1
- package/dist/openbao/proxmox-role.d.ts.map +1 -1
- package/dist/openbao/remount-wire.d.ts +1 -1
- package/dist/openbao/remount-wire.d.ts.map +1 -1
- package/dist/openbao/rename-identity.d.ts +1 -1
- package/dist/openbao/rename-identity.d.ts.map +1 -1
- package/dist/openbao/rename.d.ts +1 -1
- package/dist/openbao/rename.d.ts.map +1 -1
- package/dist/openbao/role-reconcile.d.ts +1 -1
- package/dist/openbao/role-reconcile.d.ts.map +1 -1
- package/dist/openbao/ssh-role.d.ts +1 -1
- package/dist/openbao/ssh-role.d.ts.map +1 -1
- package/dist/opnsense/alias.d.ts +5 -5
- package/dist/opnsense/alias.d.ts.map +1 -1
- package/dist/opnsense/category.d.ts +5 -5
- package/dist/opnsense/category.d.ts.map +1 -1
- package/dist/opnsense/fake-opnsense.d.ts +1 -1
- package/dist/opnsense/fake-opnsense.d.ts.map +1 -1
- package/dist/opnsense/group.d.ts +5 -5
- package/dist/opnsense/group.d.ts.map +1 -1
- package/dist/opnsense/index.js.map +1 -1
- package/dist/opnsense/providers.d.ts +1 -1
- package/dist/opnsense/providers.d.ts.map +1 -1
- package/dist/opnsense/resource.d.ts +1 -1
- package/dist/opnsense/resource.d.ts.map +1 -1
- package/dist/ownership/probe.d.ts.map +1 -1
- package/dist/paperless/custom-field.d.ts +5 -5
- package/dist/paperless/custom-field.d.ts.map +1 -1
- package/dist/paperless/document-type.d.ts +5 -5
- package/dist/paperless/document-type.d.ts.map +1 -1
- package/dist/paperless/fake-paperless.d.ts +1 -1
- package/dist/paperless/fake-paperless.d.ts.map +1 -1
- package/dist/paperless/matching-types.d.ts +1 -1
- package/dist/paperless/matching-types.d.ts.map +1 -1
- package/dist/paperless/matching.d.ts +4 -4
- package/dist/paperless/providers.d.ts +1 -1
- package/dist/paperless/providers.d.ts.map +1 -1
- package/dist/paperless/storage-path.d.ts +5 -5
- package/dist/paperless/storage-path.d.ts.map +1 -1
- package/dist/paperless/tag.d.ts +5 -5
- package/dist/paperless/tag.d.ts.map +1 -1
- package/dist/postgres/connection.d.ts +2 -2
- package/dist/postgres/connection.d.ts.map +1 -1
- package/dist/postgres/database-sql.d.ts +1 -1
- package/dist/postgres/database-sql.d.ts.map +1 -1
- package/dist/postgres/database.d.ts +1 -1
- package/dist/postgres/database.d.ts.map +1 -1
- package/dist/postgres/fake-grants-read.d.ts +1 -1
- package/dist/postgres/fake-grants-read.d.ts.map +1 -1
- package/dist/postgres/fake-grants-write.d.ts +1 -1
- package/dist/postgres/fake-grants-write.d.ts.map +1 -1
- package/dist/postgres/fake-role-sql.d.ts +1 -1
- package/dist/postgres/fake-role-sql.d.ts.map +1 -1
- package/dist/postgres/fake-schema-drop.d.ts +13 -0
- package/dist/postgres/fake-schema-drop.d.ts.map +1 -0
- package/dist/postgres/fake-schema-sql.d.ts +6 -1
- package/dist/postgres/fake-schema-sql.d.ts.map +1 -1
- package/dist/postgres/fake-sql.d.ts +4 -0
- package/dist/postgres/fake-sql.d.ts.map +1 -1
- package/dist/postgres/grants-existence.d.ts +1 -1
- package/dist/postgres/grants-existence.d.ts.map +1 -1
- package/dist/postgres/grants-ops.d.ts +1 -1
- package/dist/postgres/grants-ops.d.ts.map +1 -1
- package/dist/postgres/grants-ownership.d.ts +1 -1
- package/dist/postgres/grants-ownership.d.ts.map +1 -1
- package/dist/postgres/grants-read-defaults.d.ts +1 -1
- package/dist/postgres/grants-read-defaults.d.ts.map +1 -1
- package/dist/postgres/grants-read.d.ts +1 -1
- package/dist/postgres/grants-read.d.ts.map +1 -1
- package/dist/postgres/index.d.ts +2 -1
- package/dist/postgres/index.d.ts.map +1 -1
- package/dist/postgres/index.js +523 -324
- package/dist/postgres/index.js.map +26 -22
- package/dist/postgres/installed-classifier.d.ts +1 -1
- package/dist/postgres/installed-classifier.d.ts.map +1 -1
- package/dist/postgres/psql-executor.d.ts.map +1 -1
- package/dist/postgres/role-membership-sql.d.ts +1 -1
- package/dist/postgres/role-membership-sql.d.ts.map +1 -1
- package/dist/postgres/role-sql.d.ts +1 -1
- package/dist/postgres/role-sql.d.ts.map +1 -1
- package/dist/postgres/role.d.ts +1 -1
- package/dist/postgres/role.d.ts.map +1 -1
- package/dist/postgres/schema-assert.d.ts +1 -1
- package/dist/postgres/schema-assert.d.ts.map +1 -1
- package/dist/postgres/schema-closure-sql.d.ts +45 -0
- package/dist/postgres/schema-closure-sql.d.ts.map +1 -0
- package/dist/postgres/schema-delete.d.ts +18 -9
- package/dist/postgres/schema-delete.d.ts.map +1 -1
- package/dist/postgres/schema-drop-sql.d.ts +66 -0
- package/dist/postgres/schema-drop-sql.d.ts.map +1 -0
- package/dist/postgres/schema-errors.d.ts +19 -1
- package/dist/postgres/schema-errors.d.ts.map +1 -1
- package/dist/postgres/schema-reconcile.d.ts +1 -1
- package/dist/postgres/schema-reconcile.d.ts.map +1 -1
- package/dist/postgres/schema-sequence-error.d.ts +29 -0
- package/dist/postgres/schema-sequence-error.d.ts.map +1 -0
- package/dist/postgres/schema-sql.d.ts +17 -1
- package/dist/postgres/schema-sql.d.ts.map +1 -1
- package/dist/postgres/schema-test-kit.d.ts +3 -1
- package/dist/postgres/schema-test-kit.d.ts.map +1 -1
- package/dist/postgres/schema.d.ts +1 -1
- package/dist/postgres/schema.d.ts.map +1 -1
- package/dist/postgres/search-path.d.ts +38 -0
- package/dist/postgres/search-path.d.ts.map +1 -0
- package/dist/proxmox/acl.d.ts +1 -1
- package/dist/proxmox/acl.d.ts.map +1 -1
- package/dist/proxmox/api-token.d.ts +1 -1
- package/dist/proxmox/api-token.d.ts.map +1 -1
- package/dist/proxmox/backup-job-distilled.d.ts +2 -2
- package/dist/proxmox/backup-job-distilled.d.ts.map +1 -1
- package/dist/proxmox/backup-job.d.ts +1 -1
- package/dist/proxmox/backup-job.d.ts.map +1 -1
- package/dist/proxmox/ceph-daemon-wire.d.ts +3 -3
- package/dist/proxmox/ceph-daemon-wire.d.ts.map +1 -1
- package/dist/proxmox/ceph-daemon.d.ts +2 -2
- package/dist/proxmox/ceph-daemon.d.ts.map +1 -1
- package/dist/proxmox/ceph-flag-wire.d.ts +3 -3
- package/dist/proxmox/ceph-flag-wire.d.ts.map +1 -1
- package/dist/proxmox/ceph-flag.d.ts +1 -1
- package/dist/proxmox/ceph-flag.d.ts.map +1 -1
- package/dist/proxmox/ceph-fs-distilled.d.ts +3 -3
- package/dist/proxmox/ceph-fs-distilled.d.ts.map +1 -1
- package/dist/proxmox/ceph-fs.d.ts +1 -1
- package/dist/proxmox/ceph-fs.d.ts.map +1 -1
- package/dist/proxmox/ceph-osd-tree.d.ts +1 -1
- package/dist/proxmox/ceph-osd-tree.d.ts.map +1 -1
- package/dist/proxmox/ceph-osd-write.d.ts +2 -2
- package/dist/proxmox/ceph-osd-write.d.ts.map +1 -1
- package/dist/proxmox/ceph-osd.d.ts +1 -1
- package/dist/proxmox/ceph-osd.d.ts.map +1 -1
- package/dist/proxmox/ceph-pool-settle.d.ts +2 -2
- package/dist/proxmox/ceph-pool-settle.d.ts.map +1 -1
- package/dist/proxmox/ceph-pool-wire.d.ts +1 -1
- package/dist/proxmox/ceph-pool-wire.d.ts.map +1 -1
- package/dist/proxmox/ceph-pool.d.ts +1 -1
- package/dist/proxmox/ceph-pool.d.ts.map +1 -1
- package/dist/proxmox/client.d.ts +1 -1
- package/dist/proxmox/client.d.ts.map +1 -1
- package/dist/proxmox/distilled-pbs.d.ts +1 -1
- package/dist/proxmox/distilled-pbs.d.ts.map +1 -1
- package/dist/proxmox/distilled-pve.d.ts +1 -1
- package/dist/proxmox/distilled-pve.d.ts.map +1 -1
- package/dist/proxmox/fake-pbs-jobs.d.ts +1 -1
- package/dist/proxmox/fake-pve.d.ts +1 -1
- package/dist/proxmox/fake-pve.d.ts.map +1 -1
- package/dist/proxmox/firewall-alias-lifecycle.d.ts +6 -6
- package/dist/proxmox/firewall-alias-lifecycle.d.ts.map +1 -1
- package/dist/proxmox/firewall-alias.d.ts +1 -1
- package/dist/proxmox/firewall-alias.d.ts.map +1 -1
- package/dist/proxmox/group-wire.d.ts +2 -2
- package/dist/proxmox/group-wire.d.ts.map +1 -1
- package/dist/proxmox/group.d.ts +1 -1
- package/dist/proxmox/group.d.ts.map +1 -1
- package/dist/proxmox/ha-resource.d.ts +1 -1
- package/dist/proxmox/ha-resource.d.ts.map +1 -1
- package/dist/proxmox/ha-rule.d.ts +1 -1
- package/dist/proxmox/ha-rule.d.ts.map +1 -1
- package/dist/proxmox/index.js +38 -17
- package/dist/proxmox/index.js.map +9 -9
- package/dist/proxmox/lease-cache.d.ts +2 -2
- package/dist/proxmox/lease-cache.d.ts.map +1 -1
- package/dist/proxmox/live-core-fixtures.d.ts +1 -1
- package/dist/proxmox/live-core-fixtures.d.ts.map +1 -1
- package/dist/proxmox/lxc-lifecycle.d.ts +3 -3
- package/dist/proxmox/lxc-lifecycle.d.ts.map +1 -1
- package/dist/proxmox/lxc-read.d.ts +1 -1
- package/dist/proxmox/lxc-read.d.ts.map +1 -1
- package/dist/proxmox/lxc-task.d.ts +1 -1
- package/dist/proxmox/lxc-task.d.ts.map +1 -1
- package/dist/proxmox/lxc.d.ts +1 -1
- package/dist/proxmox/lxc.d.ts.map +1 -1
- package/dist/proxmox/members.d.ts +3 -3
- package/dist/proxmox/members.d.ts.map +1 -1
- package/dist/proxmox/metric-server-distilled.d.ts +3 -3
- package/dist/proxmox/metric-server-distilled.d.ts.map +1 -1
- package/dist/proxmox/metric-server.d.ts +1 -1
- package/dist/proxmox/metric-server.d.ts.map +1 -1
- package/dist/proxmox/mint.d.ts +1 -1
- package/dist/proxmox/mint.d.ts.map +1 -1
- package/dist/proxmox/network-apply-read.d.ts +3 -3
- package/dist/proxmox/network-apply-read.d.ts.map +1 -1
- package/dist/proxmox/network-apply-run.d.ts +1 -1
- package/dist/proxmox/network-apply-run.d.ts.map +1 -1
- package/dist/proxmox/network-apply.d.ts +1 -1
- package/dist/proxmox/network-apply.d.ts.map +1 -1
- package/dist/proxmox/node-network-wire.d.ts +2 -2
- package/dist/proxmox/node-network-wire.d.ts.map +1 -1
- package/dist/proxmox/node-network.d.ts +1 -1
- package/dist/proxmox/node-network.d.ts.map +1 -1
- package/dist/proxmox/notification-matcher-distilled.d.ts +4 -4
- package/dist/proxmox/notification-matcher-distilled.d.ts.map +1 -1
- package/dist/proxmox/notification-matcher-lifecycle.d.ts +4 -4
- package/dist/proxmox/notification-matcher.d.ts +1 -1
- package/dist/proxmox/notification-matcher.d.ts.map +1 -1
- package/dist/proxmox/notification-target-distilled.d.ts +4 -4
- package/dist/proxmox/notification-target-distilled.d.ts.map +1 -1
- package/dist/proxmox/notification-target-lifecycle.d.ts +4 -4
- package/dist/proxmox/notification-target.d.ts +1 -1
- package/dist/proxmox/notification-target.d.ts.map +1 -1
- package/dist/proxmox/pbs-datastore-lifecycle.d.ts +4 -4
- package/dist/proxmox/pbs-datastore-wire.d.ts +4 -4
- package/dist/proxmox/pbs-datastore-wire.d.ts.map +1 -1
- package/dist/proxmox/pbs-datastore.d.ts +1 -1
- package/dist/proxmox/pbs-datastore.d.ts.map +1 -1
- package/dist/proxmox/pbs-notification-matcher-distilled.d.ts +4 -4
- package/dist/proxmox/pbs-notification-matcher-distilled.d.ts.map +1 -1
- package/dist/proxmox/pbs-notification-matcher.d.ts +1 -1
- package/dist/proxmox/pbs-notification-matcher.d.ts.map +1 -1
- package/dist/proxmox/pbs-notification-target-distilled.d.ts +4 -4
- package/dist/proxmox/pbs-notification-target-distilled.d.ts.map +1 -1
- package/dist/proxmox/pbs-notification-target-lifecycle.d.ts +4 -4
- package/dist/proxmox/pbs-notification-target.d.ts +1 -1
- package/dist/proxmox/pbs-notification-target.d.ts.map +1 -1
- package/dist/proxmox/pbs-prune-job-lifecycle.d.ts +4 -4
- package/dist/proxmox/pbs-prune-job-wire.d.ts +4 -4
- package/dist/proxmox/pbs-prune-job-wire.d.ts.map +1 -1
- package/dist/proxmox/pbs-prune-job.d.ts +1 -1
- package/dist/proxmox/pbs-prune-job.d.ts.map +1 -1
- package/dist/proxmox/pbs-sync-job-lifecycle.d.ts +4 -4
- package/dist/proxmox/pbs-sync-job-wire.d.ts +4 -4
- package/dist/proxmox/pbs-sync-job-wire.d.ts.map +1 -1
- package/dist/proxmox/pbs-sync-job.d.ts +1 -1
- package/dist/proxmox/pbs-sync-job.d.ts.map +1 -1
- package/dist/proxmox/pbs-verify-job-lifecycle.d.ts +4 -4
- package/dist/proxmox/pbs-verify-job-wire.d.ts +4 -4
- package/dist/proxmox/pbs-verify-job-wire.d.ts.map +1 -1
- package/dist/proxmox/pbs-verify-job.d.ts +1 -1
- package/dist/proxmox/pbs-verify-job.d.ts.map +1 -1
- package/dist/proxmox/pool.d.ts +3 -3
- package/dist/proxmox/pool.d.ts.map +1 -1
- package/dist/proxmox/provision-declare.d.ts +1 -1
- package/dist/proxmox/provision-declare.d.ts.map +1 -1
- package/dist/proxmox/qemu-lifecycle.d.ts +3 -3
- package/dist/proxmox/qemu-lifecycle.d.ts.map +1 -1
- package/dist/proxmox/qemu-read.d.ts +1 -1
- package/dist/proxmox/qemu-read.d.ts.map +1 -1
- package/dist/proxmox/qemu-resize.d.ts +1 -1
- package/dist/proxmox/qemu-resize.d.ts.map +1 -1
- package/dist/proxmox/qemu-task.d.ts +1 -1
- package/dist/proxmox/qemu-task.d.ts.map +1 -1
- package/dist/proxmox/qemu.d.ts +1 -1
- package/dist/proxmox/qemu.d.ts.map +1 -1
- package/dist/proxmox/replication-job-lifecycle.d.ts +6 -6
- package/dist/proxmox/replication-job-lifecycle.d.ts.map +1 -1
- package/dist/proxmox/replication-job.d.ts +1 -1
- package/dist/proxmox/replication-job.d.ts.map +1 -1
- package/dist/proxmox/resource-spec.d.ts +1 -1
- package/dist/proxmox/resource-spec.d.ts.map +1 -1
- package/dist/proxmox/resource.d.ts +8 -8
- package/dist/proxmox/role.d.ts +1 -1
- package/dist/proxmox/role.d.ts.map +1 -1
- package/dist/proxmox/sdn-apply-read.d.ts +1 -1
- package/dist/proxmox/sdn-apply-read.d.ts.map +1 -1
- package/dist/proxmox/sdn-apply.d.ts +1 -1
- package/dist/proxmox/sdn-apply.d.ts.map +1 -1
- package/dist/proxmox/sdn-subnet.d.ts +1 -1
- package/dist/proxmox/sdn-subnet.d.ts.map +1 -1
- package/dist/proxmox/sdn-vnet.d.ts +1 -1
- package/dist/proxmox/sdn-vnet.d.ts.map +1 -1
- package/dist/proxmox/sdn-zone.d.ts +1 -1
- package/dist/proxmox/sdn-zone.d.ts.map +1 -1
- package/dist/proxmox/storage-download-lifecycle.d.ts +6 -6
- package/dist/proxmox/storage-download-lifecycle.d.ts.map +1 -1
- package/dist/proxmox/storage-download-task.d.ts +1 -1
- package/dist/proxmox/storage-download-task.d.ts.map +1 -1
- package/dist/proxmox/storage-download.d.ts +1 -1
- package/dist/proxmox/storage-download.d.ts.map +1 -1
- package/dist/proxmox/storage-wire.d.ts +2 -2
- package/dist/proxmox/storage-wire.d.ts.map +1 -1
- package/dist/proxmox/storage.d.ts +1 -1
- package/dist/proxmox/storage.d.ts.map +1 -1
- package/dist/proxmox/user-wire.d.ts +2 -2
- package/dist/proxmox/user-wire.d.ts.map +1 -1
- package/dist/proxmox/user.d.ts +1 -1
- package/dist/proxmox/user.d.ts.map +1 -1
- package/dist/proxmox/zfs-pool-form.d.ts +2 -2
- package/dist/proxmox/zfs-pool-form.d.ts.map +1 -1
- package/dist/proxmox/zfs-pool-wire.d.ts +2 -2
- package/dist/proxmox/zfs-pool-wire.d.ts.map +1 -1
- package/dist/proxmox/zfs-pool.d.ts +1 -1
- package/dist/proxmox/zfs-pool.d.ts.map +1 -1
- package/dist/release/binary.d.ts +1 -1
- package/dist/release/binary.d.ts.map +1 -1
- package/dist/release/download.d.ts +1 -1
- package/dist/release/download.d.ts.map +1 -1
- package/dist/release/index.js +6 -5
- package/dist/release/index.js.map +5 -5
- package/dist/talos/credentials-write.d.ts +1 -1
- package/dist/talos/credentials-write.d.ts.map +1 -1
- package/dist/talos/credentials.d.ts +1 -1
- package/dist/talos/credentials.d.ts.map +1 -1
- package/dist/talos/fake-process.d.ts +2 -2
- package/dist/talos/fake-process.d.ts.map +1 -1
- package/dist/talos/index.js +7 -7
- package/dist/talos/index.js.map +4 -4
- package/dist/talos/kubeconfig.d.ts +4 -4
- package/dist/talos/kubeconfig.d.ts.map +1 -1
- package/dist/talos/machine-config-fixtures.d.ts +1 -1
- package/dist/talos/machine-config-fixtures.d.ts.map +1 -1
- package/dist/talos/machine-config-read.d.ts +3 -3
- package/dist/talos/machine-config-read.d.ts.map +1 -1
- package/dist/talos/resource.d.ts +1 -1
- package/dist/talos/resource.d.ts.map +1 -1
- package/dist/talos/talos-bootstrap-etcd.d.ts +2 -2
- package/dist/talos/talos-bootstrap-etcd.d.ts.map +1 -1
- package/dist/talos/talos-bootstrap.d.ts +4 -4
- package/dist/talos/talos-bootstrap.d.ts.map +1 -1
- package/dist/talos/talos-cluster-health.d.ts +4 -4
- package/dist/talos/talos-cluster-health.d.ts.map +1 -1
- package/dist/talos/talos-machine-config.d.ts +2 -2
- package/dist/talos/talos-machine-config.d.ts.map +1 -1
- package/dist/talos/talosctl.d.ts +1 -1
- package/dist/talos/talosctl.d.ts.map +1 -1
- package/dist/telemetry/index.js +4 -4
- package/dist/telemetry/index.js.map +3 -3
- package/dist/telemetry/redact-serialization.d.ts +2 -2
- package/dist/telemetry/redact-serialization.d.ts.map +1 -1
- package/dist/unifi/acl-rule-ordering.d.ts +6 -6
- package/dist/unifi/acl-rule-ordering.d.ts.map +1 -1
- package/dist/unifi/acl-rule.d.ts +6 -6
- package/dist/unifi/acl-rule.d.ts.map +1 -1
- package/dist/unifi/dns-policy.d.ts +6 -6
- package/dist/unifi/dns-policy.d.ts.map +1 -1
- package/dist/unifi/fake-unifi.d.ts +1 -1
- package/dist/unifi/fake-unifi.d.ts.map +1 -1
- package/dist/unifi/firewall-policy-ordering.d.ts +6 -6
- package/dist/unifi/firewall-policy-ordering.d.ts.map +1 -1
- package/dist/unifi/firewall-policy.d.ts +6 -6
- package/dist/unifi/firewall-policy.d.ts.map +1 -1
- package/dist/unifi/firewall-zone.d.ts +6 -6
- package/dist/unifi/firewall-zone.d.ts.map +1 -1
- package/dist/unifi/index.js +2 -2
- package/dist/unifi/index.js.map +2 -2
- package/dist/unifi/network.d.ts +6 -6
- package/dist/unifi/network.d.ts.map +1 -1
- package/dist/unifi/providers.d.ts +1 -1
- package/dist/unifi/providers.d.ts.map +1 -1
- package/dist/unifi/resource.d.ts +1 -1
- package/dist/unifi/resource.d.ts.map +1 -1
- package/dist/unifi/traffic-matching-list.d.ts +6 -6
- package/dist/unifi/traffic-matching-list.d.ts.map +1 -1
- package/dist/unifi/wifi-broadcast.d.ts +6 -6
- package/dist/unifi/wifi-broadcast.d.ts.map +1 -1
- package/dist/verify/cli.js.map +1 -1
- package/dist/verify/index.js.map +1 -1
- package/docs/distilled-interim.md +1 -1
- package/docs/mesh-node.md +1 -1
- package/docs/paperless.md +1 -1
- package/docs/peers.md +8 -8
- package/docs/postgres-schema.md +22 -1
- package/docs/telemetry.md +1 -1
- package/package.json +20 -20
- package/src/argocd/fake-argocd.ts +1 -1
- package/src/argocd/resource.ts +1 -1
- package/src/caddy/admin-transport-scope.test.ts +2 -2
- package/src/caddy/admin.ts +1 -1
- package/src/caddy/caddy-http-client.ts +5 -5
- package/src/caddy/config-adopt.test.ts +2 -2
- package/src/caddy/format.ts +2 -2
- package/src/caddy/local-admin.test.ts +1 -1
- package/src/ceph/auth-entity.ts +1 -1
- package/src/ceph/ceph-auth-reconcile.ts +1 -1
- package/src/cloudflare/fake-mesh.ts +1 -1
- package/src/cloudflare/fake-r2-lock.ts +1 -1
- package/src/cloudflare/mesh-node-harness.ts +1 -1
- package/src/cloudflare/mesh-node.ts +1 -1
- package/src/cloudflare/r2-bucket-lock.ts +1 -1
- package/src/discord/fake-discord.ts +1 -1
- package/src/discord/resource.ts +1 -1
- package/src/forgejo/fake-forgejo.ts +1 -1
- package/src/forgejo/resource.ts +1 -1
- package/src/google-workspace/fake-google-workspace.ts +1 -1
- package/src/google-workspace/resource.ts +1 -1
- package/src/grafana/fake-grafana.ts +1 -1
- package/src/litellm/access-group.test.ts +1 -1
- package/src/litellm/credential-errors.ts +1 -1
- package/src/litellm/credential-guards.test.ts +1 -1
- package/src/litellm/credential-operations.ts +1 -1
- package/src/litellm/credential-rewrite.test.ts +1 -1
- package/src/litellm/fake-stack.ts +1 -1
- package/src/litellm/key-errors.ts +1 -1
- package/src/litellm/key-harness.ts +1 -1
- package/src/litellm/key-operations.ts +1 -1
- package/src/litellm/key.test.ts +2 -1
- package/src/litellm/mcp-server-handlers.test.ts +1 -1
- package/src/litellm/mcp-server-registry.test.ts +1 -1
- package/src/litellm/model-operations.test.ts +1 -1
- package/src/litellm/operations.ts +1 -1
- package/src/litellm/pass-through-endpoint-delete-swallow.test.ts +1 -1
- package/src/litellm/pass-through-endpoint.test.ts +1 -1
- package/src/litellm/pass-through-fetch-client.test.ts +2 -2
- package/src/litellm/policy-attachment.test.ts +1 -1
- package/src/litellm/policy.test.ts +1 -1
- package/src/litellm/team-members.test.ts +1 -1
- package/src/litellm/team-read.test.ts +1 -1
- package/src/litellm/tool-policy.test.ts +1 -1
- package/src/litellm/toolset.test.ts +1 -1
- package/src/netbox/fake-netbox.ts +1 -1
- package/src/netbox/resource.ts +1 -1
- package/src/openbao/adopt-core.test.ts +4 -1
- package/src/openbao/adopt-families.test.ts +4 -1
- package/src/openbao/adopt-holes.test.ts +1 -1
- package/src/openbao/adopt-recovery.test.ts +24 -0
- package/src/openbao/approle-login.ts +2 -2
- package/src/openbao/auth-method-reconcile.ts +1 -1
- package/src/openbao/auth-method.ts +1 -1
- package/src/openbao/auth-role-sdk.test.ts +1 -1
- package/src/openbao/auth-role.ts +1 -1
- package/src/openbao/bao-http.test.ts +3 -3
- package/src/openbao/bao-http.ts +4 -4
- package/src/openbao/bao-identity.ts +2 -2
- package/src/openbao/cloudflare-permission-groups.ts +1 -1
- package/src/openbao/cloudflare-role-wire.ts +1 -1
- package/src/openbao/cloudflare-role.ts +1 -1
- package/src/openbao/distilled-retry.test.ts +3 -3
- package/src/openbao/distilled.test.ts +3 -3
- package/src/openbao/distilled.ts +2 -2
- package/src/openbao/fake-bao.ts +2 -2
- package/src/openbao/fake-core.ts +1 -1
- package/src/openbao/fake-engines.ts +1 -1
- package/src/openbao/fake-families.ts +1 -1
- package/src/openbao/fake-stack.ts +13 -3
- package/src/openbao/jwt-config.ts +1 -1
- package/src/openbao/jwt-role.ts +1 -1
- package/src/openbao/kubernetes-role.ts +1 -1
- package/src/openbao/mfa-enforcement.ts +1 -1
- package/src/openbao/mfa-totp.ts +1 -1
- package/src/openbao/mfa-wire.ts +1 -1
- package/src/openbao/mount-move.ts +1 -1
- package/src/openbao/mount-reconcile.ts +1 -1
- package/src/openbao/mount.ts +1 -1
- package/src/openbao/pki-role.ts +1 -1
- package/src/openbao/plugin-reconcile.ts +1 -1
- package/src/openbao/plugin-wire.ts +1 -1
- package/src/openbao/plugin.ts +1 -1
- package/src/openbao/policy.ts +1 -1
- package/src/openbao/proxmox-role.ts +1 -1
- package/src/openbao/remount-wire.ts +1 -1
- package/src/openbao/rename-occupied.test.ts +1 -1
- package/src/openbao/role-reconcile.ts +1 -1
- package/src/openbao/role-rename.test.ts +1 -1
- package/src/openbao/ssh-role.ts +1 -1
- package/src/opnsense/fake-opnsense.ts +1 -1
- package/src/opnsense/resource.ts +1 -1
- package/src/ownership/probe.ts +51 -2
- package/src/paperless/fake-paperless.ts +1 -1
- package/src/paperless/matching-types.ts +1 -1
- package/src/postgres/connection.ts +11 -15
- package/src/postgres/database-bigint-serialization.test.ts +3 -3
- package/src/postgres/database-sql.ts +7 -7
- package/src/postgres/database.ts +1 -1
- package/src/postgres/fake-grants-read.ts +4 -4
- package/src/postgres/fake-grants-sql.ts +1 -1
- package/src/postgres/fake-grants-write.ts +1 -1
- package/src/postgres/fake-role-sql.ts +3 -3
- package/src/postgres/fake-schema-drop.ts +75 -0
- package/src/postgres/fake-schema-sql.ts +11 -2
- package/src/postgres/fake-sql.ts +11 -4
- package/src/postgres/grants-database.test.ts +5 -5
- package/src/postgres/grants-existence.ts +8 -8
- package/src/postgres/grants-ops.ts +1 -1
- package/src/postgres/grants-ownership.ts +6 -6
- package/src/postgres/grants-psql-lifecycle.test.ts +7 -3
- package/src/postgres/grants-read-defaults.ts +6 -6
- package/src/postgres/grants-read.ts +17 -17
- package/src/postgres/grants-relkind-wire.test.ts +6 -4
- package/src/postgres/index.ts +2 -0
- package/src/postgres/installed-classifier.ts +1 -1
- package/src/postgres/psql-executor-escaping.test.ts +3 -1
- package/src/postgres/psql-executor.test.ts +11 -5
- package/src/postgres/psql-executor.ts +5 -7
- package/src/postgres/role-adopt.test.ts +3 -1
- package/src/postgres/role-membership-options.test.ts +3 -1
- package/src/postgres/role-membership-repair.test.ts +3 -3
- package/src/postgres/role-membership-sql.ts +5 -5
- package/src/postgres/role-password-transports.test.ts +6 -4
- package/src/postgres/role-sql.ts +2 -2
- package/src/postgres/role.ts +1 -1
- package/src/postgres/schema-assert.ts +1 -1
- package/src/postgres/schema-closure-sql.ts +108 -0
- package/src/postgres/schema-delete-proofs.test.ts +7 -7
- package/src/postgres/schema-delete.ts +89 -47
- package/src/postgres/schema-drop-2bp01.test.ts +30 -18
- package/src/postgres/schema-drop-real.test.ts +190 -0
- package/src/postgres/schema-drop-sql.ts +135 -0
- package/src/postgres/schema-drop.test.ts +241 -0
- package/src/postgres/schema-errors.ts +26 -0
- package/src/postgres/schema-handlers.test.ts +21 -14
- package/src/postgres/schema-lifecycle.test.ts +6 -60
- package/src/postgres/schema-reconcile.ts +1 -1
- package/src/postgres/schema-sequence-error.ts +38 -0
- package/src/postgres/schema-socket.test.ts +20 -6
- package/src/postgres/schema-sql.ts +17 -12
- package/src/postgres/schema-takeover.test.ts +7 -4
- package/src/postgres/schema-test-kit.ts +18 -4
- package/src/postgres/search-path.test.ts +100 -0
- package/src/postgres/search-path.ts +62 -0
- package/src/proxmox/ceph-flag-wire.test.ts +1 -1
- package/src/proxmox/ceph-fs-destroy-sdk.test.ts +1 -1
- package/src/proxmox/ceph-pool-write.test.ts +1 -1
- package/src/proxmox/client.test.ts +2 -2
- package/src/proxmox/client.ts +2 -2
- package/src/proxmox/credentials.test.ts +1 -1
- package/src/proxmox/distilled-pbs.test.ts +1 -1
- package/src/proxmox/distilled-pbs.ts +1 -1
- package/src/proxmox/distilled-pve.test.ts +2 -2
- package/src/proxmox/distilled-pve.ts +1 -1
- package/src/proxmox/fake-pbs-jobs.ts +1 -1
- package/src/proxmox/fake-pve.ts +1 -1
- package/src/proxmox/lease-cache-mint.test.ts +1 -1
- package/src/proxmox/live-core-fixtures.ts +1 -1
- package/src/proxmox/lxc-distilled.test.ts +1 -1
- package/src/proxmox/lxc-harness.ts +1 -1
- package/src/proxmox/members-timeout.test.ts +3 -3
- package/src/proxmox/members.test.ts +1 -1
- package/src/proxmox/members.ts +4 -4
- package/src/proxmox/mint.ts +4 -4
- package/src/proxmox/node-network-read-failure.test.ts +1 -1
- package/src/proxmox/qemu-lifecycle.ts +1 -1
- package/src/proxmox/read-failure-propagation.test.ts +1 -1
- package/src/proxmox/resource-spec.ts +1 -1
- package/src/proxmox/storage-read-failure.test.ts +1 -1
- package/src/proxmox/typed-absence.test.ts +2 -2
- package/src/proxmox/unreadable-read.test.ts +1 -1
- package/src/proxmox/user.test.ts +1 -1
- package/src/proxmox/zfs-pool-read-failure.test.ts +1 -1
- package/src/release/adopt-parity.test.ts +3 -1
- package/src/release/apply-pins.test.ts +2 -2
- package/src/release/binary-root.test.ts +2 -2
- package/src/release/binary.ts +9 -2
- package/src/release/download.test.ts +3 -3
- package/src/release/download.ts +1 -1
- package/src/release/fake-deploy.ts +2 -2
- package/src/release/fake-engine.ts +2 -2
- package/src/release/fake-provider.ts +2 -2
- package/src/release/plan.test.ts +2 -2
- package/src/release/providers.ts +1 -1
- package/src/talos/credentials-write.test.ts +1 -1
- package/src/talos/credentials-write.ts +2 -2
- package/src/talos/credentials.test.ts +1 -1
- package/src/talos/credentials.ts +2 -2
- package/src/talos/fake-process.ts +2 -2
- package/src/talos/kubeconfig.test.ts +1 -1
- package/src/talos/machine-config-fixtures.ts +1 -1
- package/src/talos/resource.ts +1 -1
- package/src/talos/talos-bootstrap.test.ts +1 -1
- package/src/talos/talos-cluster-health.test.ts +1 -1
- package/src/talos/talosctl.ts +2 -2
- package/src/telemetry/http-client-sealing.test.ts +2 -2
- package/src/telemetry/layer.test.ts +3 -3
- package/src/telemetry/layer.ts +2 -2
- package/src/telemetry/redact-serialization.ts +2 -2
- package/src/unifi/fake-unifi.ts +1 -1
- package/src/unifi/get-only-guard.test.ts +3 -3
- package/src/unifi/resource.ts +1 -1
- package/src/verify/args.ts +1 -1
|
@@ -51,12 +51,14 @@ const makeFake = () =>
|
|
|
51
51
|
],
|
|
52
52
|
});
|
|
53
53
|
|
|
54
|
-
describe('measured: the "char" relkind column
|
|
55
|
-
|
|
54
|
+
describe('measured: the "char" relkind column on the socket transport', () => {
|
|
55
|
+
// ★ MEASURED 2026-10-06 on @effect/sql-pg 4.0.1: OID 18 now decodes to the string (rc.115 had no
|
|
56
|
+
// codec and returned `Uint8Array([114])`). The `::text` cast stays: it is correct on both, and
|
|
57
|
+
// the readGrants tests below fail if it is dropped from the SQL the fake shapes rows from.
|
|
58
|
+
test('PgTypes.decode answers a string for OID 18 on 4.0.1 (rc.115 answered raw bytes)', () => {
|
|
56
59
|
const decoded = PgTypes.decode(new Uint8Array([114]), 18, 1);
|
|
57
60
|
if (!Result.isSuccess(decoded)) throw new Error('fixture: decode failed for OID 18');
|
|
58
|
-
expect(decoded.success
|
|
59
|
-
expect(decoded.success).not.toBe('r');
|
|
61
|
+
expect(decoded.success).toBe('r');
|
|
60
62
|
});
|
|
61
63
|
|
|
62
64
|
test('the same byte string decodes as a string through the OID 25 text codec', () => {
|
package/src/postgres/index.ts
CHANGED
|
@@ -49,7 +49,9 @@ export {
|
|
|
49
49
|
diffPostgresSchema,
|
|
50
50
|
isPostgresSchema,
|
|
51
51
|
} from './schema.ts';
|
|
52
|
+
export { PostgresSchemaCascadeSequencesRefused } from './schema-sequence-error.ts';
|
|
52
53
|
export {
|
|
54
|
+
PostgresSchemaCascadeCrossSchemaRefused,
|
|
53
55
|
PostgresSchemaCreateVanished,
|
|
54
56
|
PostgresSchemaExistsRefused,
|
|
55
57
|
PostgresSchemaIdentityRefused,
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
* `PgConnection.ts#classifyFields` calls. If the driver moves the file, the import fails
|
|
9
9
|
* loudly in the tests that use it rather than silently asserting a fabricated shape.
|
|
10
10
|
*/
|
|
11
|
-
import { SqlError } from 'effect/
|
|
11
|
+
import { SqlError } from 'effect/sql/SqlError';
|
|
12
12
|
|
|
13
13
|
export const classifyInstalled = async (
|
|
14
14
|
code: string,
|
|
@@ -6,6 +6,7 @@ import { parseLiteral } from './fake-sql-quote.ts';
|
|
|
6
6
|
import { buildCommentSchemaSql } from './schema-sql.ts';
|
|
7
7
|
import { buildSetPasswordSql } from './role-sql.ts';
|
|
8
8
|
import { makePsqlExecutor, redactPasswordLiterals } from './psql-executor.ts';
|
|
9
|
+
import { stripPin } from './search-path.ts';
|
|
9
10
|
|
|
10
11
|
const payload = "\\'; CREATE SCHEMA injected; --";
|
|
11
12
|
const target = { database: 'postgres', username: 'postgres' };
|
|
@@ -22,7 +23,8 @@ for (const on of [true, false]) {
|
|
|
22
23
|
test(`psql executor comment and bound param stay one literal with standard_conforming_strings=${String(on)}`, async () => {
|
|
23
24
|
const fake = makeFakeSql({ schemas: [row], standardConformingStrings: on });
|
|
24
25
|
const calls: string[] = [];
|
|
25
|
-
const pg = makePsqlExecutor(async ({ stdin }) => {
|
|
26
|
+
const pg = makePsqlExecutor(async ({ stdin: raw }) => {
|
|
27
|
+
const stdin = stripPin(raw);
|
|
26
28
|
calls.push(stdin);
|
|
27
29
|
if (stdin.startsWith('COMMENT')) {
|
|
28
30
|
await Effect.runPromise(fake.unsafe(stdin.slice(0, -1)));
|
|
@@ -7,6 +7,7 @@ import { buildCreateDatabaseSql, isDuplicateDatabaseRace } from './database-sql.
|
|
|
7
7
|
import { buildSetPasswordSql } from './role-sql.ts';
|
|
8
8
|
import { scramSha256Verifier } from './role-scram.ts';
|
|
9
9
|
import { type PsqlRunner, inlineParams, makePsqlExecutor } from './psql-executor.ts';
|
|
10
|
+
import { stripPin } from './search-path.ts';
|
|
10
11
|
|
|
11
12
|
const target = { database: 'postgres', username: 'postgres' };
|
|
12
13
|
const ok = (stdout: string) => Promise.resolve({ code: 0, stdout, stderr: '' });
|
|
@@ -24,7 +25,10 @@ describe('psql executor', () => {
|
|
|
24
25
|
return ok('[{"oid":"16400","name":"x"}]\n');
|
|
25
26
|
};
|
|
26
27
|
const rows = await Effect.runPromise(
|
|
27
|
-
makePsqlExecutor(run, target).unsafe(
|
|
28
|
+
makePsqlExecutor(run, target).unsafe(
|
|
29
|
+
'SELECT 1 FROM pg_catalog.pg_database WHERE datname = $1',
|
|
30
|
+
['x'],
|
|
31
|
+
),
|
|
28
32
|
);
|
|
29
33
|
expect(rows).toEqual([{ oid: 16400, name: 'x' }]);
|
|
30
34
|
expect(calls[0]?.argv.slice(0, 1)).toEqual(['psql']);
|
|
@@ -114,10 +118,12 @@ describe('runner transport through withPg', () => {
|
|
|
114
118
|
tablespace: 'pg_default',
|
|
115
119
|
};
|
|
116
120
|
let created = false;
|
|
117
|
-
const run: PsqlRunner = ({ stdin }) => {
|
|
121
|
+
const run: PsqlRunner = ({ stdin: raw }) => {
|
|
122
|
+
const stdin = stripPin(raw);
|
|
118
123
|
stdins.push(stdin);
|
|
119
|
-
if (stdin.includes('pg_roles')) return ok('[{"present":1}]');
|
|
120
|
-
if (stdin.includes('FROM pg_database'))
|
|
124
|
+
if (stdin.includes('pg_catalog.pg_roles')) return ok('[{"present":1}]');
|
|
125
|
+
if (stdin.includes('FROM pg_catalog.pg_database'))
|
|
126
|
+
return ok(created ? JSON.stringify([row]) : '[]');
|
|
121
127
|
if (stdin.startsWith('CREATE DATABASE')) created = true;
|
|
122
128
|
return ok('');
|
|
123
129
|
};
|
|
@@ -141,7 +147,7 @@ describe('runner transport through withPg', () => {
|
|
|
141
147
|
test('transaction is one psql script from BEGIN through COMMIT', async () => {
|
|
142
148
|
const calls: string[] = [];
|
|
143
149
|
const run: PsqlRunner = (call) => {
|
|
144
|
-
calls.push(call.stdin);
|
|
150
|
+
calls.push(stripPin(call.stdin));
|
|
145
151
|
return ok('');
|
|
146
152
|
};
|
|
147
153
|
await Effect.runPromise(
|
|
@@ -14,17 +14,14 @@
|
|
|
14
14
|
* ★ ROWS COME BACK AS JSON: a row-returning statement (`SELECT`, or a `WITH` query) is wrapped
|
|
15
15
|
* in `json_agg`, so `oid` and `datconnlimit` arrive as JS numbers exactly as the socket client
|
|
16
16
|
* decodes them (database-sql.ts, no bigint).
|
|
17
|
+
* ⛔ EVERY SCRIPT IS PREFIXED WITH `SET search_path = pg_catalog, pg_temp;` — see `search-path.ts`.
|
|
17
18
|
* ★ `VERBOSITY=verbose` puts the SQLSTATE in the error line, so `42P04` (duplicate database)
|
|
18
19
|
* stays recognisable to `isDuplicateDatabaseRace`.
|
|
19
20
|
*/
|
|
20
21
|
import * as Effect from 'effect/Effect';
|
|
21
|
-
import {
|
|
22
|
-
ConnectionError,
|
|
23
|
-
SqlError,
|
|
24
|
-
SqlSyntaxError,
|
|
25
|
-
UnknownError,
|
|
26
|
-
} from 'effect/unstable/sql/SqlError';
|
|
22
|
+
import { ConnectionError, SqlError, SqlSyntaxError, UnknownError } from 'effect/sql/SqlError';
|
|
27
23
|
import { type PgExecutor, quoteStringLiteral } from './database-sql.ts';
|
|
24
|
+
import { PIN_SCRIPT_PREFIX } from './search-path.ts';
|
|
28
25
|
|
|
29
26
|
export interface PsqlResult {
|
|
30
27
|
readonly code: number;
|
|
@@ -122,7 +119,8 @@ const runScript = (
|
|
|
122
119
|
'-d',
|
|
123
120
|
target.database,
|
|
124
121
|
],
|
|
125
|
-
|
|
122
|
+
// ⛔ EVERY psql SESSION STARTS PINNED (`search-path.ts`): one process, one session.
|
|
123
|
+
stdin: `${PIN_SCRIPT_PREFIX}${stdin}`,
|
|
126
124
|
}),
|
|
127
125
|
catch: (cause) =>
|
|
128
126
|
new SqlError({ reason: new ConnectionError({ cause, operation: 'psql exec' }) }),
|
|
@@ -13,6 +13,7 @@ import * as Effect from 'effect/Effect';
|
|
|
13
13
|
import { postgresRunnerConnection } from './connection.ts';
|
|
14
14
|
import { parseLiteral } from './fake-sql-quote.ts';
|
|
15
15
|
import { makeFakeSql } from './fake-sql.ts';
|
|
16
|
+
import { stripPin } from './search-path.ts';
|
|
16
17
|
import { type PsqlRunner } from './psql-executor.ts';
|
|
17
18
|
import { postgresRoleHandlers } from './role-provider.ts';
|
|
18
19
|
import type { PostgresRoleAttributes, PostgresRoleProps } from './role-attrs.ts';
|
|
@@ -42,7 +43,8 @@ const liveRole = (): PostgresRoleAttributes => ({
|
|
|
42
43
|
*/
|
|
43
44
|
const runnerFor =
|
|
44
45
|
(fake: ReturnType<typeof makeFakeSql>): PsqlRunner =>
|
|
45
|
-
async ({ stdin }) => {
|
|
46
|
+
async ({ stdin: raw }) => {
|
|
47
|
+
const stdin = stripPin(raw);
|
|
46
48
|
const wrapped = /^SELECT coalesce\(json_agg\(t\), '\[\]'::json\)::text FROM \((.*)\) t;$/s.exec(
|
|
47
49
|
stdin,
|
|
48
50
|
);
|
|
@@ -3,6 +3,7 @@ import * as Effect from 'effect/Effect';
|
|
|
3
3
|
import { makeFakeSql } from './fake-sql.ts';
|
|
4
4
|
import { buildRepairMembershipSql, syncMemberships } from './role-membership-sql.ts';
|
|
5
5
|
import { makePsqlExecutor } from './psql-executor.ts';
|
|
6
|
+
import { stripPin } from './search-path.ts';
|
|
6
7
|
|
|
7
8
|
const props = {
|
|
8
9
|
name: 'seat',
|
|
@@ -34,7 +35,8 @@ test.each(['2BP01', '42501'])(
|
|
|
34
35
|
// denial); the real server is the dependency authority.
|
|
35
36
|
const scripts: string[] = [];
|
|
36
37
|
const pg = makePsqlExecutor(
|
|
37
|
-
({ stdin }) => {
|
|
38
|
+
({ stdin: raw }) => {
|
|
39
|
+
const stdin = stripPin(raw);
|
|
38
40
|
scripts.push(stdin);
|
|
39
41
|
return Promise.resolve(
|
|
40
42
|
stdin.startsWith('BEGIN')
|
|
@@ -84,9 +84,9 @@ test('reads INHERIT and repairs another grantor row for declared NOINHERIT', asy
|
|
|
84
84
|
expect(before?.memberships).toEqual([
|
|
85
85
|
{ parent: 'parent', grantor: 'other', admin: false, set: false, inherit: true },
|
|
86
86
|
]);
|
|
87
|
-
expect(
|
|
88
|
-
|
|
89
|
-
);
|
|
87
|
+
expect(
|
|
88
|
+
fake.statements.find((s) => s.text.includes('FROM pg_catalog.pg_auth_members'))?.text,
|
|
89
|
+
).toContain('m.inherit_option AS inherit');
|
|
90
90
|
expect(await Effect.runPromise(diffPostgresRole(props, live, {}, { found: before }))).toEqual({
|
|
91
91
|
action: 'update',
|
|
92
92
|
});
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
* (`revoke.sgml`). Every revoke here names `GRANTED BY`. A mismatched grantor can still
|
|
15
15
|
* produce only a warning; the catalog re-read below catches surviving unsafe rows.
|
|
16
16
|
*/
|
|
17
|
-
import type { SqlError } from 'effect/
|
|
17
|
+
import type { SqlError } from 'effect/sql/SqlError';
|
|
18
18
|
import * as Effect from 'effect/Effect';
|
|
19
19
|
import type { PgExecutor } from './database-sql.ts';
|
|
20
20
|
import { quoteIdent, roleExists } from './database-sql.ts';
|
|
@@ -40,10 +40,10 @@ const MEMBERSHIP_SQL = `SELECT parent.rolname AS parent,
|
|
|
40
40
|
m.admin_option AS admin,
|
|
41
41
|
m.set_option AS set,
|
|
42
42
|
m.inherit_option AS inherit
|
|
43
|
-
FROM pg_auth_members m
|
|
44
|
-
JOIN pg_roles member ON member.oid = m.member
|
|
45
|
-
JOIN pg_roles parent ON parent.oid = m.roleid
|
|
46
|
-
LEFT JOIN pg_roles grantor ON grantor.oid = m.grantor
|
|
43
|
+
FROM pg_catalog.pg_auth_members m
|
|
44
|
+
JOIN pg_catalog.pg_roles member ON member.oid = m.member
|
|
45
|
+
JOIN pg_catalog.pg_roles parent ON parent.oid = m.roleid
|
|
46
|
+
LEFT JOIN pg_catalog.pg_roles grantor ON grantor.oid = m.grantor
|
|
47
47
|
WHERE member.rolname = $1
|
|
48
48
|
ORDER BY parent.rolname, grantor.rolname NULLS FIRST`;
|
|
49
49
|
|
|
@@ -4,11 +4,12 @@ import * as PgClient from '@effect/sql-pg/PgClient';
|
|
|
4
4
|
import * as Effect from 'effect/Effect';
|
|
5
5
|
import * as Stream from 'effect/Stream';
|
|
6
6
|
import * as Tracer from 'effect/Tracer';
|
|
7
|
-
import * as Statement from 'effect/
|
|
8
|
-
import type { Connection } from 'effect/
|
|
7
|
+
import * as Statement from 'effect/sql/Statement';
|
|
8
|
+
import type { Connection } from 'effect/sql/SqlConnection';
|
|
9
9
|
import type { PgExecutor } from './database-sql.ts';
|
|
10
10
|
import { makeFakeSql } from './fake-sql.ts';
|
|
11
11
|
import { type PsqlRunner, makePsqlExecutor } from './psql-executor.ts';
|
|
12
|
+
import { stripPin } from './search-path.ts';
|
|
12
13
|
import { reconcileWithClient } from './role.ts';
|
|
13
14
|
|
|
14
15
|
const props = {
|
|
@@ -84,7 +85,8 @@ test('psql runner receives only a verifier; echoed failure and state hold no pla
|
|
|
84
85
|
for (const fail of [false, true]) {
|
|
85
86
|
const calls: Parameters<PsqlRunner>[0][] = [];
|
|
86
87
|
let created = exists;
|
|
87
|
-
const run: PsqlRunner = (
|
|
88
|
+
const run: PsqlRunner = (raw) => {
|
|
89
|
+
const call = { ...raw, stdin: stripPin(raw.stdin) };
|
|
88
90
|
calls.push(call);
|
|
89
91
|
if (call.stdin.includes('PASSWORD') && fail) {
|
|
90
92
|
return Promise.resolve({
|
|
@@ -97,7 +99,7 @@ test('psql runner receives only a verifier; echoed failure and state hold no pla
|
|
|
97
99
|
return Promise.resolve({
|
|
98
100
|
code: 0,
|
|
99
101
|
stderr: '',
|
|
100
|
-
stdout: call.stdin.includes('FROM pg_roles r')
|
|
102
|
+
stdout: call.stdin.includes('FROM pg_catalog.pg_roles r')
|
|
101
103
|
? JSON.stringify(created ? [live] : [])
|
|
102
104
|
: '[]',
|
|
103
105
|
});
|
package/src/postgres/role-sql.ts
CHANGED
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
* and the `pg_auth_members` read live in `role-membership-sql.ts` — this file stays the role
|
|
18
18
|
* row (`pg_roles`), its scalar statements and the compare between them.
|
|
19
19
|
*/
|
|
20
|
-
import type { SqlError } from 'effect/
|
|
20
|
+
import type { SqlError } from 'effect/sql/SqlError';
|
|
21
21
|
import * as Effect from 'effect/Effect';
|
|
22
22
|
import type { PgExecutor } from './database-sql.ts';
|
|
23
23
|
import { quoteIdent, quoteStringLiteral } from './database-sql.ts';
|
|
@@ -46,7 +46,7 @@ const SELECT_ROLE_SQL = `SELECT
|
|
|
46
46
|
r.rolreplication AS replication,
|
|
47
47
|
r.rolbypassrls AS bypassrls,
|
|
48
48
|
to_char(r.rolvaliduntil AT TIME ZONE 'UTC', 'YYYY-MM-DD"T"HH24:MI:SS.MS"Z"') AS "validUntil"
|
|
49
|
-
FROM pg_roles r
|
|
49
|
+
FROM pg_catalog.pg_roles r
|
|
50
50
|
WHERE r.rolname = $1`;
|
|
51
51
|
|
|
52
52
|
export const selectRole = (
|
package/src/postgres/role.ts
CHANGED
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
import { Resource } from 'alchemy';
|
|
30
30
|
import * as Effect from 'effect/Effect';
|
|
31
31
|
import * as Redacted from 'effect/Redacted';
|
|
32
|
-
import type { SqlError } from 'effect/
|
|
32
|
+
import type { SqlError } from 'effect/sql/SqlError';
|
|
33
33
|
import { type Environment } from '../secrets/write-only.ts';
|
|
34
34
|
import type { PostgresRoleAttributes, PostgresRoleProps } from './role-attrs.ts';
|
|
35
35
|
import { nameByteRefusal, validUntilRefusal } from './role-attrs.ts';
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
* refused, and nothing is dropped.
|
|
20
20
|
*/
|
|
21
21
|
import * as Effect from 'effect/Effect';
|
|
22
|
-
import type { SqlError } from 'effect/
|
|
22
|
+
import type { SqlError } from 'effect/sql/SqlError';
|
|
23
23
|
import type { PgExecutor } from './database-sql.ts';
|
|
24
24
|
import {
|
|
25
25
|
type PostgresSchemaAttributes,
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The dependency closure `DROP SCHEMA … CASCADE` would walk, and the count of what it would take
|
|
3
|
+
* that does NOT live in the schema being dropped (`schema-drop-sql.ts` refuses when it is > 0).
|
|
4
|
+
*
|
|
5
|
+
* ⛔ THE CLOSURE IS DERIVED FROM THE NAMESPACE OBJECT, NOT FROM A LIST OF CLASSES. Until
|
|
6
|
+
* 2026-10-06 the scan started from four catalogs (`pg_class`, `pg_type`, `pg_proc`,
|
|
7
|
+
* `pg_operator`), so `a.c` (a collation) used by `b.t.x` was invisible and the cascade reached
|
|
8
|
+
* into `b.t.x` (Codex read of PR 357). Now the walk starts at `(pg_namespace, v_ns)` and follows
|
|
9
|
+
* EVERY `pg_depend` row whose referenced object is already inside — the same edges
|
|
10
|
+
* `findDependentObjects` (`dependency.c`) follows — so any object class `pg_depend` can name
|
|
11
|
+
* (collation, conversion, opclass, opfamily, text-search, statistics, extension members, …)
|
|
12
|
+
* is reached with no catalog enumerated to find it.
|
|
13
|
+
* ★ EVERY `deptype` FOLLOWS (`pg_depend`, catalogs.sgml); they differ only in attribution:
|
|
14
|
+
* n NORMAL cascade drops the dependent → followed; foreign if it lives elsewhere
|
|
15
|
+
* a AUTO dropped with any drop → followed; foreign if it lives elsewhere
|
|
16
|
+
* (an owned sequence in another schema is dropped with its table)
|
|
17
|
+
* i INTERNAL a part of the referenced object → followed; attributed to its owner (below)
|
|
18
|
+
* P / S partition primary / secondary → followed; a partition in another
|
|
19
|
+
* schema is dropped with its parent, so it is foreign
|
|
20
|
+
* e EXTENSION member of an extension → followed; the extension's members are
|
|
21
|
+
* dropped with it, wherever they live
|
|
22
|
+
* x AUTO-EXT auto, and dropped with the extension → followed like `a`
|
|
23
|
+
* p PIN system object, `refobjid = 0` → never a referenced row, never joins
|
|
24
|
+
* ★ "INSIDE" is a home-schema test per class. TOAST is the case the old scan got wrong: a text
|
|
25
|
+
* table's TOAST relation (and its index) lives in `pg_toast` and depends internally on the
|
|
26
|
+
* table, so it is attributed to the table that owns it via `reltoastrelid` — otherwise every
|
|
27
|
+
* cascade of a schema with a text column was refused. Constraints, triggers, rules, policies
|
|
28
|
+
* and defaults have no schema of their own and take their table's.
|
|
29
|
+
* ⚠️ A CLASS THIS FILE DOES NOT KNOW (a cast, a foreign server, a language, an event trigger)
|
|
30
|
+
* resolves to NULL, which is NOT inside: it counts as foreign. Unknown fails CLOSED. The walk
|
|
31
|
+
* stops at a foreign object — one is enough to refuse.
|
|
32
|
+
* ★ A dependent created AFTER this scan is held off by the caller's locks (`schema-drop-sql.ts`).
|
|
33
|
+
*/
|
|
34
|
+
|
|
35
|
+
const cls = (name: string): string => `'pg_catalog.${name}'::pg_catalog.regclass`;
|
|
36
|
+
|
|
37
|
+
/** `WHEN <class> THEN <namespace column of the row>` for a catalog that carries its own. */
|
|
38
|
+
const direct = (table: string, column: string): string =>
|
|
39
|
+
`WHEN ${cls(table)} THEN (SELECT x.${column} FROM pg_catalog.${table} x WHERE x.oid = d.objid)`;
|
|
40
|
+
|
|
41
|
+
/** The same for an object with no schema of its own: the schema of the relation it hangs on. */
|
|
42
|
+
const viaRelation = (table: string, column: string): string =>
|
|
43
|
+
`WHEN ${cls(table)} THEN (SELECT c.relnamespace FROM pg_catalog.${table} x JOIN pg_catalog.pg_class c ON c.oid = x.${column} WHERE x.oid = d.objid)`;
|
|
44
|
+
|
|
45
|
+
/** An access-method member belongs to its operator family. */
|
|
46
|
+
const viaFamily = (table: string, column: string): string =>
|
|
47
|
+
`WHEN ${cls(table)} THEN (SELECT f.opfnamespace FROM pg_catalog.${table} x JOIN pg_catalog.pg_opfamily f ON f.oid = x.${column} WHERE x.oid = d.objid)`;
|
|
48
|
+
|
|
49
|
+
/** A relation's home. A TOAST relation, or the index on one, is its owner's. */
|
|
50
|
+
const RELATION_HOME = `WHEN ${cls('pg_class')} THEN COALESCE(
|
|
51
|
+
(SELECT o.relnamespace FROM pg_catalog.pg_class o
|
|
52
|
+
WHERE o.reltoastrelid <> 0
|
|
53
|
+
AND o.reltoastrelid IN (d.objid, (SELECT i.indrelid FROM pg_catalog.pg_index i WHERE i.indexrelid = d.objid))),
|
|
54
|
+
(SELECT x.relnamespace FROM pg_catalog.pg_class x WHERE x.oid = d.objid))`;
|
|
55
|
+
|
|
56
|
+
const HOME_OF_DEPENDENT = `CASE d.classid
|
|
57
|
+
WHEN ${cls('pg_namespace')} THEN d.objid
|
|
58
|
+
${RELATION_HOME}
|
|
59
|
+
${direct('pg_type', 'typnamespace')}
|
|
60
|
+
${direct('pg_proc', 'pronamespace')}
|
|
61
|
+
${direct('pg_operator', 'oprnamespace')}
|
|
62
|
+
${direct('pg_collation', 'collnamespace')}
|
|
63
|
+
${direct('pg_conversion', 'connamespace')}
|
|
64
|
+
${direct('pg_opclass', 'opcnamespace')}
|
|
65
|
+
${direct('pg_opfamily', 'opfnamespace')}
|
|
66
|
+
${direct('pg_ts_config', 'cfgnamespace')}
|
|
67
|
+
${direct('pg_ts_dict', 'dictnamespace')}
|
|
68
|
+
${direct('pg_ts_parser', 'prsnamespace')}
|
|
69
|
+
${direct('pg_ts_template', 'tmplnamespace')}
|
|
70
|
+
${direct('pg_statistic_ext', 'stxnamespace')}
|
|
71
|
+
${direct('pg_constraint', 'connamespace')}
|
|
72
|
+
${direct('pg_default_acl', 'defaclnamespace')}
|
|
73
|
+
${direct('pg_extension', 'extnamespace')}
|
|
74
|
+
${viaRelation('pg_trigger', 'tgrelid')}
|
|
75
|
+
${viaRelation('pg_rewrite', 'ev_class')}
|
|
76
|
+
${viaRelation('pg_attrdef', 'adrelid')}
|
|
77
|
+
${viaRelation('pg_policy', 'polrelid')}
|
|
78
|
+
${viaRelation('pg_publication_rel', 'prrelid')}
|
|
79
|
+
${viaFamily('pg_amop', 'amopfamily')}
|
|
80
|
+
${viaFamily('pg_amproc', 'amprocfamily')}
|
|
81
|
+
END`;
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* `v_count := …`: how many objects the cascade would drop outside `v_ns`, PLUS how many objects
|
|
85
|
+
* INSIDE it hold an `e` or `i` edge to an object outside the closure.
|
|
86
|
+
* ⛔ THE SECOND TERM IS THE OWNERSHIP ESCAPE (Codex read of PR 357, 2026-10-06). An inside table
|
|
87
|
+
* added to a foreign extension (`ALTER EXTENSION x ADD TABLE a.t`) has an OUTGOING `e` edge; the
|
|
88
|
+
* walk only follows edges INTO the closure, so it saw nothing, while `findDependentObjects`
|
|
89
|
+
* redirects the deletion of an extension member / internal part to its OWNER and drops that
|
|
90
|
+
* owner's other objects too. Any outgoing `e` or `i` edge leaving the closure counts as foreign:
|
|
91
|
+
* refuse, never follow-and-classify (the simplest correct answer fails closed).
|
|
92
|
+
*/
|
|
93
|
+
export const OUTSIDE_DEPENDENTS_SQL = `v_count := (
|
|
94
|
+
WITH RECURSIVE reach (classid, objid, inside) AS (
|
|
95
|
+
SELECT ${cls('pg_namespace')}::pg_catalog.oid, v_ns, true
|
|
96
|
+
UNION
|
|
97
|
+
SELECT d.classid, d.objid, (${HOME_OF_DEPENDENT}) IS NOT DISTINCT FROM v_ns
|
|
98
|
+
FROM pg_catalog.pg_depend d
|
|
99
|
+
JOIN reach r ON d.refclassid = r.classid AND d.refobjid = r.objid AND r.inside
|
|
100
|
+
WHERE d.deptype <> 'p'
|
|
101
|
+
)
|
|
102
|
+
SELECT (SELECT pg_catalog.count(*) FROM reach WHERE NOT inside)
|
|
103
|
+
+ (SELECT pg_catalog.count(*) FROM pg_catalog.pg_depend e
|
|
104
|
+
JOIN reach r ON e.classid = r.classid AND e.objid = r.objid AND r.inside
|
|
105
|
+
WHERE e.deptype IN ('e', 'i') AND e.refobjid <> 0
|
|
106
|
+
AND NOT EXISTS (SELECT 1 FROM reach o
|
|
107
|
+
WHERE o.inside AND o.classid = e.refclassid AND o.objid = e.refobjid))
|
|
108
|
+
)`;
|
|
@@ -65,7 +65,7 @@ describe('delete drops only what it can prove it created (Important 1)', () => {
|
|
|
65
65
|
),
|
|
66
66
|
),
|
|
67
67
|
);
|
|
68
|
-
expect(stdins.some((s) => s.startsWith('
|
|
68
|
+
expect(stdins.some((s) => s.startsWith('DO '))).toBe(false);
|
|
69
69
|
});
|
|
70
70
|
|
|
71
71
|
test('refuses on oid mismatch, CASCADE included — no DROP issued', async () => {
|
|
@@ -91,7 +91,7 @@ describe('delete drops only what it can prove it created (Important 1)', () => {
|
|
|
91
91
|
lastOid: 16442,
|
|
92
92
|
lastOwner: 'seat_role',
|
|
93
93
|
});
|
|
94
|
-
expect(stdins.some((s) => s.startsWith('
|
|
94
|
+
expect(stdins.some((s) => s.startsWith('DO '))).toBe(false);
|
|
95
95
|
// Refused before the guarded drop, so the emptiness check never ran either.
|
|
96
96
|
expect(stdins.some((s) => s.includes('AS empty'))).toBe(false);
|
|
97
97
|
});
|
|
@@ -118,7 +118,7 @@ describe('delete drops only what it can prove it created (Important 1)', () => {
|
|
|
118
118
|
lastOid: 16442,
|
|
119
119
|
lastOwner: 'seat_role',
|
|
120
120
|
});
|
|
121
|
-
expect(stdins.some((s) => s.startsWith('
|
|
121
|
+
expect(stdins.some((s) => s.startsWith('DO '))).toBe(false);
|
|
122
122
|
});
|
|
123
123
|
|
|
124
124
|
test('a live row with no persisted proof fails closed — the delete client core refuses', async () => {
|
|
@@ -134,7 +134,7 @@ describe('delete drops only what it can prove it created (Important 1)', () => {
|
|
|
134
134
|
lastOid: undefined,
|
|
135
135
|
lastOwner: undefined,
|
|
136
136
|
});
|
|
137
|
-
expect(stdins.some((s) => s.startsWith('
|
|
137
|
+
expect(stdins.some((s) => s.startsWith('DO '))).toBe(false);
|
|
138
138
|
});
|
|
139
139
|
});
|
|
140
140
|
|
|
@@ -153,7 +153,7 @@ describe('a missing declared database is schema absent (Important 2)', () => {
|
|
|
153
153
|
),
|
|
154
154
|
);
|
|
155
155
|
expect(stdins.length).toBe(1);
|
|
156
|
-
expect(stdins[0]).toContain('FROM pg_database');
|
|
156
|
+
expect(stdins[0]).toContain('FROM pg_catalog.pg_database');
|
|
157
157
|
expect(argvs.length).toBe(1);
|
|
158
158
|
expect(argvs[0]?.at(-1)).toBe('postgres');
|
|
159
159
|
});
|
|
@@ -169,7 +169,7 @@ describe('a missing declared database is schema absent (Important 2)', () => {
|
|
|
169
169
|
);
|
|
170
170
|
expect(result).toBeUndefined();
|
|
171
171
|
expect(stdins.length).toBe(1);
|
|
172
|
-
expect(stdins[0]).toContain('FROM pg_database');
|
|
172
|
+
expect(stdins[0]).toContain('FROM pg_catalog.pg_database');
|
|
173
173
|
});
|
|
174
174
|
|
|
175
175
|
test('the `database` override reaches `psql -d`: the probe targets the family database, the rest the declared one', async () => {
|
|
@@ -185,7 +185,7 @@ describe('a missing declared database is schema absent (Important 2)', () => {
|
|
|
185
185
|
),
|
|
186
186
|
),
|
|
187
187
|
);
|
|
188
|
-
expect(stdins.some((s) => s.startsWith('
|
|
188
|
+
expect(stdins.some((s) => s.startsWith('DO '))).toBe(true);
|
|
189
189
|
expect(argvs[0]?.at(-1)).toBe('postgres');
|
|
190
190
|
expect(argvs.slice(1).every((argv) => argv.at(-1) === 'agents')).toBe(true);
|
|
191
191
|
});
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* `Postgres.Schema`'s drop path: prove the connection, prove the schema is still ours, then
|
|
3
|
-
*
|
|
3
|
+
* ONE atomic statement that re-proves it under a lock and drops (`schema-drop-sql.ts`).
|
|
4
4
|
*
|
|
5
5
|
* ⛔ THE ENGINE DOES NOT RE-READ BEFORE A DELETE THAT HAS STATE (alchemy `Apply.ts`). When
|
|
6
6
|
* persisted attributes exist, `delete` receives the LAST asserted `oid` + `owner` and no
|
|
@@ -10,87 +10,129 @@
|
|
|
10
10
|
* row that no longer matches the persisted proof fails with
|
|
11
11
|
* `PostgresSchemaDeleteForeignRefused` (`schema-assert.ts#deleteForeignRefusal`) before any
|
|
12
12
|
* `DROP` is issued.
|
|
13
|
+
* ⛔ THE RE-READ ALONE IS A WINDOW. It is a separate autocommit statement (a separate `psql` on
|
|
14
|
+
* the runner transport), so the schema can change between the read and the drop. The drop
|
|
15
|
+
* therefore carries the proven `oid` + `owner` INTO one `DO` block that locks, re-verifies
|
|
16
|
+
* them, checks emptiness or cross-schema dependents, and drops in one transaction. This
|
|
17
|
+
* file's read is the typed, readable refusal; the block is the guarantee.
|
|
13
18
|
*/
|
|
14
19
|
import * as Effect from 'effect/Effect';
|
|
15
|
-
import type { SqlError } from 'effect/
|
|
20
|
+
import type { SqlError } from 'effect/sql/SqlError';
|
|
16
21
|
import type { PgExecutor } from './database-sql.ts';
|
|
17
22
|
import type { PostgresSchemaAttributes, PostgresSchemaProps } from './schema-attrs.ts';
|
|
18
23
|
import { assertDatabase, deleteForeignRefusal } from './schema-assert.ts';
|
|
19
24
|
import {
|
|
20
|
-
|
|
25
|
+
PostgresSchemaCascadeCrossSchemaRefused,
|
|
26
|
+
PostgresSchemaDeleteForeignRefused,
|
|
21
27
|
PostgresSchemaDropNotEmptyError,
|
|
22
28
|
type PostgresSchemaWrongDatabase,
|
|
23
29
|
} from './schema-errors.ts';
|
|
24
30
|
import {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
31
|
+
CASCADE_SEQUENCES,
|
|
32
|
+
CROSS_SCHEMA_DEPENDENTS,
|
|
33
|
+
IDENTITY_CHANGED,
|
|
34
|
+
NOT_EMPTY,
|
|
35
|
+
buildAtomicDropSql,
|
|
36
|
+
dependentsCount,
|
|
37
|
+
sqlStateOf,
|
|
38
|
+
} from './schema-drop-sql.ts';
|
|
39
|
+
import { PostgresSchemaCascadeSequencesRefused, sequencesCount } from './schema-sequence-error.ts';
|
|
40
|
+
import { isDependentObjectsError, selectSchema } from './schema-sql.ts';
|
|
41
|
+
|
|
42
|
+
type DropError =
|
|
43
|
+
| PostgresSchemaDropNotEmptyError
|
|
44
|
+
| PostgresSchemaCascadeCrossSchemaRefused
|
|
45
|
+
| PostgresSchemaCascadeSequencesRefused
|
|
46
|
+
| PostgresSchemaDeleteForeignRefused
|
|
47
|
+
| SqlError;
|
|
30
48
|
|
|
31
49
|
/**
|
|
32
|
-
* The guarded `DROP SCHEMA
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
50
|
+
* The atomic guarded `DROP SCHEMA` for a row the caller has already read, against any
|
|
51
|
+
* {@link PgExecutor}. The server's refusals come back as typed tags: `HF001` (the row changed
|
|
52
|
+
* between read and drop) re-reads and refuses as a foreign schema; `HF002` and the server's own
|
|
53
|
+
* `2BP01` (an object kind the emptiness check's four catalogs miss) are the not-empty tag;
|
|
54
|
+
* `HF003` is the cross-schema dependents refusal, with the count only; `HF004` refuses a cascade
|
|
55
|
+
* over a schema holding a sequence.
|
|
37
56
|
*/
|
|
38
|
-
const
|
|
57
|
+
const dropAtomic = (
|
|
39
58
|
pg: PgExecutor,
|
|
40
59
|
props: PostgresSchemaProps,
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
}
|
|
60
|
+
live: PostgresSchemaAttributes,
|
|
61
|
+
): Effect.Effect<void, DropError> => {
|
|
62
|
+
const cascade = props.cascade === true;
|
|
63
|
+
const classify = (error: SqlError): Effect.Effect<void, DropError> => {
|
|
64
|
+
const state = sqlStateOf(error);
|
|
65
|
+
if (state === NOT_EMPTY || (!cascade && isDependentObjectsError(error))) {
|
|
66
|
+
return Effect.fail(new PostgresSchemaDropNotEmptyError({ schema: props.name }));
|
|
48
67
|
}
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
68
|
+
if (state === CROSS_SCHEMA_DEPENDENTS) {
|
|
69
|
+
return Effect.fail(
|
|
70
|
+
new PostgresSchemaCascadeCrossSchemaRefused({
|
|
71
|
+
schema: props.name,
|
|
72
|
+
dependents: dependentsCount(error),
|
|
73
|
+
}),
|
|
74
|
+
);
|
|
75
|
+
}
|
|
76
|
+
if (state === CASCADE_SEQUENCES) {
|
|
77
|
+
return Effect.fail(
|
|
78
|
+
new PostgresSchemaCascadeSequencesRefused({
|
|
79
|
+
schema: props.name,
|
|
80
|
+
sequences: sequencesCount(error),
|
|
81
|
+
}),
|
|
82
|
+
);
|
|
83
|
+
}
|
|
84
|
+
if (state === IDENTITY_CHANGED) {
|
|
85
|
+
return Effect.flatMap(selectSchema(pg, props.name), (now) =>
|
|
86
|
+
now === undefined
|
|
87
|
+
? Effect.void
|
|
88
|
+
: Effect.fail(
|
|
89
|
+
new PostgresSchemaDeleteForeignRefused({
|
|
90
|
+
schema: props.name,
|
|
91
|
+
database: props.database,
|
|
92
|
+
liveOid: now.oid,
|
|
93
|
+
liveOwner: now.owner,
|
|
94
|
+
lastOid: live.oid,
|
|
95
|
+
lastOwner: live.owner,
|
|
96
|
+
}),
|
|
97
|
+
),
|
|
98
|
+
);
|
|
99
|
+
}
|
|
100
|
+
return Effect.fail(error);
|
|
101
|
+
};
|
|
102
|
+
return pg
|
|
103
|
+
.unsafe(buildAtomicDropSql({ name: props.name, oid: live.oid, owner: live.owner, cascade }))
|
|
104
|
+
.pipe(Effect.asVoid, Effect.catchTag('SqlError', classify));
|
|
105
|
+
};
|
|
61
106
|
|
|
62
|
-
/** Prove the connected database, then the guarded drop
|
|
63
|
-
* tests that drive it directly.
|
|
107
|
+
/** Prove the connected database, then the guarded drop of whatever row is live now — the drop
|
|
108
|
+
* core on its own, for the tests that drive it directly. No persisted proof is consulted: the
|
|
109
|
+
* row read here is the row the atomic drop re-verifies. */
|
|
64
110
|
export const dropWithClient = (
|
|
65
111
|
pg: PgExecutor,
|
|
66
112
|
props: PostgresSchemaProps,
|
|
67
|
-
): Effect.Effect<void, PostgresSchemaWrongDatabase |
|
|
113
|
+
): Effect.Effect<void, PostgresSchemaWrongDatabase | DropError> =>
|
|
68
114
|
Effect.gen(function* () {
|
|
69
115
|
yield* assertDatabase(props, pg);
|
|
70
|
-
yield*
|
|
116
|
+
const live = yield* selectSchema(pg, props.name);
|
|
117
|
+
if (live === undefined) return;
|
|
118
|
+
yield* dropAtomic(pg, props, live);
|
|
71
119
|
});
|
|
72
120
|
|
|
73
121
|
/**
|
|
74
122
|
* The core of `delete`: re-read first (see the file header), refuse a schema the persisted
|
|
75
|
-
* proof cannot vouch for, then the guarded drop. `output` is the persisted state the
|
|
76
|
-
* hands over — `undefined` is no proof and refuses too.
|
|
123
|
+
* proof cannot vouch for, then the atomic guarded drop. `output` is the persisted state the
|
|
124
|
+
* engine hands over — `undefined` is no proof and refuses too.
|
|
77
125
|
*/
|
|
78
126
|
export const deleteWithClient = (
|
|
79
127
|
pg: PgExecutor,
|
|
80
128
|
props: PostgresSchemaProps,
|
|
81
129
|
output: PostgresSchemaAttributes | undefined,
|
|
82
|
-
): Effect.Effect<
|
|
83
|
-
void,
|
|
84
|
-
| PostgresSchemaWrongDatabase
|
|
85
|
-
| PostgresSchemaDeleteForeignRefused
|
|
86
|
-
| PostgresSchemaDropNotEmptyError
|
|
87
|
-
| SqlError
|
|
88
|
-
> =>
|
|
130
|
+
): Effect.Effect<void, PostgresSchemaWrongDatabase | DropError> =>
|
|
89
131
|
Effect.gen(function* () {
|
|
90
132
|
yield* assertDatabase(props, pg);
|
|
91
133
|
const live = yield* selectSchema(pg, props.name);
|
|
92
134
|
if (live === undefined) return;
|
|
93
135
|
const refusal = deleteForeignRefusal(props, live, output);
|
|
94
136
|
if (refusal !== undefined) return yield* Effect.fail(refusal);
|
|
95
|
-
yield*
|
|
137
|
+
yield* dropAtomic(pg, props, live);
|
|
96
138
|
});
|