Skip to content

Commit 3da9d17

Browse files
committed
Merge branch 'master' into feat/mr-detail
2 parents c884d77 + 185072c commit 3da9d17

File tree

8 files changed

+193
-8
lines changed

8 files changed

+193
-8
lines changed

README.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# coding-hbuilderx
2+
3+
## Development
4+
5+
1. start dev mode.
6+
7+
```console
8+
yarn watch
9+
```
10+
11+
2. click run plugin option in hbuilder.

package.json

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
{
22
"name": "coding-hbuilderx",
3-
"description": "your extension description",
4-
"displayName": "your extension display name",
5-
"version": "0.0.0",
6-
"publisher": "your name",
3+
"description": "",
4+
"displayName": "CODING 代码仓库插件",
5+
"version": "1.0.0",
6+
"publisher": "coding",
77
"engines": {
88
"HBuilderX": "^2.7.0"
99
},
@@ -89,6 +89,25 @@
8989
"title": "CODING 合并请求详情"
9090
}
9191
]
92+
},
93+
"configuration": {
94+
"type": "object",
95+
"title": "CODING 代码仓库插件配置",
96+
"properties": {
97+
"codingPlugin.email": {
98+
"type": "string",
99+
"description": "CODING 用户邮箱"
100+
},
101+
"codingPlugin.token": {
102+
"type": "string",
103+
"description": "CODING 服务令牌,请勿擅自更改"
104+
},
105+
"codingPlugin.hbToken": {
106+
"type": "string",
107+
"description": "请勿修改"
108+
}
109+
110+
}
92111
}
93112
},
94113
"extensionDependencies": [

src/extension.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import WebviewProvider from './webviews';
44
import ACTIONS, { dispatch } from './utils/actions';
55
import { proxyCtx } from './utils/proxy';
66
import toast from './utils/toast';
7+
import { readConfig } from './services/dcloud';
78

89
// const accessToken = '7e4d9d17f87875e731d536d13635a700ddf52b12';
910
// const user = {
@@ -31,6 +32,10 @@ async function activate(context: IContext) {
3132

3233
const repoInfo = await CodingServer.getRepoParams();
3334
console.log('repoInfo ==> ', repoInfo);
35+
const token = await readConfig(`token`);
36+
if (!token) {
37+
toast.warn(`请先登录 CODING`);
38+
}
3439

3540
const codingServer = new CodingServer(
3641
{
@@ -49,6 +54,8 @@ async function activate(context: IContext) {
4954
codingServer,
5055
depots: [],
5156
selectedDepot: null,
57+
token,
58+
repoInfo,
5259
},
5360
});
5461

src/init.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import MRCustomEditorProvider from './customEditors/mergeRequest';
66
import toast from './utils/toast';
77
import ACTIONS, { dispatch } from './utils/actions';
88
import { IDepot, IMRItem } from './typings/common';
9+
import * as DCloudService from './services/dcloud';
910

1011
const { registerCommand } = hx.commands;
1112

@@ -100,8 +101,29 @@ export function registerCustomEditors(context: IContext) {
100101
});
101102
}
102103

104+
async function initCredentials(context: IContext) {
105+
try {
106+
let hbToken = await DCloudService.readConfig(`hbToken`);
107+
if (!hbToken) {
108+
const code = await DCloudService.grantForUserInfo();
109+
const tokenResult = await DCloudService.applyForToken(code);
110+
hbToken = tokenResult.data.access_token;
111+
}
112+
const resp = await DCloudService.fetchUser(hbToken);
113+
toast.info(`logged in as DCloud user: ${resp.data.nickname} ${resp.data.email}`);
114+
const {
115+
ctx: { codingServer, repoInfo, token },
116+
} = context;
117+
const userData = await codingServer.getUserInfo(repoInfo.team, token);
118+
toast.info(`logged in as coding user: ${userData.name} @ ${userData.team}`);
119+
} catch (err) {
120+
console.error(err);
121+
}
122+
}
123+
103124
export default function init(context: IContext) {
104125
registerCommands(context);
105126
createTreeViews(context);
106127
workspaceInit();
128+
initCredentials(context);
107129
}

