codmir 0.3.0 → 0.3.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/README.md +4 -4
- package/dist/cli/index.js +53 -87
- package/dist/cli/index.mjs +53 -87
- package/package.json +11 -6
- package/runkit-example.js +36 -0
package/README.md
CHANGED
|
@@ -27,21 +27,21 @@ npm install codmir
|
|
|
27
27
|
or with pnpm:
|
|
28
28
|
|
|
29
29
|
```bash
|
|
30
|
-
pnpm add
|
|
30
|
+
pnpm add codmir
|
|
31
31
|
```
|
|
32
32
|
|
|
33
33
|
or with yarn:
|
|
34
34
|
|
|
35
35
|
```bash
|
|
36
|
-
yarn add
|
|
36
|
+
yarn add codmir
|
|
37
37
|
```
|
|
38
38
|
|
|
39
39
|
### As a CLI (Global)
|
|
40
40
|
|
|
41
41
|
```bash
|
|
42
|
-
npm install -g
|
|
42
|
+
npm install -g codmir
|
|
43
43
|
# or
|
|
44
|
-
pnpm add -g
|
|
44
|
+
pnpm add -g codmir
|
|
45
45
|
```
|
|
46
46
|
|
|
47
47
|
Then authenticate and link your project:
|
package/dist/cli/index.js
CHANGED
|
@@ -27,8 +27,8 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
27
27
|
var import_commander = require("commander");
|
|
28
28
|
|
|
29
29
|
// src/cli/utils/auth.ts
|
|
30
|
-
var import_http = __toESM(require("http"));
|
|
31
30
|
var import_open = __toESM(require("open"));
|
|
31
|
+
var readline = __toESM(require("readline"));
|
|
32
32
|
|
|
33
33
|
// src/cli/utils/config.ts
|
|
34
34
|
var import_fs = __toESM(require("fs"));
|
|
@@ -101,96 +101,62 @@ function isAuthenticated() {
|
|
|
101
101
|
}
|
|
102
102
|
|
|
103
103
|
// src/cli/utils/auth.ts
|
|
104
|
-
|
|
105
|
-
return new Promise((resolve
|
|
106
|
-
const
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
const token = url.searchParams.get("token");
|
|
110
|
-
const error = url.searchParams.get("error");
|
|
111
|
-
if (error) {
|
|
112
|
-
res.writeHead(200, { "Content-Type": "text/html" });
|
|
113
|
-
res.end(`
|
|
114
|
-
<html>
|
|
115
|
-
<body style="font-family: system-ui; padding: 40px; text-align: center;">
|
|
116
|
-
<h1>\u274C Authentication Failed</h1>
|
|
117
|
-
<p>${error}</p>
|
|
118
|
-
<p>You can close this window.</p>
|
|
119
|
-
</body>
|
|
120
|
-
</html>
|
|
121
|
-
`);
|
|
122
|
-
server.close();
|
|
123
|
-
reject(new Error(error));
|
|
124
|
-
return;
|
|
125
|
-
}
|
|
126
|
-
if (!token) {
|
|
127
|
-
res.writeHead(400, { "Content-Type": "text/html" });
|
|
128
|
-
res.end(`
|
|
129
|
-
<html>
|
|
130
|
-
<body style="font-family: system-ui; padding: 40px; text-align: center;">
|
|
131
|
-
<h1>\u274C No token received</h1>
|
|
132
|
-
<p>You can close this window.</p>
|
|
133
|
-
</body>
|
|
134
|
-
</html>
|
|
135
|
-
`);
|
|
136
|
-
server.close();
|
|
137
|
-
reject(new Error("No token received"));
|
|
138
|
-
return;
|
|
139
|
-
}
|
|
140
|
-
res.writeHead(200, { "Content-Type": "text/html" });
|
|
141
|
-
res.end(`
|
|
142
|
-
<html>
|
|
143
|
-
<body style="font-family: system-ui; padding: 40px; text-align: center;">
|
|
144
|
-
<h1>\u2705 Authentication Successful!</h1>
|
|
145
|
-
<p>You can now close this window and return to your terminal.</p>
|
|
146
|
-
<script>setTimeout(() => window.close(), 2000);</script>
|
|
147
|
-
</body>
|
|
148
|
-
</html>
|
|
149
|
-
`);
|
|
150
|
-
try {
|
|
151
|
-
const userResponse = await fetch(`${baseUrl}/api/user/profile`, {
|
|
152
|
-
headers: {
|
|
153
|
-
"Authorization": `Bearer ${token}`
|
|
154
|
-
}
|
|
155
|
-
});
|
|
156
|
-
if (!userResponse.ok) {
|
|
157
|
-
throw new Error("Failed to fetch user info");
|
|
158
|
-
}
|
|
159
|
-
const user = await userResponse.json();
|
|
160
|
-
server.close();
|
|
161
|
-
resolve({
|
|
162
|
-
token,
|
|
163
|
-
user: {
|
|
164
|
-
id: user.id,
|
|
165
|
-
email: user.email,
|
|
166
|
-
name: user.name
|
|
167
|
-
}
|
|
168
|
-
});
|
|
169
|
-
} catch (error2) {
|
|
170
|
-
server.close();
|
|
171
|
-
reject(error2);
|
|
172
|
-
}
|
|
173
|
-
} else {
|
|
174
|
-
res.writeHead(404);
|
|
175
|
-
res.end("Not found");
|
|
176
|
-
}
|
|
104
|
+
function promptForToken() {
|
|
105
|
+
return new Promise((resolve) => {
|
|
106
|
+
const rl = readline.createInterface({
|
|
107
|
+
input: process.stdin,
|
|
108
|
+
output: process.stdout
|
|
177
109
|
});
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
console.log("\u{1F510} Opening browser for authentication...");
|
|
182
|
-
console.log(` If browser doesn't open, visit: ${authUrl}`);
|
|
183
|
-
(0, import_open.default)(authUrl).catch(() => {
|
|
184
|
-
console.log("\n\u26A0\uFE0F Could not open browser automatically.");
|
|
185
|
-
console.log(` Please visit: ${authUrl}`);
|
|
186
|
-
});
|
|
110
|
+
rl.question("\nPaste your authentication token: ", (token) => {
|
|
111
|
+
rl.close();
|
|
112
|
+
resolve(token.trim());
|
|
187
113
|
});
|
|
188
|
-
setTimeout(() => {
|
|
189
|
-
server.close();
|
|
190
|
-
reject(new Error("Authentication timeout"));
|
|
191
|
-
}, 5 * 60 * 1e3);
|
|
192
114
|
});
|
|
193
115
|
}
|
|
116
|
+
async function startOAuthFlow(baseUrl = "https://codmir.com") {
|
|
117
|
+
const authUrl = `${baseUrl}/cli/auth`;
|
|
118
|
+
console.log("\u{1F510} Opening browser for authentication...");
|
|
119
|
+
console.log(` If browser doesn't open, visit: ${authUrl}`);
|
|
120
|
+
console.log();
|
|
121
|
+
try {
|
|
122
|
+
await (0, import_open.default)(authUrl);
|
|
123
|
+
} catch {
|
|
124
|
+
console.log("\u26A0\uFE0F Could not open browser automatically.");
|
|
125
|
+
console.log(` Please visit: ${authUrl}`);
|
|
126
|
+
console.log();
|
|
127
|
+
}
|
|
128
|
+
console.log("\u{1F4CB} After authenticating in your browser:");
|
|
129
|
+
console.log(" 1. Copy the token displayed");
|
|
130
|
+
console.log(" 2. Return here and paste it below");
|
|
131
|
+
console.log();
|
|
132
|
+
const token = await promptForToken();
|
|
133
|
+
if (!token) {
|
|
134
|
+
throw new Error("No token provided");
|
|
135
|
+
}
|
|
136
|
+
try {
|
|
137
|
+
const userResponse = await fetch(`${baseUrl}/api/user/profile`, {
|
|
138
|
+
headers: {
|
|
139
|
+
"X-API-Key": token
|
|
140
|
+
}
|
|
141
|
+
});
|
|
142
|
+
if (!userResponse.ok) {
|
|
143
|
+
throw new Error("Invalid token or authentication failed");
|
|
144
|
+
}
|
|
145
|
+
const user = await userResponse.json();
|
|
146
|
+
return {
|
|
147
|
+
token,
|
|
148
|
+
user: {
|
|
149
|
+
id: user.id,
|
|
150
|
+
email: user.email,
|
|
151
|
+
name: user.name
|
|
152
|
+
}
|
|
153
|
+
};
|
|
154
|
+
} catch (error) {
|
|
155
|
+
throw new Error(
|
|
156
|
+
error instanceof Error ? error.message : "Failed to validate token"
|
|
157
|
+
);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
194
160
|
async function authenticateWithToken(token, baseUrl = "https://codmir.com") {
|
|
195
161
|
const response = await fetch(`${baseUrl}/api/user/profile`, {
|
|
196
162
|
headers: {
|
package/dist/cli/index.mjs
CHANGED
|
@@ -7,8 +7,8 @@ import {
|
|
|
7
7
|
import { Command } from "commander";
|
|
8
8
|
|
|
9
9
|
// src/cli/utils/auth.ts
|
|
10
|
-
import http from "http";
|
|
11
10
|
import open from "open";
|
|
11
|
+
import * as readline from "readline";
|
|
12
12
|
|
|
13
13
|
// src/cli/utils/config.ts
|
|
14
14
|
import fs from "fs";
|
|
@@ -81,96 +81,62 @@ function isAuthenticated() {
|
|
|
81
81
|
}
|
|
82
82
|
|
|
83
83
|
// src/cli/utils/auth.ts
|
|
84
|
-
|
|
85
|
-
return new Promise((resolve
|
|
86
|
-
const
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
const token = url.searchParams.get("token");
|
|
90
|
-
const error = url.searchParams.get("error");
|
|
91
|
-
if (error) {
|
|
92
|
-
res.writeHead(200, { "Content-Type": "text/html" });
|
|
93
|
-
res.end(`
|
|
94
|
-
<html>
|
|
95
|
-
<body style="font-family: system-ui; padding: 40px; text-align: center;">
|
|
96
|
-
<h1>\u274C Authentication Failed</h1>
|
|
97
|
-
<p>${error}</p>
|
|
98
|
-
<p>You can close this window.</p>
|
|
99
|
-
</body>
|
|
100
|
-
</html>
|
|
101
|
-
`);
|
|
102
|
-
server.close();
|
|
103
|
-
reject(new Error(error));
|
|
104
|
-
return;
|
|
105
|
-
}
|
|
106
|
-
if (!token) {
|
|
107
|
-
res.writeHead(400, { "Content-Type": "text/html" });
|
|
108
|
-
res.end(`
|
|
109
|
-
<html>
|
|
110
|
-
<body style="font-family: system-ui; padding: 40px; text-align: center;">
|
|
111
|
-
<h1>\u274C No token received</h1>
|
|
112
|
-
<p>You can close this window.</p>
|
|
113
|
-
</body>
|
|
114
|
-
</html>
|
|
115
|
-
`);
|
|
116
|
-
server.close();
|
|
117
|
-
reject(new Error("No token received"));
|
|
118
|
-
return;
|
|
119
|
-
}
|
|
120
|
-
res.writeHead(200, { "Content-Type": "text/html" });
|
|
121
|
-
res.end(`
|
|
122
|
-
<html>
|
|
123
|
-
<body style="font-family: system-ui; padding: 40px; text-align: center;">
|
|
124
|
-
<h1>\u2705 Authentication Successful!</h1>
|
|
125
|
-
<p>You can now close this window and return to your terminal.</p>
|
|
126
|
-
<script>setTimeout(() => window.close(), 2000);</script>
|
|
127
|
-
</body>
|
|
128
|
-
</html>
|
|
129
|
-
`);
|
|
130
|
-
try {
|
|
131
|
-
const userResponse = await fetch(`${baseUrl}/api/user/profile`, {
|
|
132
|
-
headers: {
|
|
133
|
-
"Authorization": `Bearer ${token}`
|
|
134
|
-
}
|
|
135
|
-
});
|
|
136
|
-
if (!userResponse.ok) {
|
|
137
|
-
throw new Error("Failed to fetch user info");
|
|
138
|
-
}
|
|
139
|
-
const user = await userResponse.json();
|
|
140
|
-
server.close();
|
|
141
|
-
resolve({
|
|
142
|
-
token,
|
|
143
|
-
user: {
|
|
144
|
-
id: user.id,
|
|
145
|
-
email: user.email,
|
|
146
|
-
name: user.name
|
|
147
|
-
}
|
|
148
|
-
});
|
|
149
|
-
} catch (error2) {
|
|
150
|
-
server.close();
|
|
151
|
-
reject(error2);
|
|
152
|
-
}
|
|
153
|
-
} else {
|
|
154
|
-
res.writeHead(404);
|
|
155
|
-
res.end("Not found");
|
|
156
|
-
}
|
|
84
|
+
function promptForToken() {
|
|
85
|
+
return new Promise((resolve) => {
|
|
86
|
+
const rl = readline.createInterface({
|
|
87
|
+
input: process.stdin,
|
|
88
|
+
output: process.stdout
|
|
157
89
|
});
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
console.log("\u{1F510} Opening browser for authentication...");
|
|
162
|
-
console.log(` If browser doesn't open, visit: ${authUrl}`);
|
|
163
|
-
open(authUrl).catch(() => {
|
|
164
|
-
console.log("\n\u26A0\uFE0F Could not open browser automatically.");
|
|
165
|
-
console.log(` Please visit: ${authUrl}`);
|
|
166
|
-
});
|
|
90
|
+
rl.question("\nPaste your authentication token: ", (token) => {
|
|
91
|
+
rl.close();
|
|
92
|
+
resolve(token.trim());
|
|
167
93
|
});
|
|
168
|
-
setTimeout(() => {
|
|
169
|
-
server.close();
|
|
170
|
-
reject(new Error("Authentication timeout"));
|
|
171
|
-
}, 5 * 60 * 1e3);
|
|
172
94
|
});
|
|
173
95
|
}
|
|
96
|
+
async function startOAuthFlow(baseUrl = "https://codmir.com") {
|
|
97
|
+
const authUrl = `${baseUrl}/cli/auth`;
|
|
98
|
+
console.log("\u{1F510} Opening browser for authentication...");
|
|
99
|
+
console.log(` If browser doesn't open, visit: ${authUrl}`);
|
|
100
|
+
console.log();
|
|
101
|
+
try {
|
|
102
|
+
await open(authUrl);
|
|
103
|
+
} catch {
|
|
104
|
+
console.log("\u26A0\uFE0F Could not open browser automatically.");
|
|
105
|
+
console.log(` Please visit: ${authUrl}`);
|
|
106
|
+
console.log();
|
|
107
|
+
}
|
|
108
|
+
console.log("\u{1F4CB} After authenticating in your browser:");
|
|
109
|
+
console.log(" 1. Copy the token displayed");
|
|
110
|
+
console.log(" 2. Return here and paste it below");
|
|
111
|
+
console.log();
|
|
112
|
+
const token = await promptForToken();
|
|
113
|
+
if (!token) {
|
|
114
|
+
throw new Error("No token provided");
|
|
115
|
+
}
|
|
116
|
+
try {
|
|
117
|
+
const userResponse = await fetch(`${baseUrl}/api/user/profile`, {
|
|
118
|
+
headers: {
|
|
119
|
+
"X-API-Key": token
|
|
120
|
+
}
|
|
121
|
+
});
|
|
122
|
+
if (!userResponse.ok) {
|
|
123
|
+
throw new Error("Invalid token or authentication failed");
|
|
124
|
+
}
|
|
125
|
+
const user = await userResponse.json();
|
|
126
|
+
return {
|
|
127
|
+
token,
|
|
128
|
+
user: {
|
|
129
|
+
id: user.id,
|
|
130
|
+
email: user.email,
|
|
131
|
+
name: user.name
|
|
132
|
+
}
|
|
133
|
+
};
|
|
134
|
+
} catch (error) {
|
|
135
|
+
throw new Error(
|
|
136
|
+
error instanceof Error ? error.message : "Failed to validate token"
|
|
137
|
+
);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
174
140
|
async function authenticateWithToken(token, baseUrl = "https://codmir.com") {
|
|
175
141
|
const response = await fetch(`${baseUrl}/api/user/profile`, {
|
|
176
142
|
headers: {
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "codmir",
|
|
3
|
-
"version": "0.3.
|
|
4
|
-
"description": "TypeScript SDK for codmir API - the AI
|
|
3
|
+
"version": "0.3.2",
|
|
4
|
+
"description": "TypeScript SDK for codmir API - the codmir AI prevents wasted engineering time",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.mjs",
|
|
7
7
|
"types": "dist/index.d.ts",
|
|
@@ -17,7 +17,9 @@
|
|
|
17
17
|
},
|
|
18
18
|
"files": [
|
|
19
19
|
"dist",
|
|
20
|
-
"README.md"
|
|
20
|
+
"README.md",
|
|
21
|
+
"LICENSE",
|
|
22
|
+
"runkit-example.js"
|
|
21
23
|
],
|
|
22
24
|
"scripts": {
|
|
23
25
|
"build": "tsup src/index.ts src/cli/index.ts --format cjs,esm --dts --clean",
|
|
@@ -38,13 +40,16 @@
|
|
|
38
40
|
"license": "MIT",
|
|
39
41
|
"repository": {
|
|
40
42
|
"type": "git",
|
|
41
|
-
"url": "https://github.com/
|
|
42
|
-
"directory": "
|
|
43
|
+
"url": "https://github.com/jobrayan/codmir.git",
|
|
44
|
+
"directory": "packages/codmir-sdk"
|
|
43
45
|
},
|
|
44
46
|
"bugs": {
|
|
45
|
-
"url": "https://github.com/
|
|
47
|
+
"url": "https://github.com/jobrayan/codmir/issues"
|
|
46
48
|
},
|
|
47
49
|
"homepage": "https://codmir.com",
|
|
50
|
+
"runkit": {
|
|
51
|
+
"example": "runkit-example.js"
|
|
52
|
+
},
|
|
48
53
|
"devDependencies": {
|
|
49
54
|
"@semantic-release/changelog": "^6.0.3",
|
|
50
55
|
"@semantic-release/commit-analyzer": "^13.0.0",
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
// RunKit example for codmir package
|
|
2
|
+
// This will appear as an interactive demo on npm
|
|
3
|
+
|
|
4
|
+
const { CodmirClient } = require('codmir');
|
|
5
|
+
|
|
6
|
+
// Initialize the client
|
|
7
|
+
const client = new CodmirClient({
|
|
8
|
+
apiKey: 'demo-api-key', // Replace with your API key
|
|
9
|
+
baseUrl: 'https://codmir.com'
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
// Example: List projects (will fail without valid API key)
|
|
13
|
+
async function demo() {
|
|
14
|
+
try {
|
|
15
|
+
console.log('codmir SDK - Interactive Demo');
|
|
16
|
+
console.log('==============================\n');
|
|
17
|
+
|
|
18
|
+
// You can try these methods with a valid API key:
|
|
19
|
+
console.log('Available methods:');
|
|
20
|
+
console.log('- client.tickets.create()');
|
|
21
|
+
console.log('- client.tickets.list()');
|
|
22
|
+
console.log('- client.tickets.update()');
|
|
23
|
+
console.log('- client.testCases.create()');
|
|
24
|
+
console.log('- client.testCases.list()');
|
|
25
|
+
console.log('\nGet your API key at: https://codmir.com/settings/tokens');
|
|
26
|
+
|
|
27
|
+
return {
|
|
28
|
+
message: 'codmir - the AI that prevents wasted engineering time',
|
|
29
|
+
docs: 'https://codmir.com/docs'
|
|
30
|
+
};
|
|
31
|
+
} catch (error) {
|
|
32
|
+
console.error('Error:', error.message);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
demo();
|