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

@mrleebo/prisma-ast

v0.12.0

Published

This library uses an abstract syntax tree to parse schema.prisma files into an object in JavaScript. It is similar to [@prisma/sdk](https://github.com/prisma/prisma/tree/master/src/packages/sdk) except that it preserves comments and model attributes.

Downloads

711,232

Readme

@mrleebo/prisma-ast

This library uses an abstract syntax tree to parse schema.prisma files into an object in JavaScript. It also allows you to update your Prisma schema files using a Builder object pattern that is fully implemented in TypeScript.

It is similar to @prisma/sdk except that it preserves comments and model attributes. It also doesn't attempt to validate the correctness of the schema at all; the focus is instead on the ability to parse the schema into an object, manipulate it using JavaScript, and re-print the schema back to a file without losing information that isn't captured by other parsers.

It is probable that a future version of @prisma/sdk will render this library obsolete.

Install

npm install @mrleebo/prisma-ast

Examples

Produce a modified schema by building upon an existing schema

produceSchema(source: string, (builder: PrismaSchemaBuilder) => void, printOptions?: PrintOptions): string

produceSchema is the simplest way to interact with prisma-ast; you input your schema source and a producer function to produce modifications to it, and it will output the schema source with your modifications applied.

import { produceSchema } from '@mrleebo/prisma-ast';

const source = `
model User {
  id   Int    @id @default(autoincrement())
  name String @unique
}
`;

const output = produceSchema(source, (builder) => {
  builder
    .model('AppSetting')
    .field('key', 'String', [{ name: 'id' }])
    .field('value', 'Json');
});
model User {
  id   Int    @id @default(autoincrement())
  name String @unique
}

model AppSetting {
  key   String @id
  value Json
}

For more information about what the builder can do, check out the PrismaSchemaBuilder class.

PrismaSchemaBuilder

The produceSchema() utility will construct a builder for you, but you can also create your own instance, which may be useful for more interactive use-cases.

import { createPrismaSchemaBuilder } from '@mrleebo/prisma-ast';

const builder = createPrismaSchemaBuilder();

builder
  .model('User')
  .field('id', 'Int')
  .attribute('id')
  .attribute('default', [{ name: 'autoincrement' }])
  .field('name', 'String')
  .attribute('unique')
  .break()
  .comment('this is a comment')
  .blockAttribute('index', ['name']);

const output = builder.print();
model User {
  id   Int @id @default(autoincrement())
  name String @unique

  // this is a comment
  @@index([name])
}

Query the prisma schema for specific objects

The builder can also help you find matching objects in the schema based on name (by string or RegExp) or parent context. You can use this to write tests against your schema, or find fields that don't match a naming convention, for example.

const source = `
  model Product {
    id     String  @id @default(auto()) @map("_id") @db.ObjectId
    name   String
    photos Photo[]
  }
`

const builder = createPrismaSchemaBuilder(source);

const product = builder.findByType('model', { name: 'Product' });
expect(product).toHaveProperty('name', 'Product');

const id = builder.findByType('field', {
  name: 'id',
  within: product?.properties,
});
expect(id).toHaveProperty('name', 'id');

const map = builder.findByType('attribute', {
  name: 'map',
  within: id?.attributes,
});
expect(map).toHaveProperty('name', 'map');

Re-sort the schema

prisma-ast can sort the schema for you. The default sort order is ['generator', 'datasource', 'model', 'enum'] and will sort objects of the same type alphabetically.

print(options?: {
  sort: boolean,
  locales?: string | string[],
  sortOrder?: Array<'generator' | 'datasource' | 'model' | 'enum'>
})

You can optionally set your own sort order, or change the locale used by the sort.

// sort with default parameters
builder.print({ sort: true });

// sort with options
builder.print({
  sort: true,
  locales: 'en-US',
  sortOrder: ['datasource', 'generator', 'model', 'enum'],
});

Need More SchemaBuilder Code snippets?

There is a lot that you can do with the schema builder. There are additional sample references available for you to explore.

Configuration Options

prisma-ast uses lilconfig to read configuration options which can be located in any of the following files, and in several other variations (see the complete list of search paths):

  • "prisma-ast" in package.json
  • .prisma-astrc
  • .prisma-astrc.json
  • .prisma-astrc.js
  • .config/.prisma-astrc

Configuration options are:

| Option | Description | Default Value | | ----------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------- | | parser.nodeTrackingLocation | Include the token locations of CST Nodes in the output schema.Disabled by default because it can impact parsing performance.Possible values are "none", "onlyOffset", and "full". | "none" |

Example Custom Configuration

Here is an example of how you can customize your configuration options in package.json.

{
  "prisma-ast": {
    "parser": {
      "nodeTrackingLocation": "full"
    }
  }
}

Underlying utility functions

The produceSchema and createPrismaSchemaBuilder functions are intended to be your interface for interacting with the prisma schema, but you can also get direct access to the AST representation if you need to edit the schema for more advanced usages that aren't covered by the methods above.

Parse a schema.prisma file into an AST object

The shape of the AST is not fully documented, and it is more likely to change than the builder API.

import { getSchema } from '@mrleebo/prisma-ast';

const source = `
model User {
  id   Int    @id @default(autoincrement())
  name String @unique
}
`;

const schema = getSchema(source);

Print a schema AST back out as a string

This is what builder.print() calls internally, and is what you'd use to print if you called getSchema().

import { printSchema } from '@mrleebo/prisma-ast';

const source = printSchema(schema);

You can optionally re-sort the schema. The default sort order is ['generator', 'datasource', 'model', 'enum'], and objects with the same type are sorted alphabetically, but the sort order can be overridden.

const source = printSchema(schema, {
  sort: true,
  locales: 'en-US',
  sortOrder: ['datasource', 'generator', 'model', 'enum'],
});