edgedb-js icon indicating copy to clipboard operation
edgedb-js copied to clipboard

Add annotations to interfaces generated by the interfaces generator

Open scotttrinh opened this issue 2 years ago • 1 comments

Using the three standard annotations (title, description, and deprecated), we can add TSDoc comments to the interfaces and properties to show more rich information in IDEs that support it.

  • Title should use a markdown heading (tbd which looks best, by maybe h2?)
  • Description should be the body of the comment
  • Type annotations should be added to the interface itself
  • Property annotations should be added to the interface's properties
  • Custom annotations should be added as a markdown table

Example

Given the following schema:

module default {
  type User {
    annotation title := "User"
    annotation description := "An authenticated account"

    required name: str {
      annotation description := "Full name of user"
      annotation is_personal_data := "true"
    }

    required email: str {
      annotation description := "Verified email account"
      annotation is_personal_data := "true"
    }
  }
}

We can generated the following interface:

/**
 * ## User
 *
 * An authenticated account
 */
interface User {
  /**
   * Full name of user
   *
   * | Annotation | Value |
   * |---|---|
   * | is_personal_data | true |
   */
  name: string;

  /**
   * Verified email account
   *
   * | Annotation | Value |
   * |---|---|
   * | is_personal_data | true |
   */
  email: string;
}

Which generates, for instance in TypeScript Playground, the following UI on hover:

Hovering the User type: Image

Hovering the name property on a User:

Image

scotttrinh avatar Jul 21 '23 20:07 scotttrinh

Very nice idea. I'm mostly interested in the queries generated by npx @edgedb/generate queries

This is the generated code now.

export type GetUserByEmailReturns = {
  "id": string;
  "owner": boolean;
  "password": string | null;
  "first_name": string;
  "last_name": string;
} | null;

export async function getUserByEmail(client: Executor, args: GetUserByEmailArgs): Promise<GetUserByEmailReturns> {
  return client.querySingle(`\
SELECT User { id, owner, password, first_name, last_name } 
FILTER 
	NOT EXISTS .deleted_at AND
	.email = <str>$email`, args);

}

It would be cool to have the type be User with its annotations, and use typescript's pick for the queries. It's much more explanatory than { id: string, password?: string}

As a byproduct, I'd love to have a schema.ts file which holds the typescript representation of the schema. It's very useful for usage in the client and the server.

And the queries.ts file would import the schema types from schema.ts in order to construct the queries types with typescript utilities (pick, omit ...)

If we are to implement this feature, It would make more sense to split it to three parts.

  1. Generate a schema.ts file from the edgedb schema.
  2. Extract annotations into typescript comments
  3. Use types from schema.ts in the queries generated by @edgedb/generate

haikyuu avatar Jul 22 '23 19:07 haikyuu