sql-formatter
sql-formatter copied to clipboard
Feature Request: user defined formatter
Describe the Feature I want to be able to define my own language which is a slight modification of an existing language. Something like this
import { format, Formatter, TrinoFormatter, register } from 'sql-formatter'
class MyFormatter extends Formatter {
/* copy pasted code from TrinoFormatter */
}
// or
class MyFormatter extends TrinoFormatter {
cfg.quotes.push({quote: "{{}}"})
}
const result = format('select {{blah}}\n\n\n from mytable', { formatter: MyFormatter })
// or
register('my-trino-dialect', MyFormatter)
const result = format('select {{blah}}\n\n\n from mytable', { language: 'my-trino-dialect' })
Why do you want this feature? We have a preprocessor/templating engine that puts stuff in our Trino queries, so for example the user writes
select {{col_name}} from mytable
and then we can have a web ui with a drop down for that value. We need to format this Trino+"{{}}}" dialect because it's what users write and format but it makes no sense to add this as its own language to sql-formatter. Currently, I have to fork this repo to do this.
This has been asked before: #132
There are two reasons for not adding such a feature:
- Currently the formatter is going through some major architectural changes. Exposing any of the current internal API would be unwise at this point, as it's all subject to change.
- Integrating with a templating language is pretty much an unsolvable problem. This quotes hack probably works in many common cases, but there are bound to be cases where it'll be impossible for the formatter to correctly format it. So it's not really a good use-case for this feature.
That said, I actually like your proposal. I also sympathize with the pain of forking a project just for extending it a little. I'd be willing to add such a feature with the following caveats:
- The API would be classified as experimental, with little to no documentation.
- The API can and will break between any release (major, minor or patch).
oops, #132 is my co-worker lol
Regarding the proposed API for this. I think it would be best to use the existing language option, like so:
import { format, Formatter } from 'sql-formatter'
class CustomFormatter extends Formatter {
/* custom implementation */
}
format('select * from mytable', { language: CustomFormatter });
This way the API surface for this would be minimal and there won't be any possibility for conflict (e.g. like when using { language: "sqlite", formatter: MyFormatter}).
This is now released in 9.2.0.
@nene is it possible to define a custom quote type? As I mentioned, I'd like to add
// Handlebars expressions
// https://handlebarsjs.com/guide/expressions.html#basic-usage
'{{}}': String.raw`(?:\{\{[^\}]*\}\})`,
then use it like
{ quote: '{{}}', prefixes: [] },
Seems like I still need to fork the repo to add a custom quote?
PS could you please make prefixes an optional argument? My custom string type doesn't have any prefixes
Not sure. Will have to think about it. Please open a new issue for that - otherwise I'll likely completely forget about it.
Regarding prefixes. If you don't need it, you can just write the value of quote field instead of the full object:
stringTypes: [ '""-qq' ]