diffsurge 0.3.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 ADDED
@@ -0,0 +1,136 @@
1
+ # diffsurge
2
+
3
+ > Catch breaking API changes before your users do.
4
+
5
+ Diffsurge helps you detect breaking API changes before they reach production.
6
+
7
+ ## Install
8
+
9
+ ```bash
10
+ npm install -g diffsurge
11
+ ```
12
+
13
+ Or use Docker:
14
+
15
+ ```bash
16
+ docker run equixankit/diffsurge-cli --help
17
+ ```
18
+
19
+ ## Setup
20
+
21
+ 1. **Create an API key** in the [Diffsurge dashboard](https://app.diffsurge.com) → Settings → API Keys
22
+ 2. **Add it to your `.env` file** in your project root:
23
+
24
+ ```env
25
+ SURGE_API_KEY=tvc_live_your_key_here
26
+ SURGE_PROJECT_ID=your-project-uuid
27
+ ```
28
+
29
+ 3. **Verify it works:**
30
+
31
+ ```bash
32
+ surge whoami
33
+ ```
34
+
35
+ ## Commands
36
+
37
+ ### `surge whoami`
38
+
39
+ Verify your API key is valid and see account info:
40
+
41
+ ```bash
42
+ surge whoami
43
+ ```
44
+
45
+ ### `surge check`
46
+
47
+ Run API checks in your CI/CD pipeline:
48
+
49
+ ```bash
50
+ # Basic check — validates API key, fetches traffic & schema stats
51
+ surge check --project-id abc-123
52
+
53
+ # With local schema diff — detect breaking changes before deploy
54
+ surge check --project-id abc-123 --schema openapi.yaml --fail-on-breaking
55
+ ```
56
+
57
+ ### `surge diff`
58
+
59
+ Compare two JSON API responses:
60
+
61
+ ```bash
62
+ surge diff --old response-v1.json --new response-v2.json
63
+ ```
64
+
65
+ ### `surge schema diff`
66
+
67
+ Compare two OpenAPI/Swagger schema files and detect breaking changes:
68
+
69
+ ```bash
70
+ surge schema diff --old api-v1.yaml --new api-v2.yaml --fail-on-breaking
71
+ ```
72
+
73
+ ### `surge replay`
74
+
75
+ Replay captured traffic against a target server:
76
+
77
+ ```bash
78
+ surge replay --source captured.json --target http://localhost:8080
79
+ ```
80
+
81
+ ## CI/CD Integration
82
+
83
+ ### GitHub Actions
84
+
85
+ ```yaml
86
+ name: API Check
87
+ on: [push, pull_request]
88
+ jobs:
89
+ api-check:
90
+ runs-on: ubuntu-latest
91
+ steps:
92
+ - uses: actions/checkout@v4
93
+ - uses: actions/setup-node@v4
94
+ with:
95
+ node-version: 20
96
+ - run: npm install -g diffsurge
97
+ - run: surge check --project-id ${{ secrets.SURGE_PROJECT_ID }}
98
+ env:
99
+ SURGE_API_KEY: ${{ secrets.SURGE_API_KEY }}
100
+ ```
101
+
102
+ ### GitLab CI
103
+
104
+ ```yaml
105
+ api-check:
106
+ image: node:20
107
+ script:
108
+ - npm install -g diffsurge
109
+ - surge check --project-id $SURGE_PROJECT_ID
110
+ variables:
111
+ SURGE_API_KEY: $SURGE_API_KEY
112
+ ```
113
+
114
+ ## Environment Variables
115
+
116
+ | Variable | Description | Default |
117
+ |---|---|---|
118
+ | `SURGE_API_KEY` | Your API key (starts with `tvc_live_`) | — |
119
+ | `SURGE_API_URL` | API base URL | `https://api.diffsurge.com` |
120
+ | `SURGE_PROJECT_ID` | Default project ID | — |
121
+
122
+ All variables can also use the `TVC_` prefix (e.g., `TVC_API_KEY`) as a fallback.
123
+
124
+ ## Flags
125
+
126
+ All commands support these global flags:
127
+
128
+ ```
129
+ --api-key API key (overrides SURGE_API_KEY)
130
+ --api-url API base URL (overrides SURGE_API_URL)
131
+ --project-id Project ID (overrides SURGE_PROJECT_ID)
132
+ ```
133
+
134
+ ## License
135
+
136
+ MIT
package/bin/surge ADDED
@@ -0,0 +1,55 @@
1
+ #!/usr/bin/env node
2
+
3
+ const { execFileSync } = require("child_process");
4
+ const path = require("path");
5
+ const os = require("os");
6
+ const fs = require("fs");
7
+
8
+ const isWindows = os.platform() === "win32";
9
+ const binaryName = isWindows ? "surge.exe" : "surge";
10
+ const binaryPath = path.join(__dirname, binaryName);
11
+
12
+ // Load .env from the current working directory and merge into process.env
13
+ function loadDotEnv() {
14
+ const envPath = path.join(process.cwd(), ".env");
15
+ try {
16
+ const content = fs.readFileSync(envPath, "utf8");
17
+ for (const line of content.split("\n")) {
18
+ const trimmed = line.trim();
19
+ if (!trimmed || trimmed.startsWith("#")) continue;
20
+ const eqIdx = trimmed.indexOf("=");
21
+ if (eqIdx === -1) continue;
22
+ const key = trimmed.slice(0, eqIdx).trim();
23
+ let val = trimmed.slice(eqIdx + 1).trim();
24
+ // Remove surrounding quotes
25
+ if (
26
+ (val.startsWith('"') && val.endsWith('"')) ||
27
+ (val.startsWith("'") && val.endsWith("'"))
28
+ ) {
29
+ val = val.slice(1, -1);
30
+ }
31
+ // Only set if not already in env (real env vars take priority)
32
+ if (!(key in process.env)) {
33
+ process.env[key] = val;
34
+ }
35
+ }
36
+ } catch {
37
+ // .env file not found or unreadable — that's fine
38
+ }
39
+ }
40
+
41
+ loadDotEnv();
42
+
43
+ try {
44
+ execFileSync(binaryPath, process.argv.slice(2), {
45
+ stdio: "inherit",
46
+ env: process.env,
47
+ });
48
+ } catch (err) {
49
+ if (err.status !== undefined) {
50
+ process.exit(err.status);
51
+ }
52
+ console.error(`Failed to run surge: ${err.message}`);
53
+ console.error(`Run "npm rebuild diffsurge" to re-download the binary.`);
54
+ process.exit(1);
55
+ }
Binary file
Binary file
Binary file
Binary file
package/install.js ADDED
@@ -0,0 +1,68 @@
1
+ #!/usr/bin/env node
2
+
3
+ const os = require("os");
4
+ const fs = require("fs");
5
+ const path = require("path");
6
+ const zlib = require("zlib");
7
+
8
+ function getPlatformBinary() {
9
+ const platform = os.platform();
10
+ const arch = os.arch();
11
+
12
+ const mapping = {
13
+ "darwin-x64": "surge-darwin-amd64",
14
+ "darwin-arm64": "surge-darwin-arm64",
15
+ "linux-x64": "surge-linux-amd64",
16
+ "linux-arm64": "surge-linux-arm64",
17
+ "win32-x64": "surge-windows-amd64.exe",
18
+ };
19
+
20
+ const key = `${platform}-${arch}`;
21
+ const binary = mapping[key];
22
+
23
+ if (!binary) {
24
+ console.error(
25
+ `Unsupported platform: ${platform}-${arch}\n` +
26
+ `Supported: ${Object.keys(mapping).join(", ")}\n` +
27
+ `You can use Docker instead: docker run equixankit/diffsurge-cli`
28
+ );
29
+ process.exit(1);
30
+ }
31
+
32
+ return binary;
33
+ }
34
+
35
+ function main() {
36
+ const binaryName = getPlatformBinary();
37
+ const isWindows = os.platform() === "win32";
38
+ const binDir = path.join(__dirname, "bin");
39
+ const dest = path.join(binDir, isWindows ? "surge.exe" : "surge");
40
+
41
+ if (fs.existsSync(dest)) {
42
+ return;
43
+ }
44
+
45
+ const gzPath = path.join(__dirname, "binaries", `${binaryName}.gz`);
46
+
47
+ if (!fs.existsSync(gzPath)) {
48
+ console.error(`Binary not found: ${gzPath}`);
49
+ console.error(`Use Docker instead: docker run equixankit/diffsurge-cli`);
50
+ process.exit(1);
51
+ }
52
+
53
+ fs.mkdirSync(binDir, { recursive: true });
54
+
55
+ console.log(`Installing surge for ${os.platform()}-${os.arch()}...`);
56
+
57
+ const compressed = fs.readFileSync(gzPath);
58
+ const decompressed = zlib.gunzipSync(compressed);
59
+ fs.writeFileSync(dest, decompressed);
60
+
61
+ if (!isWindows) {
62
+ fs.chmodSync(dest, 0o755);
63
+ }
64
+
65
+ console.log("surge installed successfully!");
66
+ }
67
+
68
+ main();
package/package.json ADDED
@@ -0,0 +1,34 @@
1
+ {
2
+ "name": "diffsurge",
3
+ "version": "0.3.0",
4
+ "description": "Diffsurge CLI — API traffic capture, diff, schema comparison, replay, and CI/CD checks with API key auth",
5
+ "keywords": [
6
+ "api",
7
+ "traffic",
8
+ "diff",
9
+ "schema",
10
+ "replay",
11
+ "testing",
12
+ "proxy",
13
+ "cli"
14
+ ],
15
+ "homepage": "https://github.com/ankit12301/tvc#readme",
16
+ "bugs": {
17
+ "url": "https://github.com/ankit12301/tvc/issues"
18
+ },
19
+ "repository": {
20
+ "type": "git",
21
+ "url": "https://github.com/ankit12301/tvc.git"
22
+ },
23
+ "license": "MIT",
24
+ "author": "Ankit Mahopatra",
25
+ "bin": {
26
+ "surge": "bin/surge"
27
+ },
28
+ "scripts": {
29
+ "postinstall": "node install.js"
30
+ },
31
+ "engines": {
32
+ "node": ">=16"
33
+ }
34
+ }