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 🙏

© 2026 – Pkg Stats / Ryan Hefner

@ctxo/lang-sql

v0.1.0

Published

Ctxo SQL language plugin (T-SQL definitions and data access)

Readme

@ctxo/lang-sql

SQL language plugin for Ctxo. It reads .sql scripts (T-SQL), turns the objects they define into symbols, and links each object to the tables, views and procedures its body touches. Data coupling then shows up in blast radius, the contexts view and the other graph tools, next to code coupling.

It is a protocol v2 plugin (apiVersion: '2'), so it needs a Ctxo CLI that understands the data kinds. Tier: syntax. No database connection, no build step, no extra runtime: the recognizers live in the zero-dependency @ctxo/sql-extract library.

What it indexes

| Source | Becomes | |---|---| | CREATE [OR ALTER] TABLE | symbol of kind table, with a columns annotation (every column, lowercase, sorted) | | CREATE [OR ALTER] VIEW, ALTER VIEW | symbol of kind view | | CREATE [OR ALTER] PROC[EDURE], ALTER PROC[EDURE] | symbol of kind procedure | | CREATE [OR ALTER] FUNCTION, ALTER FUNCTION | symbol of kind function | | table and view references after FROM, JOIN, APPLY and MERGE ... USING in a body | reads edge | | INSERT, UPDATE, DELETE, MERGE, TRUNCATE TABLE, SELECT ... INTO, OUTPUT ... INTO in a body | writes edge | | EXEC / EXECUTE of a procedure in a body | executes edge |

Symbol ids look like db/schema.sql::dbo.loans::table: the canonical two-part name in lowercase (a missing schema is dbo). The symbol name keeps the spelling as declared, without delimiters and without an added schema. Edge targets are dbo.loans::table for reads and writes and dbo.usp_notifymember::procedure for executes; Ctxo resolves them to the defining file, whichever of table or view defines the name. When several files define the same object (migrations, a docs or test copy), a definition outside test files wins, then one outside docs, doc and documentation folders, then the codepoint-smallest path, and every copy reports the same dependents in the impact tools.

Rules in short

The decision record is ADR-017. The rules are pinned by the conformance corpus in packages/sql-extract/corpus, which this package's tests also run.

  • Names have one to four dot-separated parts. [...] and "..." delimiters are removed. Three- and four-part names, temp tables (#t), table variables (@t), CTE names and the sys and information_schema schemas are skipped.
  • Canonical names fold only ASCII A to Z. Ö, ı, İ and every other character are kept, so a name such as [dbo].[Ödünç Kaydı] matches byte for byte on every side.
  • Accesses come from the body of a view, procedure or function. Top-level DML in a script (an ad hoc SELECT or INSERT) produces no edges and no symbols.
  • A body ends at the end of its GO batch, or at the next view, procedure or function definition when GO is missing. CREATE TABLE or ALTER TABLE inside a body is body text: it defines nothing and adds no columns.
  • ALTER TABLE ... ADD outside a body adds columns to a table defined in the same file.
  • Two definitions of one object in a file merge into the first.
  • Comments, string literals and GO inside strings or comments never produce accesses. A leading byte order mark is ignored.
  • A table with no body has a symbol and no edges. A recursive procedure has no self edge.
  • SQL objects carry no complexity metrics, and a call to a SQL function is not an edge.

Effect on C#

When this plugin is installed, the CLI tells every plugin that .sql files are indexed (capabilities.sqlCallSites). The C# plugin then adds reads, writes and executes edges from a method to the tables and procedures named by constant SQL at known call sites (ADO.NET, Dapper including CommandDefinition, SqlBulkCopy, EF Core raw SQL). Those edges point at the same dbo.loans::table targets this plugin defines, so a C# method and the stored procedure that touches the same table meet in the graph. Without this plugin the C# plugin emits no SQL edges.

Install

ctxo install sql

Or add @ctxo/lang-sql to the project's devDependencies. Ctxo discovers it by name. ctxo init, ctxo doctor and ctxo index --install-missing suggest it when the repository has at least 5 .sql files that are also at least 2% of its files.

Limits

  • Only T-SQL is recognized.
  • A .sql file larger than 5 MiB is skipped with one warning (skipped <file>: <n> MiB is over the 5 MiB SQL size limit) and yields no symbols or edges.
  • Constant SQL only: dynamic SQL (EXEC (@sql), EXEC @proc) is skipped.
  • Only objects defined in indexed .sql files exist as symbols; a reference to an object defined elsewhere stays unresolved until its script is indexed.