src/services/codingServer.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,9 +49,13 @@ export default class CodingServer {
4949
const result = await axios({
5050
method: 'get',
5151
url: `https://${team}.coding.net/api/current_user`,
52-
headers: this.getHeaders(),
52+
headers: this.getHeaders(token),
5353
});
5454

55+
if (result.code) {
56+
return Promise.reject(result);
57+
}
58+
5559
return result?.data;
5660
} catch (err) {
5761
console.error(err);

src/services/dcloud.ts

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
import hx from 'hbuilderx';
2+
3+
import axios from '../utils/axios';
4+
import { ITokenResponse, IDCloudUser, ITokenType, IOAuthResponse } from '../typings/common';
5+
6+
const appSecret = `dnGxdvWuEwOO3VimZwo1IsqfESam7k`;
7+
export const appId = `crvUAM0Snz`;
8+
9+
export const applyForToken = async (code: string | null) => {
10+
try {
11+
if (!code) {
12+
throw new Error(`no code provided.`);
13+
}
14+
15+
const resp: ITokenResponse = await axios.get(`https://ide.dcloud.net.cn/dcloudOauthv2/accessToken`, {
16+
params: {
17+
code,
18+
appid: appId,
19+
app_secret: appSecret,
20+
},
21+
});
22+
23+
if (resp.ret) {
24+
return Promise.reject(resp);
25+
}
26+
27+
await setConfig(`hbToken`, resp.data.access_token);
28+
return resp;
29+
} catch (e) {
30+
return Promise.reject(e);
31+
}
32+
};
33+
34+
export const fetchUser = async (accessToken: string) => {
35+
try {
36+
const resp: IDCloudUser = await axios.get(`https://ide.dcloud.net.cn/dcloudOauthv2/userInfo`, {
37+
params: {
38+
access_token: accessToken,
39+
},
40+
});
41+
42+
if (resp.ret) {
43+
return Promise.reject(resp);
44+
}
45+
46+
if (!resp.data.email) {
47+
return Promise.reject(resp);
48+
}
49+
50+
await setConfig(`email`, resp.data.email);
51+
return resp;
52+
} catch (e) {
53+
return Promise.reject(e);
54+
}
55+
};
56+
57+
export const setConfig = async (prop: string, value: string) => {
58+
const codingPlugin = hx.workspace.getConfiguration(`codingPlugin`);
59+
try {
60+
await codingPlugin.update(prop, value);
61+
return true;
62+
} catch {
63+
return false;
64+
}
65+
};
66+
67+
export const readConfig = async (prop: string) => {
68+
const codingPlugin = hx.workspace.getConfiguration(`codingPlugin`);
69+
const token = codingPlugin.get(prop, ``);
70+
return token;
71+
};
72+
73+
export const grantForUserInfo = (): Promise<string | null> =>
74+
new Promise((resolve, reject) => {
75+
hx.authorize
76+
.login({
77+
scopes: ['basic', 'email', 'phone'],
78+
appId: appId,
79+
})
80+
.then((param: IOAuthResponse) => {
81+
const { code, error } = param;
82+
if (error || !code) {
83+
return reject(null);
84+
}
85+
86+
console.log(`hbuilder oauth code: `, code);
87+
return resolve(code);
88+
});
89+
});

src/typings/common.ts

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,3 +58,36 @@ export interface IDepot {
5858
svnEnabled: boolean;
5959
vcsType: 'git' | 'svn';
6060
}
61+
62+
export interface IOAuthResponse {
63+
code: string;
64+
error: number;
65+
}
66+
67+
export interface ITokenResponse {
68+
ret: number;
69+
desc: string;
70+
data: {
71+
access_token: string;
72+
access_token_ttl: string;
73+
refresh_token: string;
74+
refresh_token_ttl: string;
75+
};
76+
}
77+
78+
export interface IDCloudUser {
79+
ret: number;
80+
desc: string;
81+
data: {
82+
nickname: string;
83+
avatar: string;
84+
uid: string;
85+
email: string;
86+
phone: string;
87+
};
88+
}
89+
90+
export enum ITokenType {
91+
AccessToken = `accessToken`,
92+
RefreshToken = `refreshToken`,
93+
}

src/utils/toast.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
import hx from 'hbuilderx';
22

3-
export const info = (msg: string, buttons?: string[]): Promise<string> => {
3+
export const info = (msg: string, buttons?: string[]) => {
44
return hx.window.showInformationMessage(msg, buttons);
55
};
66

7-
export const warn = (msg: string, buttons?: string[]): Promise<string> => {
7+
export const warn = (msg: string, buttons?: string[]) => {
88
return hx.window.showWarningMessage(msg, buttons);
99
};
1010

11-
export const error = (msg: string, buttons?: string[]): Promise<string> => {
11+
export const error = (msg: string, buttons?: string[]) => {
1212
return hx.window.showErrorMessage(msg, buttons);
1313
};
1414

0 commit comments

Comments
 (0)