@hypequery/cli 1.10.0 → 1.10.2
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.
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +0 -2
- package/dist/commands/dev.d.ts +0 -11
- package/dist/commands/dev.d.ts.map +1 -1
- package/dist/commands/dev.js +41 -48
- package/package.json +2 -5
package/dist/cli.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAkBpC,QAAA,MAAM,OAAO,SAAgB,CAAC;AAa9B,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;;EAKpE;
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAkBpC,QAAA,MAAM,OAAO,SAAgB,CAAC;AAa9B,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;;EAKpE;AAgLD,OAAO,EAAE,OAAO,EAAE,CAAC"}
|
package/dist/cli.js
CHANGED
|
@@ -78,8 +78,6 @@ program
|
|
|
78
78
|
.option('--cache <provider>', 'Cache provider (memory|redis)')
|
|
79
79
|
.option('--redis-url <url>', 'Redis connection URL')
|
|
80
80
|
.option('--open', 'Open browser automatically')
|
|
81
|
-
.option('--ui-experimental', 'Serve the experimental query UI at /__dev (unstable, not for production use)')
|
|
82
|
-
.option('--no-telemetry', 'Disable anonymous playground usage telemetry')
|
|
83
81
|
.option('--cors', 'Enable CORS')
|
|
84
82
|
.option('--path <path>', 'Analytics directory (loads <path>/api.ts or <path>/queries.ts)')
|
|
85
83
|
.option('-q, --quiet', 'Suppress startup messages')
|
package/dist/commands/dev.d.ts
CHANGED
|
@@ -8,17 +8,6 @@ export interface DevOptions {
|
|
|
8
8
|
open?: boolean;
|
|
9
9
|
cors?: boolean;
|
|
10
10
|
path?: string;
|
|
11
|
-
/**
|
|
12
|
-
* Opt into the experimental query UI/gateway at /__dev. Off by default —
|
|
13
|
-
* the UI is not release-ready; behaviour and flag may change or go away.
|
|
14
|
-
*/
|
|
15
|
-
uiExperimental?: boolean;
|
|
16
|
-
/**
|
|
17
|
-
* Anonymous playground usage telemetry. Commander sets this to `false` when
|
|
18
|
-
* `--no-telemetry` is passed; otherwise it is undefined (telemetry follows
|
|
19
|
-
* its usual endpoint/env gating).
|
|
20
|
-
*/
|
|
21
|
-
telemetry?: boolean;
|
|
22
11
|
}
|
|
23
12
|
export declare function devCommand(file?: string, options?: DevOptions): Promise<void>;
|
|
24
13
|
//# sourceMappingURL=dev.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dev.d.ts","sourceRoot":"","sources":["../../src/commands/dev.ts"],"names":[],"mappings":"AA8BA,MAAM,WAAW,UAAU;IACzB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"dev.d.ts","sourceRoot":"","sources":["../../src/commands/dev.ts"],"names":[],"mappings":"AA8BA,MAAM,WAAW,UAAU;IACzB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,wBAAsB,UAAU,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,OAAO,GAAE,UAAe,iBAiOvE"}
|
package/dist/commands/dev.js
CHANGED
|
@@ -26,30 +26,6 @@ function displayQueriesFileNotFoundError(commandName) {
|
|
|
26
26
|
logger.indent(`hypequery ${commandName} ./path/to/api.ts`);
|
|
27
27
|
logger.newline();
|
|
28
28
|
}
|
|
29
|
-
/**
|
|
30
|
-
* Attempt to create the local gateway from @hypequery/gateway. The package is an
|
|
31
|
-
* optional dependency, so it may be absent; in that case we return null (with a
|
|
32
|
-
* hint) and `hypequery dev` still runs as a plain server.
|
|
33
|
-
*/
|
|
34
|
-
async function createGatewayIfAvailable(api, telemetryDisabled) {
|
|
35
|
-
try {
|
|
36
|
-
const { createGateway } = await import('@hypequery/gateway');
|
|
37
|
-
return (await createGateway(api, {
|
|
38
|
-
projectName: path.basename(process.cwd()),
|
|
39
|
-
devToken: process.env.HYPEQUERY_DEV_TOKEN,
|
|
40
|
-
telemetryDisabled,
|
|
41
|
-
}));
|
|
42
|
-
}
|
|
43
|
-
catch (error) {
|
|
44
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
45
|
-
if (message.includes('Cannot find') || message.includes('ERR_MODULE_NOT_FOUND')) {
|
|
46
|
-
logger.warn('Playground UI not installed. Install @hypequery/gateway to enable it.');
|
|
47
|
-
return null;
|
|
48
|
-
}
|
|
49
|
-
logger.warn(`Playground failed to start: ${message}`);
|
|
50
|
-
return null;
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
29
|
export async function devCommand(file, options = {}) {
|
|
54
30
|
// Step 1: Find queries file
|
|
55
31
|
const queriesFile = file
|
|
@@ -64,8 +40,23 @@ export async function devCommand(file, options = {}) {
|
|
|
64
40
|
logger.info(`Found: ${path.relative(process.cwd(), queriesFile)}`);
|
|
65
41
|
logger.newline();
|
|
66
42
|
let currentServer = null;
|
|
67
|
-
let
|
|
43
|
+
let lifecycleOperation = Promise.resolve();
|
|
44
|
+
let shutdownRequested = false;
|
|
68
45
|
const shouldWatch = options.watch !== false; // Default to true
|
|
46
|
+
const queueLifecycleOperation = (operation) => {
|
|
47
|
+
const queued = lifecycleOperation.then(operation, operation);
|
|
48
|
+
lifecycleOperation = queued.catch(() => undefined);
|
|
49
|
+
return queued;
|
|
50
|
+
};
|
|
51
|
+
const stopCurrentRuntime = async () => {
|
|
52
|
+
const server = currentServer;
|
|
53
|
+
// Clear the reference before awaiting teardown so a second signal or
|
|
54
|
+
// restart cannot stop the same server twice.
|
|
55
|
+
currentServer = null;
|
|
56
|
+
if (server) {
|
|
57
|
+
await server.stop();
|
|
58
|
+
}
|
|
59
|
+
};
|
|
69
60
|
const startServer = async () => {
|
|
70
61
|
// Loading spinners for slow operations
|
|
71
62
|
const compileSpinner = ora('Compiling queries...').start();
|
|
@@ -92,19 +83,12 @@ export async function devCommand(file, options = {}) {
|
|
|
92
83
|
logger.header('hypequery dev');
|
|
93
84
|
logger.success(`Registered ${queryCount} ${queryCount === 1 ? 'query' : 'queries'}`);
|
|
94
85
|
logger.newline();
|
|
95
|
-
// The query UI is experimental and strictly opt-in; the default dev
|
|
96
|
-
// server is unchanged.
|
|
97
|
-
const gateway = options.uiExperimental
|
|
98
|
-
? await createGatewayIfAvailable(api, options.telemetry === false)
|
|
99
|
-
: null;
|
|
100
|
-
currentGateway = gateway;
|
|
101
86
|
// Start the server
|
|
102
87
|
const { serveDev } = await import('@hypequery/serve/dev');
|
|
103
88
|
currentServer = await serveDev(api, {
|
|
104
89
|
port: options.port,
|
|
105
90
|
hostname: options.hostname,
|
|
106
91
|
quiet: true,
|
|
107
|
-
mount: gateway?.mount,
|
|
108
92
|
});
|
|
109
93
|
const address = currentServer.server.address();
|
|
110
94
|
const port = typeof address === 'object' && address ? address.port : options.port || 4000;
|
|
@@ -116,9 +100,6 @@ export async function devCommand(file, options = {}) {
|
|
|
116
100
|
`Docs: ${baseUrl}${api.basePath ?? ''}${docsPath}`,
|
|
117
101
|
`OpenAPI: ${baseUrl}${api.basePath ?? ''}${openapiPath}`,
|
|
118
102
|
];
|
|
119
|
-
if (gateway?.uiAvailable) {
|
|
120
|
-
boxLines.unshift(`Playground: ${baseUrl}/__dev`);
|
|
121
|
-
}
|
|
122
103
|
logger.box(boxLines);
|
|
123
104
|
logger.newline();
|
|
124
105
|
logger.success(`Ready in ${process.uptime().toFixed(0)}ms`);
|
|
@@ -146,6 +127,15 @@ export async function devCommand(file, options = {}) {
|
|
|
146
127
|
}
|
|
147
128
|
}
|
|
148
129
|
catch (error) {
|
|
130
|
+
// If server startup or later setup fails, tear down any resources
|
|
131
|
+
// acquired by this attempt before retrying or exiting.
|
|
132
|
+
try {
|
|
133
|
+
await stopCurrentRuntime();
|
|
134
|
+
}
|
|
135
|
+
catch (teardownError) {
|
|
136
|
+
const message = teardownError instanceof Error ? teardownError.message : String(teardownError);
|
|
137
|
+
logger.warn(`Failed to clean up dev server resources: ${message}`);
|
|
138
|
+
}
|
|
149
139
|
// Stop spinners if they're still running
|
|
150
140
|
if (compileSpinner.isSpinning) {
|
|
151
141
|
compileSpinner.fail('Failed to compile queries');
|
|
@@ -172,26 +162,29 @@ export async function devCommand(file, options = {}) {
|
|
|
172
162
|
}
|
|
173
163
|
}
|
|
174
164
|
};
|
|
175
|
-
const restartServer = async () => {
|
|
165
|
+
const restartServer = () => queueLifecycleOperation(async () => {
|
|
166
|
+
if (shutdownRequested)
|
|
167
|
+
return;
|
|
176
168
|
if (currentServer) {
|
|
177
169
|
logger.newline();
|
|
178
170
|
logger.reload('File changed, restarting...');
|
|
179
171
|
logger.newline();
|
|
180
|
-
|
|
181
|
-
await currentGateway.shutdown();
|
|
182
|
-
await currentServer.stop();
|
|
172
|
+
await stopCurrentRuntime();
|
|
183
173
|
}
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
174
|
+
if (!shutdownRequested) {
|
|
175
|
+
await startServer();
|
|
176
|
+
}
|
|
177
|
+
});
|
|
178
|
+
const shutdown = () => {
|
|
179
|
+
if (shutdownRequested)
|
|
180
|
+
return lifecycleOperation;
|
|
181
|
+
shutdownRequested = true;
|
|
187
182
|
logger.newline();
|
|
188
183
|
logger.info('Shutting down dev server...');
|
|
189
|
-
|
|
190
|
-
await
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
}
|
|
194
|
-
process.exit(0);
|
|
184
|
+
return queueLifecycleOperation(async () => {
|
|
185
|
+
await stopCurrentRuntime();
|
|
186
|
+
process.exit(0);
|
|
187
|
+
});
|
|
195
188
|
};
|
|
196
189
|
// Start initial server
|
|
197
190
|
await startServer();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hypequery/cli",
|
|
3
|
-
"version": "1.10.
|
|
3
|
+
"version": "1.10.2",
|
|
4
4
|
"description": "Command-line interface for hypequery",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"type": "module",
|
|
@@ -22,9 +22,6 @@
|
|
|
22
22
|
"@hypequery/deployment": "0.5.1",
|
|
23
23
|
"@hypequery/protocol": "0.9.0"
|
|
24
24
|
},
|
|
25
|
-
"optionalDependencies": {
|
|
26
|
-
"@hypequery/gateway": "0.2.0"
|
|
27
|
-
},
|
|
28
25
|
"peerDependencies": {
|
|
29
26
|
"@hypequery/clickhouse": "*",
|
|
30
27
|
"@hypequery/serve": "*"
|
|
@@ -40,7 +37,7 @@
|
|
|
40
37
|
"@vitest/coverage-v8": "^3.2.6",
|
|
41
38
|
"typescript": "^5.7.3",
|
|
42
39
|
"vitest": "^3.2.6",
|
|
43
|
-
"@hypequery/clickhouse": "2.5.
|
|
40
|
+
"@hypequery/clickhouse": "2.5.2",
|
|
44
41
|
"@hypequery/serve": "0.14.0"
|
|
45
42
|
},
|
|
46
43
|
"repository": {
|