npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@phamhieu1998/grid

v0.1.8

Published

A react component to display your Postgresql table data.

Downloads

10

Readme

Supabase Grid

A react component to display your Postgresql table data.

Usage

<SupabaseGrid
  table="countries"
  clientProps={{
    supabaseUrl: '',
    supabaseKey: '',
  }}
/>

table variable can be:

  • SupaTable obj
  • Table or View name
    • Readonly: support both table and view
    • Editable: only for table. Required to create Postgresql functions below so that it can pull your table info.

Import css

import 'react-contexify/dist/ReactContexify.css';

Postgresql Functions

Load table info

CREATE FUNCTION load_table_info(filter_schema text, filter_name text)
returns table (
  id int8,
  schema name,
  name name,
  rows_estimate int8,
  comment text
) LANGUAGE PLPGSQL
AS $$
BEGIN
  RETURN query
    SELECT
      c.oid :: int8 AS id,
      nc.nspname AS schema,
      c.relname AS name,
      pg_stat_get_live_tuples(c.oid) AS live_rows_estimate,
      obj_description(c.oid) AS comment
    FROM
      pg_namespace nc
      JOIN pg_class c ON nc.oid = c.relnamespace
    WHERE
      nc.nspname = filter_schema
      AND c.relname = filter_name
      AND c.relkind IN ('r', 'p')
      AND NOT pg_is_other_temp_schema(nc.oid)
      AND (
        pg_has_role(c.relowner, 'USAGE')
        OR has_table_privilege(
          c.oid,
          'SELECT, INSERT, UPDATE, DELETE, TRUNCATE, REFERENCES, TRIGGER'
        )
        OR has_any_column_privilege(c.oid, 'SELECT, INSERT, UPDATE, REFERENCES')
      );
END
$$;

Load table columns

CREATE FUNCTION load_table_columns(filter_schema text, filter_name text)
returns table (
  table_id int8,
  schema name,
  table_name name,
  id text,
  ordinal_position int2,
  name name,
  default_value text,
  data_type text,
  format name,
  is_identity bool,
  identity_generation text,
  is_nullable bool,
  is_updatable bool,
  enums json,
  comment text
) LANGUAGE PLPGSQL
AS $$
BEGIN
  RETURN query
    SELECT
      c.oid :: int8 AS table_id,
      nc.nspname AS schema,
      c.relname AS table,
      (c.oid || '.' || a.attnum) AS id,
      a.attnum AS ordinal_position,
      a.attname AS name,
      CASE
        WHEN a.atthasdef THEN pg_get_expr(ad.adbin, ad.adrelid)
        ELSE NULL
      END AS default_value,
      CASE
        WHEN t.typtype = 'd' THEN CASE
          WHEN bt.typelem <> 0 :: oid
          AND bt.typlen = -1 THEN 'ARRAY'
          WHEN nbt.nspname = 'pg_catalog' THEN format_type(t.typbasetype, NULL)
          ELSE 'USER-DEFINED'
        END
        ELSE CASE
          WHEN t.typelem <> 0 :: oid
          AND t.typlen = -1 THEN 'ARRAY'
          WHEN nt.nspname = 'pg_catalog' THEN format_type(a.atttypid, NULL)
          ELSE 'USER-DEFINED'
        END
      END AS data_type,
      COALESCE(bt.typname, t.typname) AS format,
      CASE
        WHEN a.attidentity IN ('a', 'd') THEN TRUE
        ELSE FALSE
      END AS is_identity,
      CASE
        a.attidentity
        WHEN 'a' THEN 'ALWAYS'
        WHEN 'd' THEN 'BY DEFAULT'
        ELSE NULL
      END AS identity_generation,
      CASE
        WHEN a.attnotnull
        OR t.typtype = 'd'
        AND t.typnotnull THEN FALSE
        ELSE TRUE
      END AS is_nullable,
      CASE
        WHEN (
          c.relkind IN ('r', 'p')
        )
        OR (
          c.relkind IN ('v', 'f')
        )
        AND pg_column_is_updatable(c.oid, a.attnum, FALSE) THEN TRUE
        ELSE FALSE
      END AS is_updatable,
      array_to_json(
        array(
          SELECT
            enumlabel
          FROM
            pg_catalog.pg_enum enums
          WHERE
            COALESCE(bt.typname, t.typname) = format_type(enums.enumtypid, NULL)
          ORDER BY
            enums.enumsortorder
        )
      ) AS enums,
      col_description(c.oid, a.attnum) AS comment
    FROM
      pg_attribute a
      LEFT JOIN pg_attrdef ad ON a.attrelid = ad.adrelid
      AND a.attnum = ad.adnum
      JOIN (
        pg_class c
        JOIN pg_namespace nc ON c.relnamespace = nc.oid
      ) ON a.attrelid = c.oid
      JOIN (
        pg_type t
        JOIN pg_namespace nt ON t.typnamespace = nt.oid
      ) ON a.atttypid = t.oid
      LEFT JOIN (
        pg_type bt
        JOIN pg_namespace nbt ON bt.typnamespace = nbt.oid
      ) ON t.typtype = 'd'
      AND t.typbasetype = bt.oid
    WHERE
      NOT pg_is_other_temp_schema(nc.oid)
      AND nc.nspname = filter_schema
      AND c.relname = filter_name
      AND a.attnum > 0
      AND NOT a.attisdropped
      AND (c.relkind IN ('r', 'v', 'f', 'p'))
      AND (
        pg_has_role(c.relowner, 'USAGE')
        OR has_column_privilege(
          c.oid,
          a.attnum,
          'SELECT, INSERT, UPDATE, REFERENCES'
        )
      );
END
$$;