Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Programmatic JS API #124

Open
JulianCataldo opened this issue Jun 17, 2024 · 2 comments
Open

Programmatic JS API #124

JulianCataldo opened this issue Jun 17, 2024 · 2 comments
Labels
enhancement New feature or request

Comments

@JulianCataldo
Copy link

Hello!

Calling sqlx-ts from a Node script could be very handy, so we can integrate it in broader codegen workflow.
It could just take an input string and output a string, so we (users) could handle watching and writing files ourselves.

I'm not sure if it's feasible due to the JS/Rust bindings stuff, etc.

What do you think?

Thank you

@JasonShin
Copy link
Owner

Hello, this is interesting. Could you explain a bit more about the codegen use case (and being able to call native sqlx-ts from Node?)? I've been using sqlx-ts CLI primarily for local DX and CI/CD integration.

If watching for file changes is needed, I recommend calling sqlx-ts binary using nodemon (or anything that you prefer).

@JulianCataldo
Copy link
Author

Hey!

This is the script I'm using right now, the goal is to have a live feedback loop during dev.

import { exec as _exec } from 'node:child_process';
import { mkdir, readFile, writeFile } from 'node:fs/promises';
import { dirname, join, normalize } from 'node:path';
import { promisify } from 'node:util';

import { watch } from 'chokidar';

const exec = promisify(_exec);

const TMP = './.tmp';

await mkdir(TMP).catch(() => null);

watch(['./src/database/*/**/*.ts', '!**/*.queries.ts']).on(
  'all',
  async (event, file) => {
    const dest = join(TMP, file);
    await mkdir(dirname(dest), { recursive: true });
    const fileContent = await readFile(file, 'utf8');

    // NOTE: We need to remove template expression (`${foo}`).
    // They're not supported by `sqlx-ts`
    const fileWithoutTemplateExpressions = fileContent.replaceAll(
      /\${(.*?)}/g,
      '?',
    );

    await writeFile(dest, fileWithoutTemplateExpressions);

    const resultSqlTs = await exec(
      `pnpm sqlx-ts '${TMP}' --config .sqlxrc.json`,
    );
    console.log(resultSqlTs);
    const resultPrettier = await exec(`pnpm prettier --write ${TMP}/**/*.ts`);
    console.log(resultPrettier);

    const sourceQueries = dest.replace(/\.ts$/, '.queries.ts');
    const destQueries = sourceQueries.replace(normalize(TMP), '.');
    console.log({ sourceQueries, destQueries });

    const queriesContent = await readFile(sourceQueries, 'utf8');
    await writeFile(
      destQueries,
      `/* /!\\ AUTO-GENERATED /!\\ */\n\n${queriesContent}`,
    );
  },
);

(Unrelated but the Prettier part can be handled with a JS API, too, I was just too lazy to set it up, and it's just the finishing touch).

I'm doing several stuff here, and if I want to alter the input/output, I have to use the filesystem as a medium, which is sub-optimal.

With a JS API, I could just call something like (skipping the bike-shedding):

import { generateTypesForFile } from 'sqlx-ts';

// ...

const { result, errors } = await generateTypesForFile({ input: '...a string from the TS/whatever file…' });

// Do something with the string result
// ...

I hope this use case is more clear for you :)

Thank you

@JasonShin JasonShin added the enhancement New feature or request label Jun 19, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants