prql-js

JavaScript bindings for prql-compiler.

Installation

  1. npm install prql-js

Usage

Currently these functions are exposed

  1. function compile(prql_query: string, options?: CompileOptions): string;
  2. function prql_to_pl(prql_query: string): string;
  3. function pl_to_rq(pl_json: string): string;
  4. function rq_to_sql(rq_json: string): string;

From Node.js

Direct usage

  1. const prqljs = require("prql-js");
  2. const sql = prqljs.compile(`from employees | select first_name`);
  3. console.log(sql);

Options

  1. const opts = new prql.CompileOptions();
  2. opts.target = "sql.mssql";
  3. opts.format = false;
  4. opts.signature_comment = false;
  5. const sql = prqljs.compile(`from employees | take 10`, opts);
  6. console.log(sql);

Template literal

  1. const prqljs = require("prql-js");
  2. const prql = (string) => prqljs.compile(string[0] || "");
  3. const sql = prql`from employees | select first_name`;
  4. console.log(sql);

Template literal with newlines

  1. const prqljs = require("prql-js");
  2. const prql = (string) => prqljs.compile(string[0] || "");
  3. const sql = prql`
  4. from employees
  5. select first_name
  6. `;
  7. console.log(sql);

From a browser

  1. <html>
  2. <head>
  3. <script src="./node_modules/prql-js/dist/web/prql_js.js"></script>
  4. <script>
  5. const { compile } = wasm_bindgen;
  6. async function run() {
  7. await wasm_bindgen("./node_modules/prql-js/dist/web/prql_js_bg.wasm");
  8. const sql = compile("from employees | select first_name");
  9. console.log(sql);
  10. }
  11. run();
  12. </script>
  13. </head>
  14. <body></body>
  15. </html>

From a framework or a bundler

  1. import compile from "prql-js/dist/bundler";
  2. const sql = compile(`from employees | select first_name`);
  3. console.log(sql);

Errors

Errors are returned as following object, serialized as a JSON array:

  1. interface ErrorMessage {
  2. /// Message kind. Currently only Error is implemented.
  3. kind: "Error" | "Warning" | "Lint";
  4. /// Machine-readable identifier of the error
  5. code: string | null;
  6. /// Plain text of the error
  7. reason: string;
  8. /// A list of suggestions of how to fix the error
  9. hint: string | null;
  10. /// Character offset of error origin within a source file
  11. span: [number, number] | null;
  12. /// Annotated code, containing cause and hints.
  13. display: string | null;
  14. /// Line and column number of error origin within a source file
  15. location: SourceLocation | null;
  16. }
  17. /// Location within the source file.
  18. /// Tuples contain:
  19. /// - line number (0-based),
  20. /// - column number within that line (0-based),
  21. interface SourceLocation {
  22. start: [number, number];
  23. end: [number, number];
  24. }

These errors can be caught as such:

  1. try {
  2. const sql = prqlJs.compile(`from employees | foo first_name`);
  3. } catch (error) {
  4. const errorMessages = JSON.parse(error.message).inner;
  5. console.log(errorMessages[0].display);
  6. console.log(errorMessages[0].location);
  7. }

Development

Build:

  1. npm run build

This builds Node, bundler and web packages in the dist path.

Test:

  1. npm test

Notes

  • This uses wasm-pack to generate bindings1.
  • We’ve added an npm layer on top of the usual approach of just using wasm-pack, so we can distribute a single package with targets of node, bundler and no-modules — somewhat inverting the approach recommended by wasm-pack. The build instruction goes in a build script, rather than a pack script.

1

  1. Though we would be very open to other approaches, given wasm-pack does not
  2. seem maintained, and we're eliding many of its features to build for three
  3. targets. See <https://github.com/PRQL/prql/issues/1836> for more details.