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

Export `NodeClickHouseClient` as value from `client-node` for verbatimModuleSyntax=true environments

Open matbour opened this issue 7 months ago • 0 comments

Use case

Currently, NodeClickHouseClient is exported as a type in the client-node package.

https://github.com/ClickHouse/clickhouse-js/blob/a332672bfb70d54dfd27ae1f8f5169a6ffeea780/packages/client-node/src/index.ts#L1-L4

While I understand that it is an architecture decision so developers are forced to use the createClient function, it is problematic for dependency injection frameworks such as Nest.js or tsyringe.

In Nest.js, the following code does not work with tsconfig verbatimModuleSyntax=true:

import { createClient } from '@clickhouse/client';
import { NodeClickHouseClient } from '@clickhouse/client';
// ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ
// 'ClickHouseClient' resolves to a type-only declaration and must be imported using a type-only import when 'verbatimModuleSyntax' is enabled


@Module({
  providers: [
    {
      provide: NodeClickHouseClient,
      useFactory: () => {
        return createClient({
          url: process.env.CLICKHOUSE_URL,
          clickhouse_settings: {
            async_insert: 1,
            wait_for_async_insert: 1,
          },
        });
      },
    },
  ],
  exports: [NodeClickHouseClient],
})
export default class ClickHouseModule {}

Describe the solution you'd like

I would like to export the ClickhouseClient as a value instead of type:

-export type {
-  NodeClickHouseClient as ClickHouseClient,
-  QueryResult,
+export {
+  NodeClickHouseClient as ClickHouseClient,
+  type QueryResult,
} from './client'

Describe the alternatives you've considered

My current workaround is to import { NodeClickHouseClient } from '@clickhouse/client/dist/client.js', which is far from ideal.

import { createClient } from '@clickhouse/client';
import { NodeClickHouseClient } from '@clickhouse/client/dist/index.js';

@Module({
  providers: [
    {
      provide: NodeClickHouseClient,
      useFactory: () => {
        return createClient({
          url: process.env.CLICKHOUSE_URL,
          clickhouse_settings: {
            async_insert: 1,
            wait_for_async_insert: 1,
          },
        });
      },
    },
  ],
  exports: [NodeClickHouseClient],
})
export default class ClickHouseModule {}

Additional context

Happy to submit a PR that goes into this direction if approved.

matbour avatar Jul 29 '24 12:07 matbour