owox 0.0.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.
- package/README.md +132 -0
- package/bin/dev.cmd +3 -0
- package/bin/dev.js +5 -0
- package/bin/run.cmd +3 -0
- package/bin/run.js +5 -0
- package/dist/commands/serve.d.ts +91 -0
- package/dist/commands/serve.js +265 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/oclif.manifest.json +42 -0
- package/package.json +80 -0
package/README.md
ADDED
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
# OWOX Data Marts CLI
|
|
2
|
+
|
|
3
|
+
A command-line interface for running OWOX Data Marts application. This CLI provides a simple way to start the pre-built OWOX Data Marts server with frontend and backend components.
|
|
4
|
+
|
|
5
|
+
[](https://oclif.io)
|
|
6
|
+
[](https://npmjs.org/package/owox)
|
|
7
|
+
[](https://npmjs.org/package/owox)
|
|
8
|
+
|
|
9
|
+
<!-- toc -->
|
|
10
|
+
|
|
11
|
+
- [Usage](#usage)
|
|
12
|
+
- [Local Development: npm link](#local-development-npm-link)
|
|
13
|
+
- [Commands](#commands)
|
|
14
|
+
- [FAQ: Understanding the `bin` Folder](#faq-understanding-the-bin-folder)
|
|
15
|
+
<!-- tocstop -->
|
|
16
|
+
|
|
17
|
+
# Usage
|
|
18
|
+
|
|
19
|
+
<!-- usage -->
|
|
20
|
+
|
|
21
|
+
```sh-session
|
|
22
|
+
$ npm install -g owox
|
|
23
|
+
$ owox serve
|
|
24
|
+
Starting OWOX Data Marts...
|
|
25
|
+
Starting in production mode...
|
|
26
|
+
Starting server on port 3000...
|
|
27
|
+
$ owox --help
|
|
28
|
+
USAGE
|
|
29
|
+
$ owox COMMAND
|
|
30
|
+
...
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
<!-- usagestop -->
|
|
34
|
+
|
|
35
|
+
# Local Development: npm link
|
|
36
|
+
|
|
37
|
+
For local development and testing of this CLI, especially when it's not published to a public npm registry, you can use `npm link`. This command creates a symbolic link from your local package to the global npm directory, allowing you to run `owox` from any directory on your system as if it were globally installed.
|
|
38
|
+
|
|
39
|
+
## Using `npm link`
|
|
40
|
+
|
|
41
|
+
To link your local `owox` CLI globally, navigate to the `apps/owox` directory and execute:
|
|
42
|
+
|
|
43
|
+
```sh-session
|
|
44
|
+
$ npm link
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
After successfully linking, you can run `owox` commands from any directory:
|
|
48
|
+
|
|
49
|
+
```sh-session
|
|
50
|
+
$ owox serve --port 8080
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Using `npm unlink -g owox`
|
|
54
|
+
|
|
55
|
+
If you need to remove the global symbolic link to your local `owox` CLI, navigate to the `apps/owox` directory and execute:
|
|
56
|
+
|
|
57
|
+
```sh-session
|
|
58
|
+
$ npm unlink -g owox
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
This will remove the global link, and `owox` will no longer be accessible globally unless re-linked or installed through an npm registry.
|
|
62
|
+
|
|
63
|
+
# Commands
|
|
64
|
+
|
|
65
|
+
<!-- commands -->
|
|
66
|
+
|
|
67
|
+
- [`owox serve`](#owox-serve)
|
|
68
|
+
- [`owox help [COMMAND]`](#owox-help-command)
|
|
69
|
+
|
|
70
|
+
## `owox serve`
|
|
71
|
+
|
|
72
|
+
Start the OWOX Data Marts application in production mode
|
|
73
|
+
|
|
74
|
+
```
|
|
75
|
+
USAGE
|
|
76
|
+
$ owox serve [-p <value>]
|
|
77
|
+
|
|
78
|
+
FLAGS
|
|
79
|
+
-p, --port=<value> [default: 3000] Port number for the application
|
|
80
|
+
|
|
81
|
+
DESCRIPTION
|
|
82
|
+
Start the OWOX Data Marts application in production mode
|
|
83
|
+
|
|
84
|
+
EXAMPLES
|
|
85
|
+
$ owox serve
|
|
86
|
+
$ owox serve --port 8080
|
|
87
|
+
$ owox serve -p 3001
|
|
88
|
+
$ PORT=8080 owox serve
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
_See code: [src/commands/serve.ts](https://github.com/OWOX/owox-data-marts/blob/v0.0.0/src/commands/serve.ts)_
|
|
92
|
+
|
|
93
|
+
## `owox help [COMMAND]`
|
|
94
|
+
|
|
95
|
+
Display help for owox.
|
|
96
|
+
|
|
97
|
+
```
|
|
98
|
+
USAGE
|
|
99
|
+
$ owox help [COMMAND...] [-n]
|
|
100
|
+
|
|
101
|
+
ARGUMENTS
|
|
102
|
+
COMMAND... Command to show help for.
|
|
103
|
+
|
|
104
|
+
FLAGS
|
|
105
|
+
-n, --nested-commands Include all nested commands in the output.
|
|
106
|
+
|
|
107
|
+
DESCRIPTION
|
|
108
|
+
Display help for owox.
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
_See code: [@oclif/plugin-help](https://github.com/oclif/plugin-help/blob/v6.0.21/src/commands/help.ts)_
|
|
112
|
+
|
|
113
|
+
<!-- commandsstop -->
|
|
114
|
+
|
|
115
|
+
# FAQ
|
|
116
|
+
|
|
117
|
+
This section explains the purpose of the files located in the `bin` directory of the CLI.
|
|
118
|
+
|
|
119
|
+
### Why are there files in the `bin` folder (`dev.cmd`, `run.js`, `dev.js`, `run.cmd`)? Why do some have a `.cmd` format?
|
|
120
|
+
|
|
121
|
+
The `bin` folder contains the executable entry points for your CLI. Their presence and format are designed to support different operating systems and operational modes (development/production).
|
|
122
|
+
|
|
123
|
+
- **`run.js` (and `run.cmd`)**: These are the primary "production" entry points for your CLI.
|
|
124
|
+
|
|
125
|
+
- **`run.js`**: This is the main executable file for Unix-based systems (Linux, macOS). The `#!/usr/bin/env node` (shebang) line at the beginning tells the operating system to execute this file using Node.js. This file launches the compiled version of your CLI (from the `dist` folder).
|
|
126
|
+
- **`run.cmd`**: This is the equivalent of `run.js` for Windows operating systems. Windows does not understand shebangs, so a separate `.cmd` (or `.bat`) file is required to explicitly instruct the system to execute the Node.js script using the `node` interpreter.
|
|
127
|
+
|
|
128
|
+
- **`dev.js` (and `dev.cmd`)**: These are entry points specifically designed for **development**.
|
|
129
|
+
- **`dev.js`**: This executable file is for Unix-based systems when running in development mode. Notice the shebang line `#!/usr/bin/env -S node --loader ts-node/esm --disable-warning=ExperimentalWarning`. This allows Node.js to run your TypeScript code **without prior compilation** by using the `ts-node/esm` loader. This significantly speeds up development as you don't need to wait for compilation every time you make changes. The `development: true` flag is passed to `@oclif/core` to enable development-specific features.
|
|
130
|
+
- **`dev.cmd`**: This is the Windows equivalent of `dev.js`, also used for running in development mode with `ts-node/esm`.
|
|
131
|
+
|
|
132
|
+
In summary, the `.cmd` files ensure compatibility with Windows, while the `run` and `dev` pairs provide distinct entry points for the "production-ready" (compiled) CLI version and the active development version (directly from TypeScript source files).
|
package/bin/dev.cmd
ADDED
package/bin/dev.js
ADDED
package/bin/run.cmd
ADDED
package/bin/run.js
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { Command } from '@oclif/core';
|
|
2
|
+
/**
|
|
3
|
+
* Command to start the OWOX Data Marts application.
|
|
4
|
+
* Requires @owox/backend to be installed.
|
|
5
|
+
*/
|
|
6
|
+
export default class Serve extends Command {
|
|
7
|
+
static description: string;
|
|
8
|
+
static examples: string[];
|
|
9
|
+
static flags: {
|
|
10
|
+
port: import("@oclif/core/interfaces").OptionFlag<number, import("@oclif/core/interfaces").CustomOptions>;
|
|
11
|
+
};
|
|
12
|
+
private childProcess?;
|
|
13
|
+
private isShuttingDown;
|
|
14
|
+
/**
|
|
15
|
+
* Main execution method for the serve command
|
|
16
|
+
*/
|
|
17
|
+
run(): Promise<void>;
|
|
18
|
+
/**
|
|
19
|
+
* Attaches event handlers to the child process
|
|
20
|
+
*/
|
|
21
|
+
private attachProcessEventHandlers;
|
|
22
|
+
/**
|
|
23
|
+
* Creates environment variables for the child process
|
|
24
|
+
* @param port - Port number to set in environment
|
|
25
|
+
* @returns Environment variables object
|
|
26
|
+
*/
|
|
27
|
+
private createProcessEnvironment;
|
|
28
|
+
/**
|
|
29
|
+
* Extracts PID from ps command output line
|
|
30
|
+
*/
|
|
31
|
+
private extractPidFromProcessLine;
|
|
32
|
+
/**
|
|
33
|
+
* Gets the path to the backend package
|
|
34
|
+
* @returns The full path to the backend entry point
|
|
35
|
+
*/
|
|
36
|
+
private getBackendPath;
|
|
37
|
+
/**
|
|
38
|
+
* Handles child process exit events
|
|
39
|
+
* @param code - Exit code
|
|
40
|
+
* @param signal - Exit signal
|
|
41
|
+
*/
|
|
42
|
+
private handleProcessExit;
|
|
43
|
+
/**
|
|
44
|
+
* Handles shutdown signals
|
|
45
|
+
* @param signal - The received shutdown signal
|
|
46
|
+
*/
|
|
47
|
+
private handleShutdownSignal;
|
|
48
|
+
/**
|
|
49
|
+
* Handles startup errors
|
|
50
|
+
* @param error - The error that occurred during startup
|
|
51
|
+
*/
|
|
52
|
+
private handleStartupError;
|
|
53
|
+
/**
|
|
54
|
+
* Checks if the backend package is available
|
|
55
|
+
* @param backendPath - Path to the backend entry point
|
|
56
|
+
* @returns True if backend package exists and is accessible
|
|
57
|
+
*/
|
|
58
|
+
private isBackendAvailable;
|
|
59
|
+
/**
|
|
60
|
+
* Kills all processes marked with PROCESS_MARKER
|
|
61
|
+
*/
|
|
62
|
+
private killMarkedProcesses;
|
|
63
|
+
/**
|
|
64
|
+
* Kills a process by PID
|
|
65
|
+
*/
|
|
66
|
+
private killProcess;
|
|
67
|
+
/**
|
|
68
|
+
* Sets up graceful shutdown handlers for system signals
|
|
69
|
+
*/
|
|
70
|
+
private setupGracefulShutdown;
|
|
71
|
+
/**
|
|
72
|
+
* Spawns a child process with the given options
|
|
73
|
+
* @param options - Process spawn options
|
|
74
|
+
*/
|
|
75
|
+
private spawnProcess;
|
|
76
|
+
/**
|
|
77
|
+
* Starts the backend application
|
|
78
|
+
* @param backendPath - Path to the backend entry point
|
|
79
|
+
* @param port - Port number to run the application on
|
|
80
|
+
*/
|
|
81
|
+
private startBackend;
|
|
82
|
+
/**
|
|
83
|
+
* Waits for processes to cleanup
|
|
84
|
+
*/
|
|
85
|
+
private waitForCleanup;
|
|
86
|
+
/**
|
|
87
|
+
* Waits for the child process to complete
|
|
88
|
+
* @returns Promise that resolves when process exits successfully
|
|
89
|
+
*/
|
|
90
|
+
private waitForProcessCompletion;
|
|
91
|
+
}
|
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
import { Command, Flags } from '@oclif/core';
|
|
2
|
+
import { exec, spawn } from 'node:child_process';
|
|
3
|
+
import { existsSync } from 'node:fs';
|
|
4
|
+
import { createRequire } from 'node:module';
|
|
5
|
+
import { join } from 'node:path';
|
|
6
|
+
import { promisify } from 'node:util';
|
|
7
|
+
const execAsync = promisify(exec);
|
|
8
|
+
const require = createRequire(import.meta.url);
|
|
9
|
+
/**
|
|
10
|
+
* Constants for the serve command
|
|
11
|
+
*/
|
|
12
|
+
const CONSTANTS = {
|
|
13
|
+
CLEANUP_DELAY_MS: 1000,
|
|
14
|
+
DEFAULT_PORT: 3000,
|
|
15
|
+
PROCESS_MARKER: 'owox-app',
|
|
16
|
+
SHUTDOWN_SIGNALS: ['SIGINT', 'SIGTERM'],
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* Command to start the OWOX Data Marts application.
|
|
20
|
+
* Requires @owox/backend to be installed.
|
|
21
|
+
*/
|
|
22
|
+
export default class Serve extends Command {
|
|
23
|
+
static description = 'Start the OWOX Data Marts application';
|
|
24
|
+
static examples = [
|
|
25
|
+
'<%= config.bin %> serve',
|
|
26
|
+
'<%= config.bin %> serve --port 8080',
|
|
27
|
+
'<%= config.bin %> serve -p 3001',
|
|
28
|
+
'$ PORT=8080 <%= config.bin %> serve',
|
|
29
|
+
];
|
|
30
|
+
static flags = {
|
|
31
|
+
port: Flags.integer({
|
|
32
|
+
char: 'p',
|
|
33
|
+
default: CONSTANTS.DEFAULT_PORT,
|
|
34
|
+
description: 'Port number for the application',
|
|
35
|
+
env: 'PORT',
|
|
36
|
+
}),
|
|
37
|
+
};
|
|
38
|
+
childProcess;
|
|
39
|
+
isShuttingDown = false;
|
|
40
|
+
/**
|
|
41
|
+
* Main execution method for the serve command
|
|
42
|
+
*/
|
|
43
|
+
async run() {
|
|
44
|
+
const { flags } = await this.parse(Serve);
|
|
45
|
+
this.log('🚀 Starting OWOX Data Marts...');
|
|
46
|
+
this.setupGracefulShutdown();
|
|
47
|
+
const backendPath = this.getBackendPath();
|
|
48
|
+
if (!this.isBackendAvailable(backendPath)) {
|
|
49
|
+
this.error('@owox/backend package not found. Please ensure it is installed:\n' +
|
|
50
|
+
'npm install @owox/backend', { exit: 1 });
|
|
51
|
+
}
|
|
52
|
+
try {
|
|
53
|
+
await this.killMarkedProcesses();
|
|
54
|
+
await this.startBackend(backendPath, flags.port);
|
|
55
|
+
}
|
|
56
|
+
catch (error) {
|
|
57
|
+
this.handleStartupError(error);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Attaches event handlers to the child process
|
|
62
|
+
*/
|
|
63
|
+
attachProcessEventHandlers() {
|
|
64
|
+
if (!this.childProcess)
|
|
65
|
+
return;
|
|
66
|
+
this.childProcess.on('error', (error) => {
|
|
67
|
+
if (!this.isShuttingDown) {
|
|
68
|
+
this.error(`Application process error: ${error.message}`);
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
this.childProcess.on('exit', (code, signal) => {
|
|
72
|
+
if (!this.isShuttingDown) {
|
|
73
|
+
this.handleProcessExit(code, signal);
|
|
74
|
+
}
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Creates environment variables for the child process
|
|
79
|
+
* @param port - Port number to set in environment
|
|
80
|
+
* @returns Environment variables object
|
|
81
|
+
*/
|
|
82
|
+
createProcessEnvironment(port) {
|
|
83
|
+
return { ...process.env, PORT: port.toString() };
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Extracts PID from ps command output line
|
|
87
|
+
*/
|
|
88
|
+
extractPidFromProcessLine(processLine) {
|
|
89
|
+
const pid = processLine.trim().split(/\s+/)[1];
|
|
90
|
+
const numericPid = Number.parseInt(pid, 10);
|
|
91
|
+
return !Number.isNaN(numericPid) && numericPid > 0 ? numericPid : null;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Gets the path to the backend package
|
|
95
|
+
* @returns The full path to the backend entry point
|
|
96
|
+
*/
|
|
97
|
+
getBackendPath() {
|
|
98
|
+
try {
|
|
99
|
+
// Try to resolve using Node.js module resolution
|
|
100
|
+
return require.resolve('@owox/backend');
|
|
101
|
+
}
|
|
102
|
+
catch {
|
|
103
|
+
// Fallback to node_modules path for ESM compatibility
|
|
104
|
+
return join(this.config.root, 'node_modules', '@owox/backend', 'dist', 'main.js');
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Handles child process exit events
|
|
109
|
+
* @param code - Exit code
|
|
110
|
+
* @param signal - Exit signal
|
|
111
|
+
*/
|
|
112
|
+
handleProcessExit(code, signal) {
|
|
113
|
+
if (code !== null && code !== 0) {
|
|
114
|
+
this.error(`Application process exited with code ${code}`);
|
|
115
|
+
}
|
|
116
|
+
else if (signal) {
|
|
117
|
+
this.warn(`Application process terminated by signal ${signal}`);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Handles shutdown signals
|
|
122
|
+
* @param signal - The received shutdown signal
|
|
123
|
+
*/
|
|
124
|
+
handleShutdownSignal(signal) {
|
|
125
|
+
if (this.isShuttingDown)
|
|
126
|
+
return;
|
|
127
|
+
this.isShuttingDown = true;
|
|
128
|
+
this.log(`Received ${signal}, shutting down gracefully...`);
|
|
129
|
+
if (this.childProcess?.kill()) {
|
|
130
|
+
this.log('Stopping application...');
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Handles startup errors
|
|
135
|
+
* @param error - The error that occurred during startup
|
|
136
|
+
*/
|
|
137
|
+
handleStartupError(error) {
|
|
138
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
139
|
+
this.error(`Failed to start application: ${message}`, { exit: 1 });
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Checks if the backend package is available
|
|
143
|
+
* @param backendPath - Path to the backend entry point
|
|
144
|
+
* @returns True if backend package exists and is accessible
|
|
145
|
+
*/
|
|
146
|
+
isBackendAvailable(backendPath) {
|
|
147
|
+
return existsSync(backendPath);
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Kills all processes marked with PROCESS_MARKER
|
|
151
|
+
*/
|
|
152
|
+
async killMarkedProcesses() {
|
|
153
|
+
try {
|
|
154
|
+
const { stdout } = await execAsync(`ps -ef | grep "${CONSTANTS.PROCESS_MARKER}" | grep -v grep`);
|
|
155
|
+
if (!stdout.trim()) {
|
|
156
|
+
this.log(`🔍 No previous zombie processes found`);
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
159
|
+
const processes = stdout.trim().split('\n');
|
|
160
|
+
this.warn(`🧹 Found ${processes.length} zombie processes, cleaning up...`);
|
|
161
|
+
const killPromises = processes.map(async (processLine) => {
|
|
162
|
+
const pid = this.extractPidFromProcessLine(processLine);
|
|
163
|
+
if (pid) {
|
|
164
|
+
await this.killProcess(pid);
|
|
165
|
+
}
|
|
166
|
+
});
|
|
167
|
+
await Promise.all(killPromises);
|
|
168
|
+
await this.waitForCleanup();
|
|
169
|
+
this.log(`✅ Zombie cleanup completed`);
|
|
170
|
+
}
|
|
171
|
+
catch {
|
|
172
|
+
// This is normal if no previous processes are found
|
|
173
|
+
this.log(`🔍 No previous zombie processes found`);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Kills a process by PID
|
|
178
|
+
*/
|
|
179
|
+
async killProcess(pid) {
|
|
180
|
+
try {
|
|
181
|
+
process.kill(pid, 'SIGTERM');
|
|
182
|
+
this.log(`💀 Killed zombie process PID: ${pid}`);
|
|
183
|
+
}
|
|
184
|
+
catch {
|
|
185
|
+
this.log(`🔍 Process ${pid} already terminated`);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* Sets up graceful shutdown handlers for system signals
|
|
190
|
+
*/
|
|
191
|
+
setupGracefulShutdown() {
|
|
192
|
+
for (const signal of CONSTANTS.SHUTDOWN_SIGNALS) {
|
|
193
|
+
process.on(signal, () => this.handleShutdownSignal(signal));
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Spawns a child process with the given options
|
|
198
|
+
* @param options - Process spawn options
|
|
199
|
+
*/
|
|
200
|
+
async spawnProcess(options) {
|
|
201
|
+
const env = this.createProcessEnvironment(options.port);
|
|
202
|
+
this.log(`📦 Starting server on port ${options.port}...`);
|
|
203
|
+
// Add process marker to arguments
|
|
204
|
+
const argsWithMarker = [...options.args, `--${CONSTANTS.PROCESS_MARKER}`];
|
|
205
|
+
this.childProcess = spawn(options.command, argsWithMarker, {
|
|
206
|
+
env,
|
|
207
|
+
stdio: 'inherit',
|
|
208
|
+
});
|
|
209
|
+
if (this.childProcess.pid) {
|
|
210
|
+
this.log(`📦 Server process started with PID: ${this.childProcess.pid}`);
|
|
211
|
+
}
|
|
212
|
+
else {
|
|
213
|
+
throw new Error('Failed to start server process');
|
|
214
|
+
}
|
|
215
|
+
this.attachProcessEventHandlers();
|
|
216
|
+
return this.waitForProcessCompletion();
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* Starts the backend application
|
|
220
|
+
* @param backendPath - Path to the backend entry point
|
|
221
|
+
* @param port - Port number to run the application on
|
|
222
|
+
*/
|
|
223
|
+
async startBackend(backendPath, port) {
|
|
224
|
+
this.log('Starting backend application...');
|
|
225
|
+
const options = {
|
|
226
|
+
args: [backendPath],
|
|
227
|
+
command: 'node',
|
|
228
|
+
port,
|
|
229
|
+
};
|
|
230
|
+
await this.spawnProcess(options);
|
|
231
|
+
}
|
|
232
|
+
/**
|
|
233
|
+
* Waits for processes to cleanup
|
|
234
|
+
*/
|
|
235
|
+
async waitForCleanup() {
|
|
236
|
+
return new Promise(resolve => {
|
|
237
|
+
setTimeout(() => resolve(), CONSTANTS.CLEANUP_DELAY_MS);
|
|
238
|
+
});
|
|
239
|
+
}
|
|
240
|
+
/**
|
|
241
|
+
* Waits for the child process to complete
|
|
242
|
+
* @returns Promise that resolves when process exits successfully
|
|
243
|
+
*/
|
|
244
|
+
waitForProcessCompletion() {
|
|
245
|
+
return new Promise((resolve, reject) => {
|
|
246
|
+
if (!this.childProcess) {
|
|
247
|
+
reject(new Error('Failed to start child process'));
|
|
248
|
+
return;
|
|
249
|
+
}
|
|
250
|
+
this.childProcess.on('exit', (code) => {
|
|
251
|
+
if (this.isShuttingDown) {
|
|
252
|
+
this.log('Application stopped successfully.');
|
|
253
|
+
resolve();
|
|
254
|
+
}
|
|
255
|
+
else if (code === 0 || code === null) {
|
|
256
|
+
this.log('Application process exited successfully.');
|
|
257
|
+
resolve();
|
|
258
|
+
}
|
|
259
|
+
else {
|
|
260
|
+
reject(new Error(`Application process failed with exit code ${code}`));
|
|
261
|
+
}
|
|
262
|
+
});
|
|
263
|
+
});
|
|
264
|
+
}
|
|
265
|
+
}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { run } from '@oclif/core';
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { run } from '@oclif/core';
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
{
|
|
2
|
+
"commands": {
|
|
3
|
+
"serve": {
|
|
4
|
+
"aliases": [],
|
|
5
|
+
"args": {},
|
|
6
|
+
"description": "Start the OWOX Data Marts application",
|
|
7
|
+
"examples": [
|
|
8
|
+
"<%= config.bin %> serve",
|
|
9
|
+
"<%= config.bin %> serve --port 8080",
|
|
10
|
+
"<%= config.bin %> serve -p 3001",
|
|
11
|
+
"$ PORT=8080 <%= config.bin %> serve"
|
|
12
|
+
],
|
|
13
|
+
"flags": {
|
|
14
|
+
"port": {
|
|
15
|
+
"char": "p",
|
|
16
|
+
"description": "Port number for the application",
|
|
17
|
+
"env": "PORT",
|
|
18
|
+
"name": "port",
|
|
19
|
+
"default": 3000,
|
|
20
|
+
"hasDynamicHelp": false,
|
|
21
|
+
"multiple": false,
|
|
22
|
+
"type": "option"
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
"hasDynamicHelp": false,
|
|
26
|
+
"hiddenAliases": [],
|
|
27
|
+
"id": "serve",
|
|
28
|
+
"pluginAlias": "owox",
|
|
29
|
+
"pluginName": "owox",
|
|
30
|
+
"pluginType": "core",
|
|
31
|
+
"strict": true,
|
|
32
|
+
"enableJsonFlag": false,
|
|
33
|
+
"isESM": true,
|
|
34
|
+
"relativePath": [
|
|
35
|
+
"dist",
|
|
36
|
+
"commands",
|
|
37
|
+
"serve.js"
|
|
38
|
+
]
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
"version": "0.0.0"
|
|
42
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "owox",
|
|
3
|
+
"description": "OWOX Data Marts CLI: Simple command-line interface to start the OWOX Data Marts application with backend and frontend components.",
|
|
4
|
+
"version": "0.0.0",
|
|
5
|
+
"publishConfig": {
|
|
6
|
+
"access": "public"
|
|
7
|
+
},
|
|
8
|
+
"bin": {
|
|
9
|
+
"owox": "./bin/run.js"
|
|
10
|
+
},
|
|
11
|
+
"bugs": "https://github.com/OWOX/owox-data-marts/issues",
|
|
12
|
+
"dependencies": {
|
|
13
|
+
"@oclif/core": "^4",
|
|
14
|
+
"@oclif/plugin-help": "^6",
|
|
15
|
+
"@oclif/plugin-plugins": "^5",
|
|
16
|
+
"@owox/backend": "0.0.0"
|
|
17
|
+
},
|
|
18
|
+
"devDependencies": {
|
|
19
|
+
"@eslint/compat": "^1",
|
|
20
|
+
"@oclif/prettier-config": "^0.2.1",
|
|
21
|
+
"@oclif/test": "^4",
|
|
22
|
+
"@types/chai": "^4",
|
|
23
|
+
"@types/mocha": "^10",
|
|
24
|
+
"@types/node": "^18",
|
|
25
|
+
"chai": "^4",
|
|
26
|
+
"eslint": "^9",
|
|
27
|
+
"eslint-config-oclif": "^6",
|
|
28
|
+
"eslint-config-prettier": "^10",
|
|
29
|
+
"mocha": "^10",
|
|
30
|
+
"oclif": "^4",
|
|
31
|
+
"ts-node": "^10",
|
|
32
|
+
"typescript": "^5"
|
|
33
|
+
},
|
|
34
|
+
"engines": {
|
|
35
|
+
"node": ">=22.16.0"
|
|
36
|
+
},
|
|
37
|
+
"files": [
|
|
38
|
+
"./bin",
|
|
39
|
+
"./dist",
|
|
40
|
+
"./oclif.manifest.json"
|
|
41
|
+
],
|
|
42
|
+
"homepage": "https://github.com/OWOX/owox-data-marts",
|
|
43
|
+
"keywords": [
|
|
44
|
+
"data-marts",
|
|
45
|
+
"cli",
|
|
46
|
+
"server",
|
|
47
|
+
"nestjs",
|
|
48
|
+
"backend",
|
|
49
|
+
"owox",
|
|
50
|
+
"data-orchestration",
|
|
51
|
+
"sqlite",
|
|
52
|
+
"mysql",
|
|
53
|
+
"bigquery",
|
|
54
|
+
"athena"
|
|
55
|
+
],
|
|
56
|
+
"license": "ELv2",
|
|
57
|
+
"main": "dist/index.js",
|
|
58
|
+
"type": "module",
|
|
59
|
+
"oclif": {
|
|
60
|
+
"bin": "owox",
|
|
61
|
+
"dirname": "owox",
|
|
62
|
+
"commands": "./dist/commands",
|
|
63
|
+
"plugins": [
|
|
64
|
+
"@oclif/plugin-help",
|
|
65
|
+
"@oclif/plugin-plugins"
|
|
66
|
+
],
|
|
67
|
+
"topicSeparator": " "
|
|
68
|
+
},
|
|
69
|
+
"repository": "OWOX/owox-data-marts",
|
|
70
|
+
"scripts": {
|
|
71
|
+
"build": "tsc -b",
|
|
72
|
+
"lint": "eslint",
|
|
73
|
+
"posttest": "npm run lint",
|
|
74
|
+
"prepack": "oclif manifest",
|
|
75
|
+
"prepublishOnly": "npm audit && npm run test && npm run lint",
|
|
76
|
+
"test": "mocha --forbid-only \"test/**/*.test.ts\"",
|
|
77
|
+
"version": "oclif readme && git add README.md"
|
|
78
|
+
},
|
|
79
|
+
"types": "dist/index.d.ts"
|
|
80
|
+
}
|