@hypequery/cli 1.17.0 → 1.18.0
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":"generate-types.d.ts","sourceRoot":"","sources":["../../src/typegen/generate-types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAMH;;;GAGG;AACH,MAAM,WAAW,8BAA8B;IAC7C,KAAK,CAAC,OAAO,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,aAAa,CAAA;KAAE,GAAG,OAAO,CAAC;QAChE,IAAI,IAAI,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC;KAChD,CAAC,CAAC;CACJ;AAED,MAAM,WAAW,oBAAoB;IACnC,6EAA6E;IAC7E,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,wDAAwD;IACxD,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,qCAAqC;IACrC,MAAM,EAAE,8BAA8B,CAAC;IACvC,2DAA2D;IAC3D,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,yDAAyD;IACzD,mBAAmB,CAAC,EAAE,OAAO,CAAC;CAC/B;
|
|
1
|
+
{"version":3,"file":"generate-types.d.ts","sourceRoot":"","sources":["../../src/typegen/generate-types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAMH;;;GAGG;AACH,MAAM,WAAW,8BAA8B;IAC7C,KAAK,CAAC,OAAO,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,aAAa,CAAA;KAAE,GAAG,OAAO,CAAC;QAChE,IAAI,IAAI,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC;KAChD,CAAC,CAAC;CACJ;AAED,MAAM,WAAW,oBAAoB;IACnC,6EAA6E;IAC7E,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,wDAAwD;IACxD,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,qCAAqC;IACrC,MAAM,EAAE,8BAA8B,CAAC;IACvC,2DAA2D;IAC3D,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,yDAAyD;IACzD,mBAAmB,CAAC,EAAE,OAAO,CAAC;CAC/B;AA0HD;;GAEG;AACH,wBAAsB,uBAAuB,CAC3C,MAAM,EAAE,8BAA8B,EACtC,OAAO,GAAE,IAAI,CAAC,oBAAoB,EAAE,QAAQ,CAAM,GACjD,OAAO,CAAC,MAAM,CAAC,CAGjB;AAED;;;;GAIG;AACH,wBAAsB,aAAa,CACjC,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,oBAAoB,GAC5B,OAAO,CAAC,MAAM,EAAE,CAAC,CAYnB"}
|
|
@@ -61,8 +61,7 @@ export interface IntrospectedSchema {`;
|
|
|
61
61
|
const columns = await describeTable(client, table.name);
|
|
62
62
|
typeDefinitions += `\n ${table.name}: {`;
|
|
63
63
|
for (const column of columns) {
|
|
64
|
-
|
|
65
|
-
typeDefinitions += `\n '${column.name}': '${clickHouseType}';`;
|
|
64
|
+
typeDefinitions += `\n '${column.name}': ${JSON.stringify(column.type)};`;
|
|
66
65
|
}
|
|
67
66
|
typeDefinitions += '\n };';
|
|
68
67
|
}
|
|
@@ -73,7 +72,7 @@ export interface IntrospectedSchema {`;
|
|
|
73
72
|
const columns = await describeTable(client, table.name);
|
|
74
73
|
typeDefinitions += `export interface ${capitalizeFirstLetter(table.name)}Record {`;
|
|
75
74
|
for (const column of columns) {
|
|
76
|
-
const tsType = clickhouseToTsType(column.type)
|
|
75
|
+
const tsType = clickhouseToTsType(column.type);
|
|
77
76
|
typeDefinitions += `\n '${column.name}': ${tsType};`;
|
|
78
77
|
}
|
|
79
78
|
typeDefinitions += '\n}\n\n';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"type-parsing.d.ts","sourceRoot":"","sources":["../../src/typegen/type-parsing.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"type-parsing.d.ts","sourceRoot":"","sources":["../../src/typegen/type-parsing.ts"],"names":[],"mappings":"AAwLA;;;GAGG;AACH,eAAO,MAAM,kBAAkB,GAAI,MAAM,MAAM,KAAG,MA6CjD,CAAC"}
|
|
@@ -2,7 +2,27 @@ function splitTopLevelArgs(value) {
|
|
|
2
2
|
const parts = [];
|
|
3
3
|
let current = '';
|
|
4
4
|
let depth = 0;
|
|
5
|
+
let quote = null;
|
|
6
|
+
let escaped = false;
|
|
5
7
|
for (const char of value) {
|
|
8
|
+
if (quote) {
|
|
9
|
+
current += char;
|
|
10
|
+
if (escaped) {
|
|
11
|
+
escaped = false;
|
|
12
|
+
}
|
|
13
|
+
else if (char === '\\') {
|
|
14
|
+
escaped = true;
|
|
15
|
+
}
|
|
16
|
+
else if (char === quote) {
|
|
17
|
+
quote = null;
|
|
18
|
+
}
|
|
19
|
+
continue;
|
|
20
|
+
}
|
|
21
|
+
if (char === "'" || char === '"' || char === '`') {
|
|
22
|
+
quote = char;
|
|
23
|
+
current += char;
|
|
24
|
+
continue;
|
|
25
|
+
}
|
|
6
26
|
if (char === '(') {
|
|
7
27
|
depth += 1;
|
|
8
28
|
current += char;
|
|
@@ -25,6 +45,50 @@ function splitTopLevelArgs(value) {
|
|
|
25
45
|
}
|
|
26
46
|
return parts;
|
|
27
47
|
}
|
|
48
|
+
function decodeClickHouseEscape(char) {
|
|
49
|
+
switch (char) {
|
|
50
|
+
case 'b': return '\b';
|
|
51
|
+
case 'f': return '\f';
|
|
52
|
+
case 'n': return '\n';
|
|
53
|
+
case 'r': return '\r';
|
|
54
|
+
case 't': return '\t';
|
|
55
|
+
case '0': return '\0';
|
|
56
|
+
default: return char;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
function parseBacktickTuplePart(part) {
|
|
60
|
+
let name = '';
|
|
61
|
+
let escaped = false;
|
|
62
|
+
for (let index = 1; index < part.length; index += 1) {
|
|
63
|
+
const char = part[index];
|
|
64
|
+
if (escaped) {
|
|
65
|
+
name += decodeClickHouseEscape(char);
|
|
66
|
+
escaped = false;
|
|
67
|
+
continue;
|
|
68
|
+
}
|
|
69
|
+
if (char === '\\') {
|
|
70
|
+
escaped = true;
|
|
71
|
+
continue;
|
|
72
|
+
}
|
|
73
|
+
if (char === '`') {
|
|
74
|
+
const type = part.slice(index + 1);
|
|
75
|
+
return /^\s+\S/s.test(type) ? { name, type: type.trim() } : null;
|
|
76
|
+
}
|
|
77
|
+
name += char;
|
|
78
|
+
}
|
|
79
|
+
return null;
|
|
80
|
+
}
|
|
81
|
+
function parseNamedTuplePart(value) {
|
|
82
|
+
const part = value.trim();
|
|
83
|
+
if (part.startsWith('`')) {
|
|
84
|
+
return parseBacktickTuplePart(part);
|
|
85
|
+
}
|
|
86
|
+
const match = /^([A-Za-z_][A-Za-z0-9_]*)\s+(.+)$/s.exec(part);
|
|
87
|
+
return match ? { name: match[1], type: match[2].trim() } : null;
|
|
88
|
+
}
|
|
89
|
+
function formatTypeScriptProperty(name) {
|
|
90
|
+
return /^[A-Za-z_$][A-Za-z0-9_$]*$/.test(name) ? name : JSON.stringify(name);
|
|
91
|
+
}
|
|
28
92
|
function unwrapType(type, wrapperName) {
|
|
29
93
|
// Trim whitespace and handle case-insensitive matching
|
|
30
94
|
const trimmedType = type.trim();
|
|
@@ -104,24 +168,31 @@ function getPrimitiveTsType(type) {
|
|
|
104
168
|
* equivalent TypeScript type string.
|
|
105
169
|
*/
|
|
106
170
|
export const clickhouseToTsType = (type) => {
|
|
107
|
-
const
|
|
171
|
+
const normalizedType = type.trim();
|
|
172
|
+
const wrappedArrayType = unwrapType(normalizedType, 'Array');
|
|
108
173
|
if (wrappedArrayType) {
|
|
109
174
|
return `Array<${clickhouseToTsType(wrappedArrayType)}>`;
|
|
110
175
|
}
|
|
111
|
-
const wrappedNullableType = unwrapType(
|
|
176
|
+
const wrappedNullableType = unwrapType(normalizedType, 'Nullable');
|
|
112
177
|
if (wrappedNullableType) {
|
|
113
178
|
return `${clickhouseToTsType(wrappedNullableType)} | null`;
|
|
114
179
|
}
|
|
115
|
-
const wrappedLowCardinalityType = unwrapType(
|
|
180
|
+
const wrappedLowCardinalityType = unwrapType(normalizedType, 'LowCardinality');
|
|
116
181
|
if (wrappedLowCardinalityType) {
|
|
117
182
|
return clickhouseToTsType(wrappedLowCardinalityType);
|
|
118
183
|
}
|
|
119
|
-
const wrappedTupleType = unwrapType(
|
|
184
|
+
const wrappedTupleType = unwrapType(normalizedType, 'Tuple');
|
|
120
185
|
if (wrappedTupleType) {
|
|
121
186
|
const tupleParts = splitTopLevelArgs(wrappedTupleType);
|
|
187
|
+
const namedParts = tupleParts.map(parseNamedTuplePart);
|
|
188
|
+
if (namedParts.length > 0 && namedParts.every((part) => part !== null)) {
|
|
189
|
+
return `{ ${namedParts
|
|
190
|
+
.map((part) => `${formatTypeScriptProperty(part.name)}: ${clickhouseToTsType(part.type)}`)
|
|
191
|
+
.join('; ')} }`;
|
|
192
|
+
}
|
|
122
193
|
return `[${tupleParts.map((part) => clickhouseToTsType(part)).join(', ')}]`;
|
|
123
194
|
}
|
|
124
|
-
const wrappedMapType = unwrapType(
|
|
195
|
+
const wrappedMapType = unwrapType(normalizedType, 'Map');
|
|
125
196
|
if (wrappedMapType) {
|
|
126
197
|
const mapParts = splitTopLevelArgs(wrappedMapType);
|
|
127
198
|
if (mapParts.length === 2) {
|
|
@@ -131,7 +202,7 @@ export const clickhouseToTsType = (type) => {
|
|
|
131
202
|
}
|
|
132
203
|
return 'Record<string, unknown>';
|
|
133
204
|
}
|
|
134
|
-
const primitiveType = getPrimitiveTsType(
|
|
205
|
+
const primitiveType = getPrimitiveTsType(normalizedType);
|
|
135
206
|
if (primitiveType)
|
|
136
207
|
return primitiveType;
|
|
137
208
|
// Unsupported or more complex ClickHouse types currently preserve the historical fallback.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hypequery/cli",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.18.0",
|
|
4
4
|
"description": "CLI for scaffolding type-safe ClickHouse analytics, semantic datasets, React manifests, and deployments",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"clickhouse",
|
|
@@ -30,8 +30,8 @@
|
|
|
30
30
|
"open": "^10.0.0",
|
|
31
31
|
"ora": "^8.0.1",
|
|
32
32
|
"prompts": "^2.4.2",
|
|
33
|
-
"@hypequery/
|
|
34
|
-
"@hypequery/
|
|
33
|
+
"@hypequery/deployment": "0.7.3",
|
|
34
|
+
"@hypequery/protocol": "0.11.0"
|
|
35
35
|
},
|
|
36
36
|
"optionalDependencies": {
|
|
37
37
|
"@napi-rs/keyring": "1.3.0"
|