@rift-vs/rift 0.1.0-RC1

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 ADDED
@@ -0,0 +1,233 @@
1
+ # @rift-vs/rift
2
+
3
+ Mountebank-compatible Node.js bindings for [Rift](https://github.com/EtaCassiopeia/rift) - a high-performance service virtualization and chaos engineering proxy written in Rust.
4
+
5
+ ## Features
6
+
7
+ - **Drop-in replacement** for Mountebank's `mb.create()` API
8
+ - **High performance** - Rust-based proxy with minimal resource usage
9
+ - **Fault injection** - Built-in chaos engineering capabilities
10
+ - **TypeScript support** - Full type definitions included
11
+ - **Cross-platform** - Supports macOS, Linux, and Windows
12
+
13
+ ## Installation
14
+
15
+ ```bash
16
+ npm install @rift-vs/rift
17
+ ```
18
+
19
+ The package automatically downloads the appropriate `rift-http-proxy` binary for your platform during installation.
20
+
21
+ ### Supported Platforms
22
+
23
+ - macOS (x64, arm64)
24
+ - Linux (x64, arm64)
25
+ - Windows (x64)
26
+
27
+ ### Manual Binary Installation
28
+
29
+ If automatic download doesn't work, you can install the binary manually:
30
+
31
+ 1. Download from [GitHub Releases](https://github.com/EtaCassiopeia/rift/releases)
32
+ 2. Set the `RIFT_BINARY_PATH` environment variable to the binary location
33
+
34
+ ### Local Development Installation
35
+
36
+ If you're working with the Rift source code, you can install locally:
37
+
38
+ ```bash
39
+ # Clone and build Rift
40
+ git clone https://github.com/EtaCassiopeia/rift.git
41
+ cd rift
42
+
43
+ # Install the binary locally (builds and installs to ~/.local/bin)
44
+ ./scripts/install-local.sh
45
+
46
+ # Or if you already have a release build:
47
+ RIFT_SKIP_BUILD=1 ./scripts/install-local.sh
48
+ ```
49
+
50
+ The package will automatically find the `rift` or `mb` binary in your PATH.
51
+
52
+ ## Usage
53
+
54
+ ### Basic Usage
55
+
56
+ ```javascript
57
+ import rift from '@rift-vs/rift';
58
+
59
+ // Start a Rift server (Mountebank-compatible)
60
+ const server = await rift.create({
61
+ port: 2525,
62
+ loglevel: 'debug',
63
+ });
64
+
65
+ // Create an imposter via REST API
66
+ await fetch('http://localhost:2525/imposters', {
67
+ method: 'POST',
68
+ headers: { 'Content-Type': 'application/json' },
69
+ body: JSON.stringify({
70
+ port: 4545,
71
+ protocol: 'http',
72
+ stubs: [
73
+ {
74
+ predicates: [{ equals: { path: '/api/users' } }],
75
+ responses: [
76
+ {
77
+ is: {
78
+ statusCode: 200,
79
+ headers: { 'Content-Type': 'application/json' },
80
+ body: JSON.stringify([{ id: 1, name: 'Alice' }]),
81
+ },
82
+ },
83
+ ],
84
+ },
85
+ ],
86
+ }),
87
+ });
88
+
89
+ // Your tests can now use http://localhost:4545/api/users
90
+
91
+ // Clean up
92
+ await server.close();
93
+ ```
94
+
95
+ ### Migration from Mountebank
96
+
97
+ Migrating from Mountebank is straightforward - just change the import:
98
+
99
+ **Before (Mountebank):**
100
+
101
+ ```javascript
102
+ import mb from 'mountebank';
103
+
104
+ const server = await mb.create({
105
+ port: 2525,
106
+ loglevel: 'debug',
107
+ allowInjection: true,
108
+ });
109
+ ```
110
+
111
+ **After (Rift):**
112
+
113
+ ```javascript
114
+ import rift from '@rift-vs/rift';
115
+
116
+ const server = await rift.create({
117
+ port: 2525,
118
+ loglevel: 'debug',
119
+ allowInjection: true,
120
+ });
121
+ ```
122
+
123
+ ### TypeScript
124
+
125
+ Full TypeScript support is included:
126
+
127
+ ```typescript
128
+ import rift, { CreateOptions, RiftServer } from '@rift-vs/rift';
129
+
130
+ const options: CreateOptions = {
131
+ port: 2525,
132
+ loglevel: 'debug',
133
+ };
134
+
135
+ const server: RiftServer = await rift.create(options);
136
+
137
+ // server.port - the port the server is listening on
138
+ // server.host - the host the server is bound to
139
+ // server.close() - gracefully close the server
140
+ ```
141
+
142
+ ## API Reference
143
+
144
+ ### `create(options?: CreateOptions): Promise<RiftServer>`
145
+
146
+ Creates and starts a new Rift server instance.
147
+
148
+ #### Options
149
+
150
+ | Option | Type | Default | Description |
151
+ | -------------------- | ------------ | ------------- | ------------------------------------------ |
152
+ | `port` | `number` | `2525` | Admin API port |
153
+ | `host` | `string` | `'localhost'` | Bind address |
154
+ | `loglevel` | `string` | `'info'` | Log level: debug, info, warn, error |
155
+ | `logfile` | `string` | - | Path to log file |
156
+ | `ipWhitelist` | `string[]` | - | Allowed IP addresses |
157
+ | `allowInjection` | `boolean` | `false` | Enable script injection |
158
+
159
+ ### `RiftServer`
160
+
161
+ The server instance returned by `create()`.
162
+
163
+ #### Properties
164
+
165
+ - `port: number` - The port the server is listening on
166
+ - `host: string` - The host the server is bound to
167
+
168
+ #### Methods
169
+
170
+ - `close(): Promise<void>` - Gracefully shutdown the server
171
+
172
+ #### Events
173
+
174
+ - `exit` - Emitted when the server process exits
175
+ - `error` - Emitted on server errors
176
+ - `stdout` - Emitted with stdout data
177
+ - `stderr` - Emitted with stderr data
178
+
179
+ ### Utility Functions
180
+
181
+ #### `findBinary(): Promise<string>`
182
+
183
+ Locates the rift-http-proxy binary. Searches in order:
184
+ 1. `RIFT_BINARY_PATH` environment variable
185
+ 2. Package's `binaries/` directory
186
+ 3. System PATH
187
+
188
+ #### `downloadBinary(version?: string): Promise<string>`
189
+
190
+ Downloads the Rift binary for the current platform.
191
+
192
+ #### `getBinaryVersion(): Promise<string | null>`
193
+
194
+ Returns the installed binary version, or null if not found.
195
+
196
+ ## REST API Compatibility
197
+
198
+ Rift implements the Mountebank REST API:
199
+
200
+ | Endpoint | Method | Description |
201
+ | --------------------------------- | -------- | --------------------- |
202
+ | `/` | GET | Server info |
203
+ | `/imposters` | GET | List all imposters |
204
+ | `/imposters` | POST | Create imposter |
205
+ | `/imposters` | PUT | Replace all imposters |
206
+ | `/imposters` | DELETE | Delete all imposters |
207
+ | `/imposters/:port` | GET | Get imposter |
208
+ | `/imposters/:port` | DELETE | Delete imposter |
209
+ | `/imposters/:port/stubs` | POST | Add stub to imposter |
210
+ | `/imposters/:port/requests` | DELETE | Clear requests |
211
+
212
+ ## Environment Variables
213
+
214
+ | Variable | Description |
215
+ | ------------------------- | ------------------------------------------------ |
216
+ | `RIFT_BINARY_PATH` | Path to the rift-http-proxy binary |
217
+ | `RIFT_VERSION` | Version to download (default: latest) |
218
+ | `RIFT_DOWNLOAD_URL` | Custom download URL for binary |
219
+ | `RIFT_SKIP_BINARY_DOWNLOAD` | Skip binary download during install |
220
+
221
+ ## Requirements
222
+
223
+ - Node.js 18.0.0 or later
224
+ - One of the supported platforms (see above)
225
+
226
+ ## License
227
+
228
+ MIT
229
+
230
+ ## Related
231
+
232
+ - [Rift](https://github.com/EtaCassiopeia/rift) - The Rust proxy
233
+ - [Mountebank](https://www.mbtest.org/) - The original service virtualization tool
@@ -0,0 +1,280 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Postinstall script for rift-node
5
+ *
6
+ * Downloads the appropriate Rift binary for the current platform.
7
+ * This script runs automatically after `npm install`.
8
+ */
9
+
10
+ import https from 'https';
11
+ import fs from 'fs';
12
+ import path from 'path';
13
+ import { fileURLToPath } from 'url';
14
+ import { execSync } from 'child_process';
15
+
16
+ const __filename = fileURLToPath(import.meta.url);
17
+ const __dirname = path.dirname(__filename);
18
+
19
+ const BINARIES_DIR = path.join(__dirname, '..', 'binaries');
20
+ const BINARY_NAME = process.platform === 'win32' ? 'rift.exe' : 'rift';
21
+
22
+ // Version to download (can be overridden by RIFT_VERSION env var)
23
+ // Use 'latest' to get the latest release, or specify a version like 'v0.1.0'
24
+ const VERSION = process.env.RIFT_VERSION || 'latest';
25
+
26
+ // GitHub releases base URL (can be overridden by RIFT_DOWNLOAD_URL env var)
27
+ const BASE_URL =
28
+ process.env.RIFT_DOWNLOAD_URL || 'https://github.com/EtaCassiopeia/rift/releases/download';
29
+
30
+ // Platform to Rust target mapping
31
+ const PLATFORM_TO_TARGET = {
32
+ 'darwin-x64': 'x86_64-apple-darwin',
33
+ 'darwin-arm64': 'aarch64-apple-darwin',
34
+ 'linux-x64': 'x86_64-unknown-linux-gnu',
35
+ 'linux-arm64': 'aarch64-unknown-linux-gnu',
36
+ 'win32-x64': 'x86_64-pc-windows-msvc',
37
+ };
38
+
39
+ // Archive extension by platform
40
+ const ARCHIVE_EXT = {
41
+ 'darwin-x64': 'tar.gz',
42
+ 'darwin-arm64': 'tar.gz',
43
+ 'linux-x64': 'tar.gz',
44
+ 'linux-arm64': 'tar.gz',
45
+ 'win32-x64': 'zip',
46
+ };
47
+
48
+ /**
49
+ * Download a file from URL, following redirects
50
+ */
51
+ function downloadFile(url, dest) {
52
+ return new Promise((resolve, reject) => {
53
+ const file = fs.createWriteStream(dest);
54
+
55
+ const request = https.get(url, (response) => {
56
+ // Handle redirects (GitHub releases redirect to S3)
57
+ if (response.statusCode === 301 || response.statusCode === 302) {
58
+ const redirectUrl = response.headers.location;
59
+ if (redirectUrl) {
60
+ file.close();
61
+ fs.unlinkSync(dest);
62
+ downloadFile(redirectUrl, dest).then(resolve).catch(reject);
63
+ return;
64
+ }
65
+ }
66
+
67
+ if (response.statusCode !== 200) {
68
+ file.close();
69
+ try {
70
+ fs.unlinkSync(dest);
71
+ } catch {}
72
+ reject(new Error(`Failed to download: HTTP ${response.statusCode}`));
73
+ return;
74
+ }
75
+
76
+ response.pipe(file);
77
+
78
+ file.on('finish', () => {
79
+ file.close();
80
+ resolve();
81
+ });
82
+ });
83
+
84
+ request.on('error', (err) => {
85
+ file.close();
86
+ try {
87
+ fs.unlinkSync(dest);
88
+ } catch {}
89
+ reject(err);
90
+ });
91
+
92
+ file.on('error', (err) => {
93
+ file.close();
94
+ try {
95
+ fs.unlinkSync(dest);
96
+ } catch {}
97
+ reject(err);
98
+ });
99
+ });
100
+ }
101
+
102
+ /**
103
+ * Extract archive based on type
104
+ */
105
+ function extractArchive(archivePath, destDir) {
106
+ if (archivePath.endsWith('.tar.gz')) {
107
+ execSync(`tar -xzf "${archivePath}" -C "${destDir}"`, { stdio: 'pipe' });
108
+ } else if (archivePath.endsWith('.zip')) {
109
+ if (process.platform === 'win32') {
110
+ execSync(
111
+ `powershell -Command "Expand-Archive -Path '${archivePath}' -DestinationPath '${destDir}' -Force"`,
112
+ { stdio: 'pipe' }
113
+ );
114
+ } else {
115
+ execSync(`unzip -o "${archivePath}" -d "${destDir}"`, { stdio: 'pipe' });
116
+ }
117
+ } else {
118
+ throw new Error(`Unknown archive format: ${archivePath}`);
119
+ }
120
+ }
121
+
122
+ /**
123
+ * Get the latest release version from GitHub
124
+ */
125
+ async function getLatestVersion() {
126
+ return new Promise((resolve, reject) => {
127
+ const options = {
128
+ hostname: 'api.github.com',
129
+ path: '/repos/EtaCassiopeia/rift/releases/latest',
130
+ headers: {
131
+ 'User-Agent': 'rift-node-installer',
132
+ },
133
+ };
134
+
135
+ https.get(options, (response) => {
136
+ if (response.statusCode === 302 || response.statusCode === 301) {
137
+ // Follow redirect
138
+ https.get(response.headers.location, handleResponse);
139
+ return;
140
+ }
141
+ handleResponse(response);
142
+
143
+ function handleResponse(res) {
144
+ let data = '';
145
+ res.on('data', (chunk) => (data += chunk));
146
+ res.on('end', () => {
147
+ try {
148
+ const json = JSON.parse(data);
149
+ resolve(json.tag_name);
150
+ } catch (e) {
151
+ reject(new Error('Failed to parse GitHub API response'));
152
+ }
153
+ });
154
+ }
155
+ }).on('error', reject);
156
+ });
157
+ }
158
+
159
+ async function main() {
160
+ const platformKey = `${process.platform}-${process.arch}`;
161
+ const target = PLATFORM_TO_TARGET[platformKey];
162
+ const archiveExt = ARCHIVE_EXT[platformKey];
163
+
164
+ // Check if binary already exists (e.g., user installed manually)
165
+ const existingBinary = path.join(BINARIES_DIR, BINARY_NAME);
166
+ if (fs.existsSync(existingBinary)) {
167
+ console.log(`Rift binary already exists at ${existingBinary}`);
168
+ return;
169
+ }
170
+
171
+ // Check if RIFT_BINARY_PATH is set (user has their own binary)
172
+ if (process.env.RIFT_BINARY_PATH) {
173
+ console.log(`Using existing binary from RIFT_BINARY_PATH: ${process.env.RIFT_BINARY_PATH}`);
174
+ return;
175
+ }
176
+
177
+ // Check if running in CI with RIFT_SKIP_BINARY_DOWNLOAD
178
+ if (process.env.RIFT_SKIP_BINARY_DOWNLOAD) {
179
+ console.log('Skipping binary download (RIFT_SKIP_BINARY_DOWNLOAD is set)');
180
+ return;
181
+ }
182
+
183
+ // Check if rift or mb is already in PATH
184
+ const binaryNames = ['rift', 'mb', 'rift-http-proxy'];
185
+ const whichCmd = process.platform === 'win32' ? 'where' : 'which';
186
+ for (const name of binaryNames) {
187
+ try {
188
+ execSync(`${whichCmd} ${name}`, { stdio: 'pipe' });
189
+ console.log(`Found '${name}' in PATH, skipping download`);
190
+ return;
191
+ } catch {
192
+ // Not found, continue
193
+ }
194
+ }
195
+
196
+ if (!target) {
197
+ console.warn(`\nUnsupported platform: ${platformKey}`);
198
+ console.warn('You can manually install the rift binary and set RIFT_BINARY_PATH');
199
+ console.warn('Visit: https://github.com/EtaCassiopeia/rift/releases\n');
200
+ // Don't fail the install - the package can still be used if binary is installed manually
201
+ return;
202
+ }
203
+
204
+ // Create binaries directory
205
+ if (!fs.existsSync(BINARIES_DIR)) {
206
+ fs.mkdirSync(BINARIES_DIR, { recursive: true });
207
+ }
208
+
209
+ // Determine version to download
210
+ let version = VERSION;
211
+ if (version === 'latest') {
212
+ try {
213
+ console.log('Fetching latest release version...');
214
+ version = await getLatestVersion();
215
+ console.log(`Latest version: ${version}`);
216
+ } catch (e) {
217
+ console.warn(`Failed to get latest version: ${e.message}`);
218
+ console.warn('Please set RIFT_VERSION environment variable or install manually');
219
+ return;
220
+ }
221
+ }
222
+
223
+ // Archive name format: rift-VERSION-TARGET.tar.gz (or .zip for Windows)
224
+ const archiveName = `rift-${version}-${target}.${archiveExt}`;
225
+ const url = `${BASE_URL}/${version}/${archiveName}`;
226
+ const archivePath = path.join(BINARIES_DIR, archiveName);
227
+
228
+ console.log(`\nDownloading Rift ${version} for ${platformKey}...`);
229
+ console.log(`URL: ${url}\n`);
230
+
231
+ try {
232
+ // Download the archive
233
+ await downloadFile(url, archivePath);
234
+
235
+ // Extract the archive
236
+ console.log('Extracting...');
237
+ extractArchive(archivePath, BINARIES_DIR);
238
+
239
+ // The archive contains a directory with the binary
240
+ // Move the binary to the binaries directory
241
+ const extractedDir = path.join(BINARIES_DIR, `rift-${version}-${target}`);
242
+ const extractedBinary = path.join(extractedDir, BINARY_NAME);
243
+ const finalBinaryPath = path.join(BINARIES_DIR, BINARY_NAME);
244
+
245
+ if (fs.existsSync(extractedBinary)) {
246
+ fs.renameSync(extractedBinary, finalBinaryPath);
247
+ // Clean up extracted directory
248
+ fs.rmSync(extractedDir, { recursive: true, force: true });
249
+ } else if (fs.existsSync(finalBinaryPath)) {
250
+ // Binary was extracted directly
251
+ } else {
252
+ throw new Error(`Binary not found after extraction`);
253
+ }
254
+
255
+ // Clean up archive file
256
+ try {
257
+ fs.unlinkSync(archivePath);
258
+ } catch {}
259
+
260
+ // Make binary executable (Unix only)
261
+ if (process.platform !== 'win32') {
262
+ fs.chmodSync(finalBinaryPath, 0o755);
263
+ }
264
+
265
+ console.log(`\nRift binary installed successfully!`);
266
+ console.log(`Location: ${finalBinaryPath}\n`);
267
+ } catch (error) {
268
+ console.error(`\nFailed to download Rift binary: ${error.message}`);
269
+ console.error('\nYou can manually install the rift binary:');
270
+ console.error(' 1. Download from: https://github.com/EtaCassiopeia/rift/releases');
271
+ console.error(' 2. Set RIFT_BINARY_PATH environment variable to the binary path');
272
+ console.error(' 3. Or place the binary in your system PATH\n');
273
+ // Don't fail the install - the package can still be used if binary is installed manually
274
+ }
275
+ }
276
+
277
+ main().catch((error) => {
278
+ console.error('Postinstall error:', error);
279
+ // Don't exit with error code - allow npm install to succeed
280
+ });
@@ -0,0 +1,2 @@
1
+ # This directory contains downloaded Rift binaries
2
+ # The actual binaries are downloaded by postinstall.js and are not committed to git
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Binary discovery and download utilities for Rift
3
+ */
4
+ /**
5
+ * Platform to binary filename mapping
6
+ */
7
+ export declare const PLATFORM_MAP: Record<string, string>;
8
+ /**
9
+ * Get the platform key for the current system
10
+ */
11
+ export declare function getPlatformKey(): string;
12
+ /**
13
+ * Find the Rift binary path
14
+ * Searches in order:
15
+ * 1. RIFT_BINARY_PATH environment variable
16
+ * 2. Local binaries directory (downloaded by postinstall)
17
+ * 3. System PATH (checks for rift-http-proxy, rift, and mb)
18
+ *
19
+ * @returns Path to the Rift binary
20
+ * @throws Error if binary not found
21
+ */
22
+ export declare function findBinary(): Promise<string>;
23
+ /**
24
+ * Download and install the Rift binary for the current platform
25
+ *
26
+ * @param version Version to download (default: 'latest')
27
+ * @param baseUrl Base URL for releases (default: GitHub releases)
28
+ */
29
+ export declare function downloadBinary(version?: string, baseUrl?: string): Promise<string>;
30
+ /**
31
+ * Check if the binary is already installed
32
+ */
33
+ export declare function isBinaryInstalled(): boolean;
34
+ /**
35
+ * Get the installed binary version
36
+ */
37
+ export declare function getBinaryVersion(): Promise<string | null>;
38
+ //# sourceMappingURL=binary.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"binary.d.ts","sourceRoot":"","sources":["../src/binary.ts"],"names":[],"mappings":"AAAA;;GAEG;AAsBH;;GAEG;AACH,eAAO,MAAM,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAM/C,CAAC;AAEF;;GAEG;AACH,wBAAgB,cAAc,IAAI,MAAM,CAEvC;AAED;;;;;;;;;GASG;AACH,wBAAsB,UAAU,IAAI,OAAO,CAAC,MAAM,CAAC,CA2ClD;AA0FD;;;;;GAKG;AACH,wBAAsB,cAAc,CAClC,OAAO,GAAE,MAAiB,EAC1B,OAAO,GAAE,MAAkE,GAC1E,OAAO,CAAC,MAAM,CAAC,CAiDjB;AAED;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,OAAO,CAO3C;AAED;;GAEG;AACH,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAW/D"}
package/dist/binary.js ADDED
@@ -0,0 +1,239 @@
1
+ /**
2
+ * Binary discovery and download utilities for Rift
3
+ */
4
+ import { execSync } from 'child_process';
5
+ import fs from 'fs';
6
+ import https from 'https';
7
+ import path from 'path';
8
+ import { fileURLToPath } from 'url';
9
+ const __filename = fileURLToPath(import.meta.url);
10
+ const __dirname = path.dirname(__filename);
11
+ // Binary names in order of preference
12
+ // - rift-http-proxy: The original Cargo binary name
13
+ // - rift: The name used by install-local.sh
14
+ // - mb: Mountebank compatibility alias
15
+ const BINARY_NAMES = process.platform === 'win32'
16
+ ? ['rift-http-proxy.exe', 'rift.exe', 'mb.exe']
17
+ : ['rift-http-proxy', 'rift', 'mb'];
18
+ const BINARY_NAME = BINARY_NAMES[0];
19
+ const BINARIES_DIR = path.join(__dirname, '..', 'binaries');
20
+ /**
21
+ * Platform to binary filename mapping
22
+ */
23
+ export const PLATFORM_MAP = {
24
+ 'darwin-x64': 'rift-http-proxy-x86_64-apple-darwin.tar.gz',
25
+ 'darwin-arm64': 'rift-http-proxy-aarch64-apple-darwin.tar.gz',
26
+ 'linux-x64': 'rift-http-proxy-x86_64-unknown-linux-gnu.tar.gz',
27
+ 'linux-arm64': 'rift-http-proxy-aarch64-unknown-linux-gnu.tar.gz',
28
+ 'win32-x64': 'rift-http-proxy-x86_64-pc-windows-msvc.zip',
29
+ };
30
+ /**
31
+ * Get the platform key for the current system
32
+ */
33
+ export function getPlatformKey() {
34
+ return `${process.platform}-${process.arch}`;
35
+ }
36
+ /**
37
+ * Find the Rift binary path
38
+ * Searches in order:
39
+ * 1. RIFT_BINARY_PATH environment variable
40
+ * 2. Local binaries directory (downloaded by postinstall)
41
+ * 3. System PATH (checks for rift-http-proxy, rift, and mb)
42
+ *
43
+ * @returns Path to the Rift binary
44
+ * @throws Error if binary not found
45
+ */
46
+ export async function findBinary() {
47
+ // 1. Check RIFT_BINARY_PATH environment variable
48
+ if (process.env.RIFT_BINARY_PATH) {
49
+ const envPath = process.env.RIFT_BINARY_PATH;
50
+ if (fs.existsSync(envPath)) {
51
+ return envPath;
52
+ }
53
+ console.warn(`RIFT_BINARY_PATH set but file not found: ${envPath}`);
54
+ }
55
+ // 2. Check local binaries directory for any of the binary names
56
+ for (const name of BINARY_NAMES) {
57
+ const localBin = path.join(BINARIES_DIR, name);
58
+ if (fs.existsSync(localBin)) {
59
+ return localBin;
60
+ }
61
+ }
62
+ // 3. Check system PATH for any of the binary names
63
+ const whichCmd = process.platform === 'win32' ? 'where' : 'which';
64
+ for (const name of BINARY_NAMES) {
65
+ try {
66
+ const result = execSync(`${whichCmd} ${name}`, {
67
+ encoding: 'utf8',
68
+ stdio: ['pipe', 'pipe', 'pipe'],
69
+ });
70
+ const binPath = result.trim().split('\n')[0];
71
+ if (binPath && fs.existsSync(binPath)) {
72
+ return binPath;
73
+ }
74
+ }
75
+ catch {
76
+ // Not found, try next name
77
+ }
78
+ }
79
+ throw new Error(`Rift binary not found. Install it via one of:\n` +
80
+ ` 1. Run './scripts/install-local.sh' from the Rift repo\n` +
81
+ ` 2. Run 'npm install' again (postinstall will download)\n` +
82
+ ` 3. Set RIFT_BINARY_PATH environment variable\n` +
83
+ ` 4. Install 'rift' or 'rift-http-proxy' to your system PATH\n\n` +
84
+ `For manual installation, visit: https://github.com/EtaCassiopeia/rift/releases`);
85
+ }
86
+ /**
87
+ * Download a file from URL to destination
88
+ */
89
+ async function downloadFile(url, dest) {
90
+ return new Promise((resolve, reject) => {
91
+ const file = fs.createWriteStream(dest);
92
+ const request = https.get(url, (response) => {
93
+ // Handle redirects
94
+ if (response.statusCode === 301 || response.statusCode === 302) {
95
+ const redirectUrl = response.headers.location;
96
+ if (redirectUrl) {
97
+ file.close();
98
+ fs.unlinkSync(dest);
99
+ downloadFile(redirectUrl, dest).then(resolve).catch(reject);
100
+ return;
101
+ }
102
+ }
103
+ if (response.statusCode !== 200) {
104
+ file.close();
105
+ fs.unlinkSync(dest);
106
+ reject(new Error(`Failed to download: HTTP ${response.statusCode}`));
107
+ return;
108
+ }
109
+ response.pipe(file);
110
+ file.on('finish', () => {
111
+ file.close();
112
+ resolve();
113
+ });
114
+ });
115
+ request.on('error', (err) => {
116
+ file.close();
117
+ fs.unlinkSync(dest);
118
+ reject(err);
119
+ });
120
+ file.on('error', (err) => {
121
+ file.close();
122
+ fs.unlinkSync(dest);
123
+ reject(err);
124
+ });
125
+ });
126
+ }
127
+ /**
128
+ * Extract a tar.gz file
129
+ */
130
+ async function extractTarGz(archivePath, destDir) {
131
+ // Use tar command for simplicity (available on macOS, Linux, and Git Bash on Windows)
132
+ try {
133
+ execSync(`tar -xzf "${archivePath}" -C "${destDir}"`, {
134
+ stdio: 'pipe',
135
+ });
136
+ }
137
+ catch (error) {
138
+ throw new Error(`Failed to extract archive: ${error}`);
139
+ }
140
+ }
141
+ /**
142
+ * Extract a zip file (for Windows)
143
+ */
144
+ async function extractZip(archivePath, destDir) {
145
+ // Use PowerShell on Windows
146
+ if (process.platform === 'win32') {
147
+ try {
148
+ execSync(`powershell -Command "Expand-Archive -Path '${archivePath}' -DestinationPath '${destDir}' -Force"`, { stdio: 'pipe' });
149
+ }
150
+ catch (error) {
151
+ throw new Error(`Failed to extract zip: ${error}`);
152
+ }
153
+ }
154
+ else {
155
+ // Use unzip on Unix systems
156
+ try {
157
+ execSync(`unzip -o "${archivePath}" -d "${destDir}"`, {
158
+ stdio: 'pipe',
159
+ });
160
+ }
161
+ catch (error) {
162
+ throw new Error(`Failed to extract zip: ${error}`);
163
+ }
164
+ }
165
+ }
166
+ /**
167
+ * Download and install the Rift binary for the current platform
168
+ *
169
+ * @param version Version to download (default: 'latest')
170
+ * @param baseUrl Base URL for releases (default: GitHub releases)
171
+ */
172
+ export async function downloadBinary(version = 'latest', baseUrl = 'https://github.com/EtaCassiopeia/rift/releases/download') {
173
+ const platformKey = getPlatformKey();
174
+ const filename = PLATFORM_MAP[platformKey];
175
+ if (!filename) {
176
+ throw new Error(`Unsupported platform: ${platformKey}\n` +
177
+ `You can manually install the rift-http-proxy binary and set RIFT_BINARY_PATH`);
178
+ }
179
+ // Create binaries directory if it doesn't exist
180
+ if (!fs.existsSync(BINARIES_DIR)) {
181
+ fs.mkdirSync(BINARIES_DIR, { recursive: true });
182
+ }
183
+ const url = `${baseUrl}/${version}/${filename}`;
184
+ const archivePath = path.join(BINARIES_DIR, filename);
185
+ const binaryPath = path.join(BINARIES_DIR, BINARY_NAME);
186
+ console.log(`Downloading Rift binary for ${platformKey}...`);
187
+ console.log(`URL: ${url}`);
188
+ // Download the archive
189
+ await downloadFile(url, archivePath);
190
+ // Extract the archive
191
+ console.log('Extracting...');
192
+ if (filename.endsWith('.tar.gz')) {
193
+ await extractTarGz(archivePath, BINARIES_DIR);
194
+ }
195
+ else if (filename.endsWith('.zip')) {
196
+ await extractZip(archivePath, BINARIES_DIR);
197
+ }
198
+ // Clean up archive
199
+ fs.unlinkSync(archivePath);
200
+ // Make binary executable (Unix only)
201
+ if (process.platform !== 'win32') {
202
+ fs.chmodSync(binaryPath, 0o755);
203
+ }
204
+ // Verify binary exists
205
+ if (!fs.existsSync(binaryPath)) {
206
+ throw new Error(`Binary not found after extraction: ${binaryPath}`);
207
+ }
208
+ console.log('Rift binary installed successfully!');
209
+ return binaryPath;
210
+ }
211
+ /**
212
+ * Check if the binary is already installed
213
+ */
214
+ export function isBinaryInstalled() {
215
+ try {
216
+ findBinary();
217
+ return true;
218
+ }
219
+ catch {
220
+ return false;
221
+ }
222
+ }
223
+ /**
224
+ * Get the installed binary version
225
+ */
226
+ export async function getBinaryVersion() {
227
+ try {
228
+ const binaryPath = await findBinary();
229
+ const result = execSync(`"${binaryPath}" --version`, {
230
+ encoding: 'utf8',
231
+ stdio: ['pipe', 'pipe', 'pipe'],
232
+ });
233
+ return result.trim();
234
+ }
235
+ catch {
236
+ return null;
237
+ }
238
+ }
239
+ //# sourceMappingURL=binary.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"binary.js","sourceRoot":"","sources":["../src/binary.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,57 @@
1
+ /**
2
+ * Rift Node.js bindings - Mountebank-compatible API
3
+ *
4
+ * This package provides a drop-in replacement for Mountebank's `mb.create()` API,
5
+ * allowing easy migration from Mountebank to Rift.
6
+ *
7
+ * @example
8
+ * ```javascript
9
+ * import rift from '@rift-vs/rift';
10
+ *
11
+ * const server = await rift.create({
12
+ * port: 2525,
13
+ * loglevel: 'debug',
14
+ * redis: {
15
+ * host: 'localhost',
16
+ * port: 6379,
17
+ * },
18
+ * });
19
+ *
20
+ * // Use the server...
21
+ *
22
+ * await server.close();
23
+ * ```
24
+ */
25
+ import type { CreateOptions, RiftServer } from './types.js';
26
+ export * from './types.js';
27
+ export { findBinary, downloadBinary, getBinaryVersion } from './binary.js';
28
+ /**
29
+ * Create a new Rift server instance
30
+ *
31
+ * This function provides Mountebank-compatible API for creating a server.
32
+ * It spawns the Rift binary as a child process and waits for it to be ready.
33
+ *
34
+ * @param options Server configuration options (compatible with Mountebank)
35
+ * @returns A RiftServer instance that can be used to interact with the server
36
+ *
37
+ * @example
38
+ * ```javascript
39
+ * // Basic usage
40
+ * const server = await create({ port: 2525 });
41
+ *
42
+ * // With Redis backend
43
+ * const server = await create({
44
+ * port: 2525,
45
+ * redis: { host: 'localhost', port: 6379 }
46
+ * });
47
+ *
48
+ * // Clean up
49
+ * await server.close();
50
+ * ```
51
+ */
52
+ export declare function create(options?: CreateOptions): Promise<RiftServer>;
53
+ declare const _default: {
54
+ create: typeof create;
55
+ };
56
+ export default _default;
57
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAMH,OAAO,KAAK,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAG5D,cAAc,YAAY,CAAC;AAC3B,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAwJ3E;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAsB,MAAM,CAAC,OAAO,GAAE,aAAkB,GAAG,OAAO,CAAC,UAAU,CAAC,CAoD7E;;;;AAGD,wBAA0B"}
package/dist/index.js ADDED
@@ -0,0 +1,224 @@
1
+ /**
2
+ * Rift Node.js bindings - Mountebank-compatible API
3
+ *
4
+ * This package provides a drop-in replacement for Mountebank's `mb.create()` API,
5
+ * allowing easy migration from Mountebank to Rift.
6
+ *
7
+ * @example
8
+ * ```javascript
9
+ * import rift from '@rift-vs/rift';
10
+ *
11
+ * const server = await rift.create({
12
+ * port: 2525,
13
+ * loglevel: 'debug',
14
+ * redis: {
15
+ * host: 'localhost',
16
+ * port: 6379,
17
+ * },
18
+ * });
19
+ *
20
+ * // Use the server...
21
+ *
22
+ * await server.close();
23
+ * ```
24
+ */
25
+ import { spawn } from 'child_process';
26
+ import { EventEmitter } from 'events';
27
+ import axios from 'axios';
28
+ import { findBinary } from './binary.js';
29
+ // Re-export types
30
+ export * from './types.js';
31
+ export { findBinary, downloadBinary, getBinaryVersion } from './binary.js';
32
+ const DEFAULT_PORT = 2525;
33
+ const DEFAULT_HOST = 'localhost';
34
+ const STARTUP_TIMEOUT_MS = 30000;
35
+ const HEALTH_CHECK_INTERVAL_MS = 100;
36
+ const SHUTDOWN_TIMEOUT_MS = 5000;
37
+ /**
38
+ * Internal implementation of RiftServer
39
+ */
40
+ class RiftServerImpl extends EventEmitter {
41
+ port;
42
+ host;
43
+ process;
44
+ closed = false;
45
+ constructor(port, host, process) {
46
+ super();
47
+ this.port = port;
48
+ this.host = host;
49
+ this.process = process;
50
+ // Forward process events
51
+ process.on('exit', (code, signal) => {
52
+ this.emit('exit', code, signal);
53
+ });
54
+ process.on('error', (error) => {
55
+ this.emit('error', error);
56
+ });
57
+ // Capture stdout/stderr for debugging
58
+ process.stdout?.on('data', (data) => {
59
+ this.emit('stdout', data.toString());
60
+ });
61
+ process.stderr?.on('data', (data) => {
62
+ this.emit('stderr', data.toString());
63
+ });
64
+ }
65
+ /**
66
+ * Gracefully close the server
67
+ */
68
+ async close() {
69
+ if (this.closed || !this.process) {
70
+ return;
71
+ }
72
+ this.closed = true;
73
+ return new Promise((resolve) => {
74
+ const timeout = setTimeout(() => {
75
+ // Force kill if graceful shutdown takes too long
76
+ this.process?.kill('SIGKILL');
77
+ resolve();
78
+ }, SHUTDOWN_TIMEOUT_MS);
79
+ this.process.once('exit', () => {
80
+ clearTimeout(timeout);
81
+ resolve();
82
+ });
83
+ // Send graceful shutdown signal
84
+ this.process.kill('SIGTERM');
85
+ });
86
+ }
87
+ }
88
+ /**
89
+ * Build CLI arguments from CreateOptions
90
+ */
91
+ function buildCliArgs(options) {
92
+ const args = [];
93
+ // Port
94
+ const port = options.port || DEFAULT_PORT;
95
+ args.push('--port', String(port));
96
+ // Host/bind address
97
+ if (options.host) {
98
+ args.push('--host', options.host);
99
+ }
100
+ // Logging configuration
101
+ if (options.loglevel) {
102
+ args.push('--loglevel', options.loglevel);
103
+ }
104
+ if (options.logfile) {
105
+ args.push('--log', options.logfile);
106
+ }
107
+ // Script injection support
108
+ if (options.allowInjection) {
109
+ args.push('--allow-injection');
110
+ }
111
+ // IP whitelist
112
+ if (options.ipWhitelist && options.ipWhitelist.length > 0) {
113
+ args.push('--ip-whitelist', options.ipWhitelist.join(','));
114
+ }
115
+ // Local only mode
116
+ if (options.host === 'localhost' || options.host === '127.0.0.1') {
117
+ // Don't add --local-only by default, let user control via ipWhitelist
118
+ }
119
+ // Note: Redis support for distributed state requires Rift native mode
120
+ // The Mountebank API mode doesn't support Redis directly
121
+ // For Redis support, use --rift-config with a native config file
122
+ return args;
123
+ }
124
+ /**
125
+ * Wait for the server to be ready by polling the health endpoint
126
+ */
127
+ async function waitForServer(host, port, timeoutMs) {
128
+ const startTime = Date.now();
129
+ const url = `http://${host}:${port}/`;
130
+ while (Date.now() - startTime < timeoutMs) {
131
+ try {
132
+ await axios.get(url, { timeout: 1000 });
133
+ // Server is responding
134
+ return;
135
+ }
136
+ catch (error) {
137
+ const axiosError = error;
138
+ // If we get any HTTP response, the server is up
139
+ if (axiosError.response) {
140
+ return;
141
+ }
142
+ // Otherwise, wait and retry
143
+ await sleep(HEALTH_CHECK_INTERVAL_MS);
144
+ }
145
+ }
146
+ throw new Error(`Rift server did not start within ${timeoutMs}ms`);
147
+ }
148
+ /**
149
+ * Sleep for a given number of milliseconds
150
+ */
151
+ function sleep(ms) {
152
+ return new Promise((resolve) => setTimeout(resolve, ms));
153
+ }
154
+ /**
155
+ * Create a new Rift server instance
156
+ *
157
+ * This function provides Mountebank-compatible API for creating a server.
158
+ * It spawns the Rift binary as a child process and waits for it to be ready.
159
+ *
160
+ * @param options Server configuration options (compatible with Mountebank)
161
+ * @returns A RiftServer instance that can be used to interact with the server
162
+ *
163
+ * @example
164
+ * ```javascript
165
+ * // Basic usage
166
+ * const server = await create({ port: 2525 });
167
+ *
168
+ * // With Redis backend
169
+ * const server = await create({
170
+ * port: 2525,
171
+ * redis: { host: 'localhost', port: 6379 }
172
+ * });
173
+ *
174
+ * // Clean up
175
+ * await server.close();
176
+ * ```
177
+ */
178
+ export async function create(options = {}) {
179
+ const port = options.port || DEFAULT_PORT;
180
+ const host = options.host || DEFAULT_HOST;
181
+ const args = buildCliArgs(options);
182
+ // Find the rift binary
183
+ const binaryPath = await findBinary();
184
+ // Spawn the process
185
+ const proc = spawn(binaryPath, args, {
186
+ stdio: ['ignore', 'pipe', 'pipe'],
187
+ detached: false,
188
+ });
189
+ // Capture stderr for error reporting
190
+ let stderr = '';
191
+ proc.stderr?.on('data', (data) => {
192
+ stderr += data.toString();
193
+ });
194
+ // Handle spawn errors
195
+ proc.on('error', (error) => {
196
+ throw new Error(`Failed to start Rift: ${error.message}`);
197
+ });
198
+ // Check for early exit
199
+ const earlyExitPromise = new Promise((_, reject) => {
200
+ proc.once('exit', (code, signal) => {
201
+ if (code !== null && code !== 0) {
202
+ reject(new Error(`Rift process exited with code ${code}.\nStderr: ${stderr || 'none'}`));
203
+ }
204
+ else if (signal) {
205
+ reject(new Error(`Rift process killed by signal ${signal}`));
206
+ }
207
+ });
208
+ });
209
+ // Wait for server to be ready, or handle early exit
210
+ try {
211
+ await Promise.race([
212
+ waitForServer(host, port, STARTUP_TIMEOUT_MS),
213
+ earlyExitPromise,
214
+ ]);
215
+ }
216
+ catch (error) {
217
+ proc.kill('SIGKILL');
218
+ throw error;
219
+ }
220
+ return new RiftServerImpl(port, host, proc);
221
+ }
222
+ // Default export for Mountebank compatibility
223
+ export default { create };
224
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,135 @@
1
+ /**
2
+ * TypeScript types for Rift Node.js bindings
3
+ * Provides Mountebank-compatible API types
4
+ */
5
+ /**
6
+ * Redis connection options for distributed state management
7
+ */
8
+ export interface RedisOptions {
9
+ /** Redis server hostname */
10
+ host: string;
11
+ /** Redis server port */
12
+ port: number;
13
+ /** Redis password (optional) */
14
+ password?: string;
15
+ /** Enable TLS for Redis connection */
16
+ tls_enabled?: boolean;
17
+ }
18
+ /**
19
+ * Options for creating a Rift server instance
20
+ * Compatible with Mountebank's mb.create() options
21
+ */
22
+ export interface CreateOptions {
23
+ /** Admin API port (default: 2525) */
24
+ port?: number;
25
+ /** Bind address (default: localhost) */
26
+ host?: string;
27
+ /** Log level: debug, info, warn, error */
28
+ loglevel?: 'debug' | 'info' | 'warn' | 'error';
29
+ /** Path to log file */
30
+ logfile?: string;
31
+ /** IP addresses allowed to connect (Mountebank compatibility) */
32
+ ipWhitelist?: string[];
33
+ /** Enable JavaScript injection via Rhai scripts */
34
+ allowInjection?: boolean;
35
+ /** Path to custom imposters repository module */
36
+ impostersRepository?: string;
37
+ /** Redis configuration for distributed state */
38
+ redis?: RedisOptions;
39
+ }
40
+ /**
41
+ * Represents a running Rift server instance
42
+ */
43
+ export interface RiftServer {
44
+ /** The port the server is listening on */
45
+ readonly port: number;
46
+ /** The host the server is bound to */
47
+ readonly host: string;
48
+ /** Gracefully close the server */
49
+ close(): Promise<void>;
50
+ }
51
+ /**
52
+ * Mountebank imposter stub predicate
53
+ */
54
+ export interface Predicate {
55
+ equals?: Record<string, unknown>;
56
+ deepEquals?: Record<string, unknown>;
57
+ contains?: Record<string, unknown>;
58
+ startsWith?: Record<string, unknown>;
59
+ endsWith?: Record<string, unknown>;
60
+ matches?: Record<string, unknown>;
61
+ exists?: Record<string, unknown>;
62
+ not?: Predicate;
63
+ or?: Predicate[];
64
+ and?: Predicate[];
65
+ inject?: string;
66
+ }
67
+ /**
68
+ * Mountebank imposter stub response
69
+ */
70
+ export interface Response {
71
+ is?: {
72
+ statusCode?: number;
73
+ headers?: Record<string, string>;
74
+ body?: string | Record<string, unknown>;
75
+ };
76
+ proxy?: {
77
+ to: string;
78
+ mode?: 'proxyOnce' | 'proxyAlways' | 'proxyTransparent';
79
+ predicateGenerators?: Array<{
80
+ matches: Record<string, unknown>;
81
+ }>;
82
+ };
83
+ inject?: string;
84
+ _behaviors?: {
85
+ wait?: number;
86
+ repeat?: number;
87
+ copy?: Array<{
88
+ from: string;
89
+ into: string;
90
+ using: {
91
+ method: string;
92
+ selector: string;
93
+ };
94
+ }>;
95
+ decorate?: string;
96
+ };
97
+ }
98
+ /**
99
+ * Mountebank imposter stub
100
+ */
101
+ export interface Stub {
102
+ predicates?: Predicate[];
103
+ responses: Response[];
104
+ }
105
+ /**
106
+ * Mountebank imposter configuration
107
+ */
108
+ export interface ImposterConfig {
109
+ port: number;
110
+ protocol: 'http' | 'https' | 'tcp' | 'smtp';
111
+ name?: string;
112
+ stubs?: Stub[];
113
+ defaultResponse?: Response;
114
+ allowCORS?: boolean;
115
+ recordRequests?: boolean;
116
+ }
117
+ /**
118
+ * Mountebank imposter with runtime state
119
+ */
120
+ export interface Imposter extends ImposterConfig {
121
+ numberOfRequests?: number;
122
+ requests?: unknown[];
123
+ }
124
+ /**
125
+ * Server information returned by GET /
126
+ */
127
+ export interface ServerInfo {
128
+ version: string;
129
+ imposters: Array<{
130
+ port: number;
131
+ protocol: string;
132
+ numberOfRequests?: number;
133
+ }>;
134
+ }
135
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/dist/types.js ADDED
@@ -0,0 +1,6 @@
1
+ /**
2
+ * TypeScript types for Rift Node.js bindings
3
+ * Provides Mountebank-compatible API types
4
+ */
5
+ export {};
6
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;GAGG"}
package/package.json ADDED
@@ -0,0 +1,71 @@
1
+ {
2
+ "name": "@rift-vs/rift",
3
+ "version": "0.1.0-RC1",
4
+ "description": "Mountebank-compatible Node.js bindings for Rift - A high-performance service virtualization proxy",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "type": "module",
8
+ "exports": {
9
+ ".": {
10
+ "import": "./dist/index.js",
11
+ "types": "./dist/index.d.ts"
12
+ }
13
+ },
14
+ "scripts": {
15
+ "build": "tsc",
16
+ "test": "node --experimental-vm-modules node_modules/jest/bin/jest.js",
17
+ "test:unit": "npm test -- --testPathPattern=test/unit",
18
+ "test:integration": "npm test -- --testPathPattern=test/integration",
19
+ "postinstall": "node bin/postinstall.js",
20
+ "prepublishOnly": "npm run build",
21
+ "lint": "eslint src test --ext .ts",
22
+ "typecheck": "tsc --noEmit"
23
+ },
24
+ "dependencies": {
25
+ "axios": "^1.6.0"
26
+ },
27
+ "devDependencies": {
28
+ "@types/jest": "^29.5.0",
29
+ "@types/node": "^20.10.0",
30
+ "@typescript-eslint/eslint-plugin": "^6.0.0",
31
+ "@typescript-eslint/parser": "^6.0.0",
32
+ "eslint": "^8.56.0",
33
+ "jest": "^29.7.0",
34
+ "ts-jest": "^29.1.0",
35
+ "typescript": "^5.3.0"
36
+ },
37
+ "engines": {
38
+ "node": ">=18.0.0"
39
+ },
40
+ "files": [
41
+ "dist",
42
+ "bin",
43
+ "binaries/.gitkeep"
44
+ ],
45
+ "keywords": [
46
+ "mountebank",
47
+ "mock",
48
+ "stub",
49
+ "test",
50
+ "double",
51
+ "chaos",
52
+ "engineering",
53
+ "rift",
54
+ "service-virtualization",
55
+ "api-mocking"
56
+ ],
57
+ "repository": {
58
+ "type": "git",
59
+ "url": "https://github.com/EtaCassiopeia/rift.git",
60
+ "directory": "packages/rift-node"
61
+ },
62
+ "bugs": {
63
+ "url": "https://github.com/EtaCassiopeia/rift/issues"
64
+ },
65
+ "homepage": "https://github.com/EtaCassiopeia/rift/tree/master/packages/rift-node#readme",
66
+ "license": "MIT",
67
+ "author": "Rift Contributors",
68
+ "publishConfig": {
69
+ "access": "public"
70
+ }
71
+ }