@risingwave/wavelet-cli 0.1.3 → 0.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"codegen.d.ts","sourceRoot":"","sources":["../src/codegen.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAwB,MAAM,qBAAqB,CAAA;AAI9E,wBAAsB,cAAc,CAAC,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CA0CzE"}
1
+ {"version":3,"file":"codegen.d.ts","sourceRoot":"","sources":["../src/codegen.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAoC,MAAM,qBAAqB,CAAA;AAI1F,wBAAsB,cAAc,CAAC,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CA6DzE"}
package/dist/codegen.js CHANGED
@@ -8,24 +8,7 @@ const node_fs_1 = require("node:fs");
8
8
  const pg_1 = __importDefault(require("pg"));
9
9
  const { Client } = pg_1.default;
10
10
  async function generateClient(config) {
11
- const client = new Client({ connectionString: config.database });
12
- await client.connect();
13
- const viewTypes = [];
14
- for (const viewName of Object.keys(config.views ?? {})) {
15
- try {
16
- // Query column info from RisingWave
17
- const result = await client.query(`SELECT column_name, data_type FROM information_schema.columns WHERE table_name = $1 ORDER BY ordinal_position`, [viewName]);
18
- const columns = result.rows.map((row) => ({
19
- name: row.column_name,
20
- tsType: pgTypeToTs(row.data_type),
21
- }));
22
- viewTypes.push({ name: viewName, columns });
23
- }
24
- catch {
25
- // If we can't query schema, generate generic types
26
- viewTypes.push({ name: viewName, columns: [] });
27
- }
28
- }
11
+ // Stream types are always known from config
29
12
  const streamTypes = [];
30
13
  for (const [streamName, streamDef] of Object.entries(config.streams ?? {})) {
31
14
  const columns = Object.entries(streamDef.columns).map(([name, type]) => ({
@@ -34,11 +17,71 @@ async function generateClient(config) {
34
17
  }));
35
18
  streamTypes.push({ name: streamName, columns });
36
19
  }
37
- await client.end();
20
+ // View types: try config-declared columns first, then RisingWave introspection, then generic
21
+ const viewTypes = [];
22
+ let dbClient = null;
23
+ for (const [viewName, viewDef] of Object.entries(config.views ?? {})) {
24
+ // Tier 1: explicit columns in config
25
+ const declaredColumns = getViewColumns(viewDef);
26
+ if (declaredColumns) {
27
+ viewTypes.push({ name: viewName, columns: declaredColumns });
28
+ continue;
29
+ }
30
+ // Tier 2: introspect from RisingWave (if reachable)
31
+ if (!dbClient) {
32
+ dbClient = await tryConnect(config.database);
33
+ }
34
+ if (dbClient) {
35
+ try {
36
+ const result = await dbClient.query(`SELECT column_name, data_type FROM information_schema.columns WHERE table_name = $1 ORDER BY ordinal_position`, [viewName]);
37
+ if (result.rows.length > 0) {
38
+ viewTypes.push({
39
+ name: viewName,
40
+ columns: result.rows.map((row) => ({
41
+ name: row.column_name,
42
+ tsType: pgTypeToTs(row.data_type),
43
+ })),
44
+ });
45
+ continue;
46
+ }
47
+ }
48
+ catch {
49
+ // Fall through to tier 3
50
+ }
51
+ }
52
+ // Tier 3: generic fallback
53
+ viewTypes.push({ name: viewName, columns: [] });
54
+ }
55
+ if (dbClient) {
56
+ await dbClient.end().catch(() => { });
57
+ }
38
58
  const code = generateCode(viewTypes, streamTypes);
39
59
  (0, node_fs_1.mkdirSync)('.wavelet', { recursive: true });
40
60
  (0, node_fs_1.writeFileSync)('.wavelet/client.ts', code);
41
61
  }
62
+ function getViewColumns(viewDef) {
63
+ // SqlFragment has no columns
64
+ if ('_tag' in viewDef && viewDef._tag === 'sql')
65
+ return null;
66
+ // ViewDef might have explicit columns
67
+ const vd = viewDef;
68
+ if (!vd.columns)
69
+ return null;
70
+ return Object.entries(vd.columns).map(([name, type]) => ({
71
+ name,
72
+ tsType: columnTypeToTs(type),
73
+ }));
74
+ }
75
+ async function tryConnect(connectionString) {
76
+ const client = new Client({ connectionString, connectionTimeoutMillis: 3000 });
77
+ try {
78
+ await client.connect();
79
+ return client;
80
+ }
81
+ catch {
82
+ return null;
83
+ }
84
+ }
42
85
  function generateCode(views, streams) {
43
86
  let code = `// Auto-generated by wavelet generate - do not edit\n`;
44
87
  code += `// Run 'npx wavelet generate' to regenerate\n\n`;
@@ -1 +1 @@
1
- {"version":3,"file":"codegen.js","sourceRoot":"","sources":["../src/codegen.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"codegen.js","sourceRoot":"","sources":["../src/codegen.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@risingwave/wavelet-cli",
3
- "version": "0.1.3",
3
+ "version": "0.1.4",
4
4
  "description": "Wavelet CLI - manage views, generate types, run dev server",
5
5
  "bin": {
6
6
  "wavelet": "./dist/index.js"
@@ -10,8 +10,8 @@
10
10
  "dev": "tsx src/index.ts"
11
11
  },
12
12
  "dependencies": {
13
- "@risingwave/wavelet": "0.1.3",
14
- "@risingwave/wavelet-server": "0.1.3",
13
+ "@risingwave/wavelet": "0.1.4",
14
+ "@risingwave/wavelet-server": "0.1.4",
15
15
  "pg": "^8.13.0",
16
16
  "tsx": "^4.0.0"
17
17
  },
package/src/codegen.ts CHANGED
@@ -1,37 +1,12 @@
1
1
  import { writeFileSync, mkdirSync } from 'node:fs'
2
2
  import pg from 'pg'
3
- import type { WaveletConfig, SqlFragment, ViewDef } from '@risingwave/wavelet'
3
+ import type { WaveletConfig, SqlFragment, ViewDef, ColumnType } from '@risingwave/wavelet'
4
4
 
5
5
  const { Client } = pg
6
6
 
7
7
  export async function generateClient(config: WaveletConfig): Promise<void> {
8
- const client = new Client({ connectionString: config.database })
9
- await client.connect()
10
-
11
- const viewTypes: { name: string; columns: { name: string; tsType: string }[] }[] = []
12
-
13
- for (const viewName of Object.keys(config.views ?? {})) {
14
- try {
15
- // Query column info from RisingWave
16
- const result = await client.query(
17
- `SELECT column_name, data_type FROM information_schema.columns WHERE table_name = $1 ORDER BY ordinal_position`,
18
- [viewName]
19
- )
20
-
21
- const columns = result.rows.map((row: any) => ({
22
- name: row.column_name,
23
- tsType: pgTypeToTs(row.data_type),
24
- }))
25
-
26
- viewTypes.push({ name: viewName, columns })
27
- } catch {
28
- // If we can't query schema, generate generic types
29
- viewTypes.push({ name: viewName, columns: [] })
30
- }
31
- }
32
-
33
- const streamTypes: { name: string; columns: { name: string; tsType: string }[] }[] = []
34
-
8
+ // Stream types are always known from config
9
+ const streamTypes: TypedEntity[] = []
35
10
  for (const [streamName, streamDef] of Object.entries(config.streams ?? {})) {
36
11
  const columns = Object.entries(streamDef.columns).map(([name, type]) => ({
37
12
  name,
@@ -40,7 +15,51 @@ export async function generateClient(config: WaveletConfig): Promise<void> {
40
15
  streamTypes.push({ name: streamName, columns })
41
16
  }
42
17
 
43
- await client.end()
18
+ // View types: try config-declared columns first, then RisingWave introspection, then generic
19
+ const viewTypes: TypedEntity[] = []
20
+ let dbClient: InstanceType<typeof Client> | null = null
21
+
22
+ for (const [viewName, viewDef] of Object.entries(config.views ?? {})) {
23
+ // Tier 1: explicit columns in config
24
+ const declaredColumns = getViewColumns(viewDef)
25
+ if (declaredColumns) {
26
+ viewTypes.push({ name: viewName, columns: declaredColumns })
27
+ continue
28
+ }
29
+
30
+ // Tier 2: introspect from RisingWave (if reachable)
31
+ if (!dbClient) {
32
+ dbClient = await tryConnect(config.database)
33
+ }
34
+
35
+ if (dbClient) {
36
+ try {
37
+ const result = await dbClient.query(
38
+ `SELECT column_name, data_type FROM information_schema.columns WHERE table_name = $1 ORDER BY ordinal_position`,
39
+ [viewName]
40
+ )
41
+ if (result.rows.length > 0) {
42
+ viewTypes.push({
43
+ name: viewName,
44
+ columns: result.rows.map((row: any) => ({
45
+ name: row.column_name,
46
+ tsType: pgTypeToTs(row.data_type),
47
+ })),
48
+ })
49
+ continue
50
+ }
51
+ } catch {
52
+ // Fall through to tier 3
53
+ }
54
+ }
55
+
56
+ // Tier 3: generic fallback
57
+ viewTypes.push({ name: viewName, columns: [] })
58
+ }
59
+
60
+ if (dbClient) {
61
+ await dbClient.end().catch(() => {})
62
+ }
44
63
 
45
64
  const code = generateCode(viewTypes, streamTypes)
46
65
 
@@ -48,10 +67,36 @@ export async function generateClient(config: WaveletConfig): Promise<void> {
48
67
  writeFileSync('.wavelet/client.ts', code)
49
68
  }
50
69
 
51
- function generateCode(
52
- views: { name: string; columns: { name: string; tsType: string }[] }[],
53
- streams: { name: string; columns: { name: string; tsType: string }[] }[]
54
- ): string {
70
+ interface TypedEntity {
71
+ name: string
72
+ columns: { name: string; tsType: string }[]
73
+ }
74
+
75
+ function getViewColumns(viewDef: ViewDef | SqlFragment): { name: string; tsType: string }[] | null {
76
+ // SqlFragment has no columns
77
+ if ('_tag' in viewDef && viewDef._tag === 'sql') return null
78
+
79
+ // ViewDef might have explicit columns
80
+ const vd = viewDef as ViewDef
81
+ if (!vd.columns) return null
82
+
83
+ return Object.entries(vd.columns).map(([name, type]) => ({
84
+ name,
85
+ tsType: columnTypeToTs(type),
86
+ }))
87
+ }
88
+
89
+ async function tryConnect(connectionString: string): Promise<InstanceType<typeof Client> | null> {
90
+ const client = new Client({ connectionString, connectionTimeoutMillis: 3000 })
91
+ try {
92
+ await client.connect()
93
+ return client
94
+ } catch {
95
+ return null
96
+ }
97
+ }
98
+
99
+ function generateCode(views: TypedEntity[], streams: TypedEntity[]): string {
55
100
  let code = `// Auto-generated by wavelet generate - do not edit\n`
56
101
  code += `// Run 'npx wavelet generate' to regenerate\n\n`
57
102
  code += `import { WaveletClient } from '@risingwave/wavelet-sdk'\n`